mirror of
https://github.com/espruino/Espruino.git
synced 2026-02-01 15:55:37 +00:00
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)
This commit is contained in:
parent
ce15301880
commit
617e1a2975
@ -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)
|
||||
|
||||
53
src/jsvar.c
53
src/jsvar.c
@ -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
|
||||
@ -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();
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user