aboutsummaryrefslogtreecommitdiff
path: root/core/text/lua
diff options
context:
space:
mode:
authorskytrias <skytrias@protonmail.com>2022-12-01 19:39:07 +0100
committerskytrias <skytrias@protonmail.com>2022-12-18 23:11:23 +0100
commit0ae1812f90eac575b07fc3cfdfdcaf9c48119cd6 (patch)
tree07a7ef98c9149b798afc4b77f84b81514f3c11d1 /core/text/lua
parenteb5523d5d3326fce3c0d00ca071051875715447f (diff)
small fixes and oob checks, stop infinite loops on empty matches
Diffstat (limited to 'core/text/lua')
-rw-r--r--core/text/lua/strlib.odin19
1 files changed, 15 insertions, 4 deletions
diff --git a/core/text/lua/strlib.odin b/core/text/lua/strlib.odin
index ca95367e9..05495afe4 100644
--- a/core/text/lua/strlib.odin
+++ b/core/text/lua/strlib.odin
@@ -23,6 +23,7 @@ Error :: enum {
Unfinished_Capture,
Malformed_Pattern,
Rune_Error,
+ Match_Invalid,
}
L_ESC :: '%'
@@ -183,17 +184,21 @@ classend :: proc(ms: ^MatchState, p: int) -> (step: int, err: Error) {
case '[': {
// fine with step by 1
- if ms.pattern[step] == '^' {
+ if step + 1 < len(ms.pattern) && ms.pattern[step] == '^' {
step += 1
}
// run till end is reached
- for ms.pattern[step] != ']' {
+ for {
if step == len(ms.pattern) {
err = .Malformed_Pattern
return
}
+ if ms.pattern[step] == ']' {
+ break
+ }
+
// dont care about utf8 here
step += 1
@@ -417,7 +422,7 @@ match :: proc(ms: ^MatchState, s, p: int) -> (unused: int, err: Error) {
char, _ := utf8_peek(ms.pattern[p:]) or_return
switch char {
case '(': {
- if ms.pattern[p + 1] == ')' {
+ if p + 1 < len(ms.pattern) && ms.pattern[p + 1] == ')' {
s = start_capture(ms, s, p + 2, CAP_POSITION) or_return
} else {
s = start_capture(ms, s, p + 1, CAP_UNFINISHED) or_return
@@ -582,7 +587,7 @@ push_onecapture :: proc(
}
case CAP_POSITION: {
- matches[i] = { init - 1, init - 1 }
+ matches[i] = { init, init + 1 }
}
case: {
@@ -697,8 +702,14 @@ find_aux :: proc(
res := match(&ms, s, p) or_return
if res != INVALID {
+ // disallow non advancing match
+ if s == res {
+ err = .Match_Invalid
+ }
+
// NOTE(Skytrias): first result is reserved for a full match
matches[0] = { s, res }
+
// rest are the actual captures
captures = push_captures(&ms, -1, -1, matches[1:]) or_return
captures += 1