@@ -761,6 +761,10 @@ sandbox = {
761
761
next = next ,
762
762
pairs = pairs ,
763
763
pcall = function (...)
764
+ -- prevent infinite pcall() loops by checking deadline before pcall()
765
+ local status , err = pcall (checkDeadline )
766
+ if not status then return false , err end
767
+
764
768
return pcallTimeoutCheck (pcall (... ))
765
769
end ,
766
770
print = nil , -- in boot/*_base.lua
@@ -807,18 +811,27 @@ sandbox = {
807
811
type = type ,
808
812
_VERSION = _VERSION :match (" Luaj" ) and " Luaj" or _VERSION :match (" 5.4" ) and " Lua 5.4" or _VERSION :match (" 5.3" ) and " Lua 5.3" or " Lua 5.2" ,
809
813
xpcall = function (f , msgh , ...)
810
- local handled = false
814
+ -- allow xpcall() to call the message handler recursively, per manual 2.3
815
+ -- Lua itself promises to break the infinite loop; failing that, the timeout
816
+ -- check will take care of this.
817
+ local errorCapture
818
+ errorCapture = function (ff , ...)
819
+ -- prevent infinite xpcall() loops by checking deadline before xpcall()
820
+ local status , err = pcall (checkDeadline )
821
+ if not status then return false , err end
822
+
823
+ return xpcall (ff , function (...)
824
+ if rawequal ((... ), tooLongWithoutYielding ) then
825
+ return tooLongWithoutYielding
826
+ else
827
+ return select (2 , errorCapture (msgh , ... ))
828
+ end
829
+ end , ... )
830
+ end
831
+
811
832
checkArg (2 , msgh , " function" )
812
- local result = table.pack (xpcall (f , function (...)
813
- if rawequal ((... ), tooLongWithoutYielding ) then
814
- return tooLongWithoutYielding
815
- elseif handled then
816
- return ...
817
- else
818
- handled = true
819
- return msgh (... )
820
- end
821
- end , ... ))
833
+ local result = table.pack (errorCapture (f , ... ))
834
+ -- if the final returned error is due to timeout, run handler one last time
822
835
if rawequal (result [2 ], tooLongWithoutYielding ) then
823
836
result = table.pack (result [1 ], select (2 , pcallTimeoutCheck (pcall (msgh , tostring (tooLongWithoutYielding )))))
824
837
end
0 commit comments