Skip to content

Commit

Permalink
Ensure that pretokenised Strings are loaded as Flat Strings when exec…
Browse files Browse the repository at this point in the history
…uted from a String in RAM

            E.nativeCall also checks to see if getting data as a flat string failed (could have caused segfault)
  • Loading branch information
gfwilliams committed Oct 23, 2024
1 parent ce15301 commit 617e1a2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 16 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
ESP32C3: don't kick connected BLE devices off if reset() is called
ESP32C3: disable warnings about "BT_BTM: BTM_GetSecurityFlags false"
Handle semicolons between field declarations in classes
Ensure that pretokenised Strings are loaded as Flat Strings when executed from a String in RAM
E.nativeCall also checks to see if getting data as a flat string failed (could have caused segfault)

2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()'
Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off)
Expand Down
53 changes: 38 additions & 15 deletions src/jsvar.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,21 +1632,9 @@ JsVar *jsvAsStringAndUnLock(JsVar *var) {
JsVar *jsvAsFlatString(JsVar *var) {
if (jsvIsFlatString(var)) return jsvLockAgain(var);
JsVar *str = jsvAsString(var);
size_t len = jsvGetStringLength(str);
JsVar *flat = jsvNewFlatStringOfLength((unsigned int)len);
if (flat) {
JsvStringIterator src;
JsvStringIterator dst;
jsvStringIteratorNew(&src, str, 0);
jsvStringIteratorNew(&dst, flat, 0);
while (len--) {
jsvStringIteratorSetCharAndNext(&dst, jsvStringIteratorGetCharAndNext(&src));
}
jsvStringIteratorFree(&src);
jsvStringIteratorFree(&dst);
}
JsVar *fs = jsvNewFlatStringFromStringVar(str, 0, JSVAPPENDSTRINGVAR_MAXLENGTH);
jsvUnLock(str);
return flat;
return fs;
}

/** Given a JsVar meant to be an index to an array, convert it to
Expand Down Expand Up @@ -1943,7 +1931,29 @@ void jsvAppendStringVar(JsVar *var, const JsVar *str, size_t stridx, size_t maxL
jsvStringIteratorFree(&dst);
}

/** Create a new String from a substring in RAM. It is always writable. jsvNewFromStringVar can reference a non-writable string.
/** Create a new flat string from the given var with the given index and length */
JsVar *jsvNewFlatStringFromStringVar(JsVar *var, size_t stridx, size_t maxLength) {
assert(jsvIsString(var));
size_t len = jsvGetStringLength(var);
if (stridx>len) len=0;
else len -= stridx;
if (len > maxLength) len = maxLength;
JsVar *flat = jsvNewFlatStringOfLength((unsigned int)len);
if (flat) {
JsvStringIterator src;
JsvStringIterator dst;
jsvStringIteratorNew(&src, var, stridx);
jsvStringIteratorNew(&dst, flat, 0);
while (len--) {
jsvStringIteratorSetCharAndNext(&dst, jsvStringIteratorGetCharAndNext(&src));
}
jsvStringIteratorFree(&src);
jsvStringIteratorFree(&dst);
}
return flat;
}

/** Create a new (non-flat) String from a substring in RAM. It is always writable and appendable. jsvNewFromStringVar can reference a non-writable string.
The Argument must be a string. stridx = start char or str, maxLength = max number of characters (can be JSVAPPENDSTRINGVAR_MAXLENGTH) */
JsVar *jsvNewWritableStringFromStringVar(const JsVar *str, size_t stridx, size_t maxLength) {
JsVar *var = jsvNewFromEmptyString();
Expand All @@ -1958,6 +1968,7 @@ JsVar *jsvNewWritableStringFromStringVar(const JsVar *str, size_t stridx, size_t
/** Create a new variable from a substring. If a Native or Flash String, the memory area will be referenced (so the new string may not be writable)
The Argument must be a string. stridx = start char or str, maxLength = max number of characters (can be JSVAPPENDSTRINGVAR_MAXLENGTH) */
JsVar *jsvNewFromStringVar(const JsVar *str, size_t stridx, size_t maxLength) {
assert(jsvIsString(str));
if (jsvIsNativeString(str) || jsvIsFlashString(str)) {
// if it's a flash string, just change the pointer (but we must check length)
size_t l = jsvGetStringLength(str);
Expand All @@ -1968,6 +1979,18 @@ JsVar *jsvNewFromStringVar(const JsVar *str, size_t stridx, size_t maxLength) {
res->varData.nativeStr.len = (JsVarDataNativeStrLength)maxLength;
return res;
}
if (jsvIsFlatString(str)) {
// work out how long we really want it...
size_t length = jsvGetCharactersInVar(str);
if (stridx >= length) length = 0;
else length -= stridx;
if (length > maxLength) length = maxLength;
// if it's long enough to make sense, create a flat string instead
if (length > JSV_FLAT_STRING_BREAK_EVEN) {
JsVar *var = jsvNewFlatStringFromStringVar(str, stridx, length);
if (var) return var;
}
}
return jsvNewWritableStringFromStringVar(str, stridx, maxLength);
}

Expand Down
4 changes: 3 additions & 1 deletion src/jsvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,9 @@ JsVar *jsvNewUTF8String(JsVar* dataString); ///< Create a new unicode string usi
JsVar *jsvNewUTF8StringAndUnLock(JsVar* dataString); ///< Create a new unicode string using the given data string for backing
#endif
static ALWAYS_INLINE JsVar *jsvNewNull() { return jsvNewWithFlags(JSV_NULL); } ;///< Create a new null variable
/** Create a new String from a substring in RAM. It is always writable. jsvNewFromStringVar can reference a non-writable string.
/** Create a new flat string from the given var with the given index and length */
JsVar *jsvNewFlatStringFromStringVar(JsVar *var, size_t stridx, size_t maxLength);
/** Create a new (non-flat) String from a substring in RAM. It is always writable and appendable. jsvNewFromStringVar can reference a non-writable string.
The Argument must be a string. stridx = start char or str, maxLength = max number of characters (can be JSVAPPENDSTRINGVAR_MAXLENGTH) */
JsVar *jsvNewWritableStringFromStringVar(const JsVar *str, size_t stridx, size_t maxLength);
/** Create a new variable from a substring. If a Native or Flash String, the memory area will be referenced (so the new string may not be writable)
Expand Down
4 changes: 4 additions & 0 deletions src/jswrap_espruino.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ JsVar *jswrap_espruino_nativeCall(JsVarInt addr, JsVar *signature, JsVar *data)
JsVar *fn = jsvNewNativeFunction((void *)(size_t)addr, (unsigned short)argTypes);
if (data) {
JsVar *flat = jsvAsFlatString(data);
if (!flat) { // can't get a flat string!
jsvUnLock(fn);
return 0;
}
jsvAddNamedChildAndUnLock(fn, flat, JSPARSE_FUNCTION_CODE_NAME);
}
return fn;
Expand Down

0 comments on commit 617e1a2

Please sign in to comment.