jscript: Add support for string literals with embedded null bytes.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1314140a37
commit
922049a21d
|
@ -829,7 +829,7 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
|
|||
case LT_NULL:
|
||||
return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
|
||||
case LT_STRING:
|
||||
return push_instr_str(ctx, OP_str, compiler_alloc_string(ctx, literal->u.wstr));
|
||||
return push_instr_str(ctx, OP_str, literal->u.str);
|
||||
case LT_REGEXP:
|
||||
return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags);
|
||||
DEFAULT_UNREACHABLE;
|
||||
|
@ -841,7 +841,7 @@ static HRESULT literal_as_string(compiler_ctx_t *ctx, literal_t *literal, jsstr_
|
|||
{
|
||||
switch(literal->type) {
|
||||
case LT_STRING:
|
||||
*str = compiler_alloc_string(ctx, literal->u.wstr);
|
||||
*str = literal->u.str;
|
||||
break;
|
||||
case LT_DOUBLE:
|
||||
return double_to_string(literal->u.dval, str);
|
||||
|
|
|
@ -373,33 +373,41 @@ static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
|
|||
return tIdentifier;
|
||||
}
|
||||
|
||||
static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endch)
|
||||
static int parse_string_literal(parser_ctx_t *ctx, jsstr_t **ret, WCHAR endch)
|
||||
{
|
||||
const WCHAR *ptr = ++ctx->ptr;
|
||||
WCHAR *wstr;
|
||||
const WCHAR *ptr = ++ctx->ptr, *ret_str = ptr;
|
||||
BOOL needs_unescape = FALSE;
|
||||
WCHAR *unescape_str;
|
||||
size_t len;
|
||||
|
||||
while(ctx->ptr < ctx->end && *ctx->ptr != endch) {
|
||||
if(*ctx->ptr++ == '\\')
|
||||
if(*ctx->ptr++ == '\\') {
|
||||
ctx->ptr++;
|
||||
needs_unescape = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(ctx->ptr == ctx->end)
|
||||
return lex_error(ctx, JS_E_UNTERMINATED_STRING);
|
||||
|
||||
len = ctx->ptr-ptr;
|
||||
|
||||
*ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
|
||||
memcpy(wstr, ptr, len*sizeof(WCHAR));
|
||||
|
||||
len = ctx->ptr - ptr;
|
||||
ctx->ptr++;
|
||||
|
||||
if(!unescape(wstr, &len)) {
|
||||
if(needs_unescape) {
|
||||
ret_str = unescape_str = parser_alloc(ctx, len * sizeof(WCHAR));
|
||||
if(!unescape_str)
|
||||
return lex_error(ctx, E_OUTOFMEMORY);
|
||||
memcpy(unescape_str, ptr, len * sizeof(WCHAR));
|
||||
if(!unescape(unescape_str, &len)) {
|
||||
WARN("unescape failed\n");
|
||||
return lex_error(ctx, E_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
wstr[len] = 0;
|
||||
if(!(*ret = compiler_alloc_string_len(ctx->compiler, ret_str, len)))
|
||||
return lex_error(ctx, E_OUTOFMEMORY);
|
||||
|
||||
/* FIXME: leaking string */
|
||||
return tStringLiteral;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ typedef struct {
|
|||
literal_type_t type;
|
||||
union {
|
||||
double dval;
|
||||
const WCHAR *wstr;
|
||||
jsstr_t *str;
|
||||
BOOL bval;
|
||||
struct {
|
||||
jsstr_t *str;
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct _statement_list_t {
|
|||
statement_t *tail;
|
||||
} statement_list_t;
|
||||
|
||||
static literal_t *new_string_literal(parser_ctx_t*,const WCHAR*);
|
||||
static literal_t *new_string_literal(parser_ctx_t*,jsstr_t*);
|
||||
static literal_t *new_null_literal(parser_ctx_t*);
|
||||
|
||||
typedef struct _property_list_t {
|
||||
|
@ -147,7 +147,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
|
|||
%union {
|
||||
int ival;
|
||||
const WCHAR *srcptr;
|
||||
LPCWSTR wstr;
|
||||
jsstr_t *str;
|
||||
literal_t *literal;
|
||||
struct _argument_list_t *argument_list;
|
||||
case_clausule_t *case_clausule;
|
||||
|
@ -177,7 +177,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
|
|||
%token <identifier> tIdentifier
|
||||
%token <ival> tAssignOper tEqOper tShiftOper tRelOper
|
||||
%token <literal> tNumericLiteral tBooleanLiteral
|
||||
%token <wstr> tStringLiteral
|
||||
%token <str> tStringLiteral
|
||||
%token tEOF
|
||||
|
||||
%type <source_elements> SourceElements
|
||||
|
@ -813,7 +813,7 @@ GetterSetterMethod
|
|||
|
||||
/* Ecma-262 3rd Edition 11.1.5 */
|
||||
PropertyName
|
||||
: IdentifierName { $$ = new_string_literal(ctx, $1); }
|
||||
: IdentifierName { $$ = new_string_literal(ctx, compiler_alloc_string_len(ctx->compiler, $1, strlenW($1))); }
|
||||
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
|
||||
| tNumericLiteral { $$ = $1; }
|
||||
|
||||
|
@ -921,12 +921,12 @@ static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size
|
|||
return stat;
|
||||
}
|
||||
|
||||
static literal_t *new_string_literal(parser_ctx_t *ctx, const WCHAR *str)
|
||||
static literal_t *new_string_literal(parser_ctx_t *ctx, jsstr_t *str)
|
||||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->type = LT_STRING;
|
||||
ret->u.wstr = str;
|
||||
ret->u.str = str;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -180,6 +180,9 @@ ok(tmp === "undefined", "typeof((new Object).doesnotexist = " + tmp);
|
|||
tmp = typeof(testObj.onlyDispID);
|
||||
ok(tmp === "unknown", "typeof(testObj.onlyDispID) = " + tmp);
|
||||
|
||||
ok("\0\0x\0\0".length === 5, "\"\\0\\0x\\0\\0\".length = " + "\0\0x\0\0".length);
|
||||
ok("\0\0x\0\0" === String.fromCharCode(0) + "\0x\0" + String.fromCharCode(0), "\"\\0\\0x\\0\\0\" unexpected");
|
||||
|
||||
ok(testFunc1(true, "test") === true, "testFunc1 not returned true");
|
||||
|
||||
ok(testFunc1.arguments === null, "testFunc1.arguments = " + testFunc1.arguments);
|
||||
|
|
Loading…
Reference in New Issue