Skip to content

Commit 7ef769f

Browse files
committed
Fix stack overflow if executing regex full of hundreds of open brackets (fix #1487)
1 parent d3d5ea3 commit 7ef769f

File tree

4 files changed

+10
-1
lines changed

4 files changed

+10
-1
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
Pixl.js: Add Pixl.setLCDPower to allow the LCD to be powered off, more than halving power consumption
7272
nRF5x: Allow NRF.setScan and NRF.findDevices to take the same search filters NRF.requestDevice does (fix #1496)
7373
Fix buffer overrun if we have to reallocate a pointer to argument lists when calling a function (fix #1491)
74+
Fix stack overflow if executing regex full of hundreds of open brackets (fix #1487)
7475

7576
1v99 : Increase jslMatch error buffer size to handle "UNFINISHED TEMPLATE LITERAL" string (#1426)
7677
nRF5x: Make FlashWrite cope with flash writes > 4k

src/jsparse.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ void jspeiLoadScopesFromVar(JsVar *arr) {
215215
execInfo.scopes[execInfo.scopeCount++] = jsvLockAgain(arr);
216216
}
217217
// -----------------------------------------------
218+
/// Check that we have enough stack to recurse. Return true if all ok, error if not.
218219
bool jspCheckStackPosition() {
219220
if (jsuGetFreeStack() < 512) { // giving us 512 bytes leeway
220221
jsExceptionHere(JSET_ERROR, "Too much recursion - the stack is about to overflow");

src/jsparse.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ bool jspIsConstructor(JsVar *constructor, const char *constructorName);
2929
/** Get the constructor of the given object, or return 0 if ot found, or not a function */
3030
JsVar *jspGetConstructor(JsVar *object);
3131

32+
/// Check that we have enough stack to recurse. Return true if all ok, error if not.
33+
bool jspCheckStackPosition();
34+
3235
/// Create a new built-in object that jswrapper can use to check for built-in functions
3336
JsVar *jspNewBuiltin(const char *name);
3437

src/jswrap_regexp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,13 @@ JsVar *matchhere(char *regexp, JsvStringIterator *txtIt, matchInfo info) {
172172
info.groupStart[info.groups] = jsvStringIteratorGetIndex(txtIt);
173173
info.groupEnd[info.groups] = info.groupStart[info.groups];
174174
if (info.groups<MAX_GROUPS) info.groups++;
175+
if (!jspCheckStackPosition()) return 0;
175176
return matchhere(regexp+1, txtIt, info);
176177
}
177178
if (regexp[0] == ')') {
178-
info.groupEnd[info.groups-1] = jsvStringIteratorGetIndex(txtIt);
179+
if (info.groups>0)
180+
info.groupEnd[info.groups-1] = jsvStringIteratorGetIndex(txtIt);
181+
if (!jspCheckStackPosition()) return 0;
179182
return matchhere(regexp+1, txtIt, info);
180183
}
181184
int charLength;
@@ -219,6 +222,7 @@ JsVar *matchhere(char *regexp, JsvStringIterator *txtIt, matchInfo info) {
219222
//
220223
if (jsvStringIteratorHasChar(txtIt) && charMatched) {
221224
jsvStringIteratorNext(txtIt);
225+
if (!jspCheckStackPosition()) return 0;
222226
return matchhere(regexp+charLength, txtIt, info);
223227
}
224228
return 0;

0 commit comments

Comments
 (0)