Bug 704238: Limit max string lengths.

Check string length when creating strings to not exceed a maximum,
so we avoid integer overflows when concatenating strings.

The string limit must be small enough that we'll not integer overflow
in one concatenation (A + B + 1 must not overflow while still
exceeding the string limit).

Set the limit to 64KB for now.

If we need 2GB strings then we will have to use double or int64 variables
when calculating string lengths.
This commit is contained in:
Tor Andersson
2021-09-07 18:02:28 +02:00
parent 453d28fcc0
commit b06a5e9b02
5 changed files with 24 additions and 7 deletions

View File

@@ -123,11 +123,15 @@ static void Ap_join(js_State *J)
n += strlen(r);
if (k == 0) {
out = js_malloc(J, n);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
out = js_malloc(J, (int)n);
strcpy(out, r);
} else {
n += seplen;
out = js_realloc(J, out, n);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
out = js_realloc(J, out, (int)n);
strcat(out, sep);
strcat(out, r);
}

3
jsi.h
View File

@@ -93,6 +93,9 @@ typedef struct js_StackTrace js_StackTrace;
#ifndef JS_ASTLIMIT
#define JS_ASTLIMIT 100 /* max nested expressions */
#endif
#ifndef JS_STRLIMIT
#define JS_STRLIMIT (1<<16) /* max string length */
#endif
/* instruction size -- change to int if you get integer overflow syntax errors */

View File

@@ -42,7 +42,9 @@ static js_StringNode jsS_sentinel = { &jsS_sentinel, &jsS_sentinel, 0, ""};
static js_StringNode *jsS_newstringnode(js_State *J, const char *string, const char **result)
{
int n = strlen(string);
size_t n = strlen(string);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
js_StringNode *node = js_malloc(J, soffsetof(js_StringNode, string) + n + 1);
node->left = node->right = &jsS_sentinel;
node->level = 1;

View File

@@ -119,7 +119,9 @@ void js_pushnumber(js_State *J, double v)
void js_pushstring(js_State *J, const char *v)
{
int n = strlen(v);
size_t n = strlen(v);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
CHECKSTACK(1);
if (n <= soffsetof(js_Value, type)) {
char *s = STACK[TOP].u.shrstr;
@@ -135,6 +137,8 @@ void js_pushstring(js_State *J, const char *v)
void js_pushlstring(js_State *J, const char *v, int n)
{
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
CHECKSTACK(1);
if (n <= soffsetof(js_Value, type)) {
char *s = STACK[TOP].u.shrstr;

View File

@@ -123,20 +123,24 @@ static void Sp_concat(js_State *J)
return;
s = checkstring(J, 0);
n = strlen(s);
n = 1 + strlen(s);
if (js_try(J)) {
js_free(J, out);
js_throw(J);
}
out = js_malloc(J, n + 1);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
out = js_malloc(J, n);
strcpy(out, s);
for (i = 1; i < top; ++i) {
s = js_tostring(J, i);
n += strlen(s);
out = js_realloc(J, out, n + 1);
if (n > JS_STRLIMIT)
js_rangeerror(J, "invalid string length");
out = js_realloc(J, out, n);
strcat(out, s);
}