Module: wine Branch: master Commit: 79557db98133a2c6062d7416448a41bd4ed33d71 URL: https://source.winehq.org/git/wine.git/?a=commit;h=79557db98133a2c6062d74164...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Mar 1 17:44:07 2019 +0100
jscript: Support embedded null bytes in unescape.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/jscript/json.c | 4 ++-- dlls/jscript/lex.c | 25 +++++++++++++++---------- dlls/jscript/parser.h | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/jscript/json.c b/dlls/jscript/json.c index d440543..b5e6e10 100644 --- a/dlls/jscript/json.c +++ b/dlls/jscript/json.c @@ -89,14 +89,14 @@ static HRESULT parse_json_string(json_parse_ctx_t *ctx, WCHAR **r) return E_OUTOFMEMORY; if(len) memcpy(buf, ptr, len*sizeof(WCHAR)); - buf[len] = 0;
- if(!unescape(buf)) { + if(!unescape(buf, &len)) { FIXME("unescape failed\n"); heap_free(buf); return E_FAIL; }
+ buf[len] = 0; ctx->ptr++; *r = buf; return S_OK; diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c index be20e99..2f0172c 100644 --- a/dlls/jscript/lex.c +++ b/dlls/jscript/lex.c @@ -260,19 +260,20 @@ static BOOL skip_spaces(parser_ctx_t *ctx) return ctx->ptr != ctx->end; }
-BOOL unescape(WCHAR *str) +BOOL unescape(WCHAR *str, size_t *len) { - WCHAR *pd, *p, c; + WCHAR *pd, *p, c, *end = str + *len; int i;
pd = p = str; - while(*p) { + while(p < end) { if(*p != '\') { *pd++ = *p++; continue; }
- p++; + if(++p == end) + return FALSE;
switch(*p) { case ''': @@ -296,6 +297,8 @@ BOOL unescape(WCHAR *str) c = '\r'; break; case 'x': + if(p + 2 >= end) + return FALSE; i = hex_to_int(*++p); if(i == -1) return FALSE; @@ -307,6 +310,8 @@ BOOL unescape(WCHAR *str) c += i; break; case 'u': + if(p + 4 >= end) + return FALSE; i = hex_to_int(*++p); if(i == -1) return FALSE; @@ -330,9 +335,9 @@ BOOL unescape(WCHAR *str) default: if(isdigitW(*p)) { c = *p++ - '0'; - if(isdigitW(*p)) { + if(p < end && isdigitW(*p)) { c = c*8 + (*p++ - '0'); - if(isdigitW(*p)) + if(p < end && isdigitW(*p)) c = c*8 + (*p++ - '0'); } p--; @@ -345,7 +350,7 @@ BOOL unescape(WCHAR *str) p++; }
- *pd = 0; + *len = pd - str; return TRUE; }
@@ -372,7 +377,7 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endc { const WCHAR *ptr = ++ctx->ptr; WCHAR *wstr; - int len; + size_t len;
while(ctx->ptr < ctx->end && *ctx->ptr != endch) { if(*ctx->ptr++ == '\') @@ -386,15 +391,15 @@ static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endc
*ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR)); memcpy(wstr, ptr, len*sizeof(WCHAR)); - wstr[len] = 0;
ctx->ptr++;
- if(!unescape(wstr)) { + if(!unescape(wstr, &len)) { WARN("unescape failed\n"); return lex_error(ctx, E_FAIL); }
+ wstr[len] = 0; return tStringLiteral; }
diff --git a/dlls/jscript/parser.h b/dlls/jscript/parser.h index 03f504f..f4f044c 100644 --- a/dlls/jscript/parser.h +++ b/dlls/jscript/parser.h @@ -63,7 +63,7 @@ static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size) }
BOOL is_identifier_char(WCHAR) DECLSPEC_HIDDEN; -BOOL unescape(WCHAR*) DECLSPEC_HIDDEN; +BOOL unescape(WCHAR*,size_t*) DECLSPEC_HIDDEN; HRESULT parse_decimal(const WCHAR**,const WCHAR*,double*) DECLSPEC_HIDDEN;
typedef enum {