Jacek Caban : jscript: Support embedded null bytes in unescape.

Alexandre Julliard julliard at winehq.org
Mon Mar 4 15:08:24 CST 2019


Module: wine
Branch: master
Commit: 79557db98133a2c6062d7416448a41bd4ed33d71
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=79557db98133a2c6062d7416448a41bd4ed33d71

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Mar  1 17:44:07 2019 +0100

jscript: Support embedded null bytes in unescape.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 {




More information about the wine-cvs mailing list