Skip to content

Commit eb3841f

Browse files
authored
Improve regex and fix pcall not returning (#2186)
* Improve regex and fix pcall not returning * Don't use %b
1 parent 1ef0f63 commit eb3841f

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

lua/entities/gmod_wire_expression2/core/string.lua

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,18 @@ end)
338338
/******************************************************************************/
339339

340340
local function checkregex(data, pattern)
341-
local limits = {15000, 500, 150, 70, 40} -- Worst case is about 200ms
342-
local n = 0 for i in string.gmatch(string.gsub(pattern, "%%.", ""), "[%+%-%*]") do n = n + 1 end
341+
local limits = {[0] = 50000000, 15000, 500, 150, 70, 40} -- Worst case is about 200ms
342+
-- strip escaped things
343+
local stripped, nrepl = string.gsub(pattern, "%%.", "")
344+
-- strip bracketed things
345+
stripped, nrepl2 = string.gsub(stripped, "%[.-%]", "")
346+
-- strip captures
347+
stripped = string.gsub(stripped, "[()]", "")
348+
-- Find extenders
349+
local n = 0 for i in string.gmatch(stripped, "[%+%-%*]") do n = n + 1 end
343350
local msg
344-
if n==0 then return
345-
elseif n<=#limits then
346-
if #data>limits[n] then msg = n.." ext search length too long ("..limits[n].." max)" else return end
351+
if n<=#limits then
352+
if #data*(#stripped + nrepl - n + nrepl2)>limits[n] then msg = n.." ext search length too long ("..limits[n].." max)" else return end
347353
else
348354
msg = "too many extenders"
349355
end
@@ -356,7 +362,7 @@ local find = string.find
356362

357363
--- Returns the 1st occurrence of the string <pattern>, returns 0 if not found. Prints malformed string errors to the chat area.
358364
e2function number string:findRE(string pattern)
359-
local OK, Ret = pcall(function() checkregex(this, pattern) string.find(this, pattern) end)
365+
local OK, Ret = pcall(function() checkregex(this, pattern) return string.find(this, pattern) end)
360366
if not OK then
361367
self.player:ChatPrint(Ret)
362368
return 0
@@ -367,7 +373,7 @@ end
367373

368374
--- 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.
369375
e2function number string:findRE(string pattern, start)
370-
local OK, Ret = pcall(function() checkregex(this, pattern) find(this, pattern, start) end)
376+
local OK, Ret = pcall(function() checkregex(this, pattern) return find(this, pattern, start) end)
371377
if not OK then
372378
self.player:ChatPrint(Ret)
373379
return 0
@@ -394,7 +400,7 @@ end
394400

395401
--- Finds and replaces every occurrence of <pattern> with <new> using regular expressions. Prints malformed string errors to the chat area.
396402
e2function string string:replaceRE(string pattern, string new)
397-
local OK, Ret = pcall(function() checkregex(this, pattern) gsub(this, pattern, new) end)
403+
local OK, Ret = pcall(function() checkregex(this, pattern) return gsub(this, pattern, new) end)
398404
if not OK then
399405
self.player:ChatPrint(Ret)
400406
return ""
@@ -414,7 +420,7 @@ e2function array string:explode(string delim)
414420
end
415421

416422
e2function array string:explodeRE( string delim )
417-
local ok, ret = pcall(function() checkregex(this, pattern) string_Explode( delim, this, true ) end)
423+
local ok, ret = pcall(function() checkregex(this, pattern) return string_Explode( delim, this, true ) end)
418424
if not ok then
419425
self.player:ChatPrint(ret)
420426
ret = {}
@@ -453,7 +459,7 @@ local table_remove = table.remove
453459

454460
--- runs [[string.match]](<this>, <pattern>) and returns the sub-captures as an array. Prints malformed pattern errors to the chat area.
455461
e2function array string:match(string pattern)
456-
local args = {pcall(function() checkregex(this, pattern) string_match(this, pattern) end)}
462+
local args = {pcall(function() checkregex(this, pattern) return string_match(this, pattern) end)}
457463
if not args[1] then
458464
self.player:ChatPrint(args[2] or "Unknown error in str:match")
459465
return {}
@@ -465,7 +471,7 @@ end
465471

466472
--- runs [[string.match]](<this>, <pattern>, <position>) and returns the sub-captures as an array. Prints malformed pattern errors to the chat area.
467473
e2function array string:match(string pattern, position)
468-
local args = {pcall(function() checkregex(this, pattern) string_match(this, pattern, position) end)}
474+
local args = {pcall(function() checkregex(this, pattern) return string_match(this, pattern, position) end)}
469475
if not args[1] then
470476
self.player:ChatPrint(args[2] or "Unknown error in str:match")
471477
return {}
@@ -501,7 +507,7 @@ end
501507
--- runs [[string.gmatch]](<this>, <pattern>) and returns the captures in an array in a table. Prints malformed pattern errors to the chat area.
502508
-- (By Divran)
503509
e2function table string:gmatch(string pattern)
504-
local OK, ret = pcall(function() checkregex(this, pattern) gmatch(self, this, pattern) end)
510+
local OK, ret = pcall(function() checkregex(this, pattern) return gmatch(self, this, pattern) end)
505511
if (!OK) then
506512
self.player:ChatPrint( ret or "Unknown error in str:gmatch" )
507513
return newE2Table()
@@ -514,7 +520,7 @@ end
514520
-- (By Divran)
515521
e2function table string:gmatch(string pattern, position)
516522
this = this:Right( -position-1 )
517-
local OK, ret = pcall(function() checkregex(this, pattern) gmatch(self, this, pattern) end)
523+
local OK, ret = pcall(function() checkregex(this, pattern) return gmatch(self, this, pattern) end)
518524
if (!OK) then
519525
self.player:ChatPrint( ret or "Unknown error in str:gmatch" )
520526
return newE2Table()
@@ -525,7 +531,7 @@ end
525531

526532
--- 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.
527533
e2function string string:matchFirst(string pattern)
528-
local OK, Ret = pcall(function() checkregex(this, pattern) string_match(this, pattern) end)
534+
local OK, Ret = pcall(function() checkregex(this, pattern) return string_match(this, pattern) end)
529535
if not OK then
530536
self.player:ChatPrint(Ret)
531537
return ""
@@ -536,7 +542,7 @@ end
536542

537543
--- 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.
538544
e2function string string:matchFirst(string pattern, position)
539-
local OK, Ret = pcall(function() checkregex(this, pattern) string_match(this, pattern, position) end)
545+
local OK, Ret = pcall(function() checkregex(this, pattern) return string_match(this, pattern, position) end)
540546
if not OK then
541547
self.player:ChatPrint(Ret)
542548
return ""

0 commit comments

Comments
 (0)