Improve regex and fix pcall not returning (#2186)

* Improve regex and fix pcall not returning

* Don't use %b
This commit is contained in:
thegrb93 2021-06-25 19:50:34 -04:00 committed by GitHub
parent 1ef0f63dd1
commit eb3841f19c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -338,12 +338,18 @@ end)
/******************************************************************************/
local function checkregex(data, pattern)
local limits = {15000, 500, 150, 70, 40} -- Worst case is about 200ms
local n = 0 for i in string.gmatch(string.gsub(pattern, "%%.", ""), "[%+%-%*]") do n = n + 1 end
local limits = {[0] = 50000000, 15000, 500, 150, 70, 40} -- Worst case is about 200ms
-- strip escaped things
local stripped, nrepl = string.gsub(pattern, "%%.", "")
-- strip bracketed things
stripped, nrepl2 = string.gsub(stripped, "%[.-%]", "")
-- strip captures
stripped = string.gsub(stripped, "[()]", "")
-- Find extenders
local n = 0 for i in string.gmatch(stripped, "[%+%-%*]") do n = n + 1 end
local msg
if n==0 then return
elseif n<=#limits then
if #data>limits[n] then msg = n.." ext search length too long ("..limits[n].." max)" else return end
if n<=#limits then
if #data*(#stripped + nrepl - n + nrepl2)>limits[n] then msg = n.." ext search length too long ("..limits[n].." max)" else return end
else
msg = "too many extenders"
end
@ -356,7 +362,7 @@ local find = string.find
--- Returns the 1st occurrence of the string <pattern>, returns 0 if not found. Prints malformed string errors to the chat area.
e2function number string:findRE(string pattern)
local OK, Ret = pcall(function() checkregex(this, pattern) string.find(this, pattern) end)
local OK, Ret = pcall(function() checkregex(this, pattern) return string.find(this, pattern) end)
if not OK then
self.player:ChatPrint(Ret)
return 0
@ -367,7 +373,7 @@ end
--- Returns the 1st occurrence of the string <pattern> starting at <start> and going to the end of the string, returns 0 if not found. Prints malformed string errors to the chat area.
e2function number string:findRE(string pattern, start)
local OK, Ret = pcall(function() checkregex(this, pattern) find(this, pattern, start) end)
local OK, Ret = pcall(function() checkregex(this, pattern) return find(this, pattern, start) end)
if not OK then
self.player:ChatPrint(Ret)
return 0
@ -394,7 +400,7 @@ end
--- Finds and replaces every occurrence of <pattern> with <new> using regular expressions. Prints malformed string errors to the chat area.
e2function string string:replaceRE(string pattern, string new)
local OK, Ret = pcall(function() checkregex(this, pattern) gsub(this, pattern, new) end)
local OK, Ret = pcall(function() checkregex(this, pattern) return gsub(this, pattern, new) end)
if not OK then
self.player:ChatPrint(Ret)
return ""
@ -414,7 +420,7 @@ e2function array string:explode(string delim)
end
e2function array string:explodeRE( string delim )
local ok, ret = pcall(function() checkregex(this, pattern) string_Explode( delim, this, true ) end)
local ok, ret = pcall(function() checkregex(this, pattern) return string_Explode( delim, this, true ) end)
if not ok then
self.player:ChatPrint(ret)
ret = {}
@ -453,7 +459,7 @@ local table_remove = table.remove
--- runs [[string.match]](<this>, <pattern>) and returns the sub-captures as an array. Prints malformed pattern errors to the chat area.
e2function array string:match(string pattern)
local args = {pcall(function() checkregex(this, pattern) string_match(this, pattern) end)}
local args = {pcall(function() checkregex(this, pattern) return string_match(this, pattern) end)}
if not args[1] then
self.player:ChatPrint(args[2] or "Unknown error in str:match")
return {}
@ -465,7 +471,7 @@ end
--- runs [[string.match]](<this>, <pattern>, <position>) and returns the sub-captures as an array. Prints malformed pattern errors to the chat area.
e2function array string:match(string pattern, position)
local args = {pcall(function() checkregex(this, pattern) string_match(this, pattern, position) end)}
local args = {pcall(function() checkregex(this, pattern) return string_match(this, pattern, position) end)}
if not args[1] then
self.player:ChatPrint(args[2] or "Unknown error in str:match")
return {}
@ -501,7 +507,7 @@ end
--- runs [[string.gmatch]](<this>, <pattern>) and returns the captures in an array in a table. Prints malformed pattern errors to the chat area.
-- (By Divran)
e2function table string:gmatch(string pattern)
local OK, ret = pcall(function() checkregex(this, pattern) gmatch(self, this, pattern) end)
local OK, ret = pcall(function() checkregex(this, pattern) return gmatch(self, this, pattern) end)
if (!OK) then
self.player:ChatPrint( ret or "Unknown error in str:gmatch" )
return newE2Table()
@ -514,7 +520,7 @@ end
-- (By Divran)
e2function table string:gmatch(string pattern, position)
this = this:Right( -position-1 )
local OK, ret = pcall(function() checkregex(this, pattern) gmatch(self, this, pattern) end)
local OK, ret = pcall(function() checkregex(this, pattern) return gmatch(self, this, pattern) end)
if (!OK) then
self.player:ChatPrint( ret or "Unknown error in str:gmatch" )
return newE2Table()
@ -525,7 +531,7 @@ end
--- runs [[string.match]](<this>, <pattern>) and returns the first match or an empty string if the match failed. Prints malformed pattern errors to the chat area.
e2function string string:matchFirst(string pattern)
local OK, Ret = pcall(function() checkregex(this, pattern) string_match(this, pattern) end)
local OK, Ret = pcall(function() checkregex(this, pattern) return string_match(this, pattern) end)
if not OK then
self.player:ChatPrint(Ret)
return ""
@ -536,7 +542,7 @@ end
--- runs [[string.match]](<this>, <pattern>, <position>) and returns the first match or an empty string if the match failed. Prints malformed pattern errors to the chat area.
e2function string string:matchFirst(string pattern, position)
local OK, Ret = pcall(function() checkregex(this, pattern) string_match(this, pattern, position) end)
local OK, Ret = pcall(function() checkregex(this, pattern) return string_match(this, pattern, position) end)
if not OK then
self.player:ChatPrint(Ret)
return ""