From f30503ce4e0482d638a2561ca3ddc6e1291a104a Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Sun, 28 Jun 2015 18:09:10 +0100 Subject: [PATCH] Fix incompatible JSON errors This fixes differences in error codes with PHP 5 and 7. The malformed UTF-8 and control character error codes are now returned even in non-string context which makes it the same as it was in PHP 5 json ext. --- ext/json/json_scanner.c | 1116 +++++++++++++++++++--------------- ext/json/json_scanner.re | 16 +- ext/json/tests/bug69187.phpt | 16 + 3 files changed, 662 insertions(+), 486 deletions(-) diff --git a/ext/json/json_scanner.c b/ext/json/json_scanner.c index 7b192c43f1..70662b5c31 100644 --- a/ext/json/json_scanner.c +++ b/ext/json/json_scanner.c @@ -148,74 +148,110 @@ yyc_JS: 0, 0, 0, 0, 0, 0, 0, 0, }; yych = *YYCURSOR; - if (yych <= '9') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy3; - if (yych <= 0x08) goto yy5; - if (yych <= '\t') goto yy7; - goto yy9; + if (yych <= ']') { + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy5; + } else { + if (yych <= '\t') goto yy7; + if (yych <= '\n') goto yy9; + goto yy5; + } } else { - if (yych == '\r') goto yy10; - if (yych <= 0x1F) goto yy5; - goto yy7; + if (yych <= 0x1F) { + if (yych <= '\r') goto yy10; + goto yy5; + } else { + if (yych <= ' ') goto yy11; + if (yych <= '!') goto yy12; + goto yy14; + } } } else { - if (yych <= ',') { - if (yych == '"') goto yy11; - if (yych <= '+') goto yy5; - goto yy13; + if (yych <= '0') { + if (yych <= ',') { + if (yych <= '+') goto yy12; + goto yy16; + } else { + if (yych <= '-') goto yy18; + if (yych <= '/') goto yy12; + goto yy19; + } } else { - if (yych <= '-') goto yy15; - if (yych <= '/') goto yy5; - if (yych <= '0') goto yy16; - goto yy18; + if (yych <= 'Z') { + if (yych <= '9') goto yy21; + if (yych <= ':') goto yy22; + goto yy12; + } else { + if (yych <= '[') goto yy24; + if (yych <= '\\') goto yy12; + goto yy26; + } } } } else { - if (yych <= 'm') { - if (yych <= '\\') { - if (yych <= ':') goto yy19; - if (yych == '[') goto yy21; - goto yy5; + if (yych <= '}') { + if (yych <= 's') { + if (yych <= 'f') { + if (yych <= 'e') goto yy12; + goto yy28; + } else { + if (yych == 'n') goto yy29; + goto yy12; + } } else { - if (yych <= ']') goto yy23; - if (yych == 'f') goto yy25; - goto yy5; + if (yych <= 'z') { + if (yych <= 't') goto yy30; + goto yy12; + } else { + if (yych <= '{') goto yy31; + if (yych <= '|') goto yy12; + goto yy33; + } } } else { - if (yych <= 'z') { - if (yych <= 'n') goto yy26; - if (yych == 't') goto yy27; - goto yy5; + if (yych <= 0xEC) { + if (yych <= 0xC1) { + if (yych <= 0x7F) goto yy12; + goto yy35; + } else { + if (yych <= 0xDF) goto yy37; + if (yych <= 0xE0) goto yy38; + goto yy39; + } } else { - if (yych <= '{') goto yy28; - if (yych == '}') goto yy30; - goto yy5; + if (yych <= 0xF0) { + if (yych <= 0xED) goto yy40; + if (yych <= 0xEF) goto yy41; + goto yy42; + } else { + if (yych <= 0xF3) goto yy43; + if (yych <= 0xF4) goto yy44; + goto yy35; + } } } } -yy3: ++YYCURSOR; { if (s->limit < s->cursor) { return PHP_JSON_T_EOI; } else { - s->errcode = PHP_JSON_ERROR_SYNTAX; + s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } } yy5: ++YYCURSOR; -yy6: { - s->errcode = PHP_JSON_ERROR_SYNTAX; + s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } yy7: ++YYCURSOR; yych = *YYCURSOR; - goto yy58; + goto yy82; yy8: { goto std; } yy9: @@ -223,9 +259,19 @@ yy9: goto yy8; yy10: yych = *++YYCURSOR; - if (yych == '\n') goto yy59; - goto yy58; + if (yych == '\n') goto yy83; + goto yy82; yy11: + yych = *++YYCURSOR; + goto yy82; +yy12: + ++YYCURSOR; +yy13: + { + s->errcode = PHP_JSON_ERROR_SYNTAX; + return PHP_JSON_T_ERROR; + } +yy14: ++YYCURSOR; { s->str_start = s->cursor; @@ -233,25 +279,25 @@ yy11: PHP_JSON_CONDITION_SET(STR_P1); PHP_JSON_CONDITION_GOTO(STR_P1); } -yy13: +yy16: ++YYCURSOR; { return ','; } -yy15: +yy18: yych = *++YYCURSOR; - if (yych <= '/') goto yy6; - if (yych <= '0') goto yy56; - if (yych <= '9') goto yy46; - goto yy6; -yy16: + if (yych <= '/') goto yy13; + if (yych <= '0') goto yy80; + if (yych <= '9') goto yy70; + goto yy13; +yy19: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'D') { - if (yych == '.') goto yy48; + if (yych == '.') goto yy72; } else { - if (yych <= 'E') goto yy49; - if (yych == 'e') goto yy49; + if (yych <= 'E') goto yy73; + if (yych == 'e') goto yy73; } -yy17: +yy20: { zend_bool bigint = 0, negative = s->token[0] == '-'; size_t digits = (size_t) (s->cursor - s->token - negative); @@ -276,161 +322,263 @@ yy17: return PHP_JSON_T_DOUBLE; } } -yy18: +yy21: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy47; -yy19: + goto yy71; +yy22: ++YYCURSOR; { return ':'; } -yy21: +yy24: ++YYCURSOR; { return '['; } -yy23: +yy26: ++YYCURSOR; { return ']'; } -yy25: +yy28: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'a') goto yy41; - goto yy6; -yy26: + if (yych == 'a') goto yy65; + goto yy13; +yy29: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'u') goto yy37; - goto yy6; -yy27: + if (yych == 'u') goto yy61; + goto yy13; +yy30: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'r') goto yy32; - goto yy6; -yy28: + if (yych == 'r') goto yy57; + goto yy13; +yy31: ++YYCURSOR; { return '{'; } -yy30: +yy33: ++YYCURSOR; { return '}'; } -yy32: +yy35: + ++YYCURSOR; +yy36: + { + s->errcode = PHP_JSON_ERROR_UTF8; + return PHP_JSON_T_ERROR; + } +yy37: yych = *++YYCURSOR; - if (yych == 'u') goto yy34; -yy33: + if (yych <= 0x7F) goto yy36; + if (yych <= 0xBF) goto yy48; + goto yy36; +yy38: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x9F) goto yy36; + if (yych <= 0xBF) goto yy56; + goto yy36; +yy39: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy36; + if (yych <= 0xBF) goto yy55; + goto yy36; +yy40: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy36; + if (yych <= 0x9F) goto yy54; + goto yy36; +yy41: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy36; + if (yych <= 0xBF) goto yy53; + goto yy36; +yy42: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x8F) goto yy36; + if (yych <= 0xBF) goto yy51; + goto yy36; +yy43: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy36; + if (yych <= 0xBF) goto yy49; + goto yy36; +yy44: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x7F) goto yy36; + if (yych >= 0x90) goto yy36; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy47; +yy46: YYCURSOR = YYMARKER; if (yyaccept <= 1) { if (yyaccept == 0) { - goto yy17; + goto yy20; } else { - goto yy6; + goto yy13; } } else { - goto yy53; + if (yyaccept == 2) { + goto yy36; + } else { + goto yy77; + } } -yy34: +yy47: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych >= 0xC0) goto yy46; +yy48: + yych = *++YYCURSOR; + goto yy13; +yy49: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych >= 0xC0) goto yy46; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy51: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych >= 0xC0) goto yy46; + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy53: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy54: yych = *++YYCURSOR; - if (yych != 'e') goto yy33; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy55: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy56: + yych = *++YYCURSOR; + if (yych <= 0x7F) goto yy46; + if (yych <= 0xBF) goto yy48; + goto yy46; +yy57: + yych = *++YYCURSOR; + if (yych != 'u') goto yy46; + yych = *++YYCURSOR; + if (yych != 'e') goto yy46; ++YYCURSOR; { ZVAL_TRUE(&s->value); return PHP_JSON_T_TRUE; } -yy37: +yy61: yych = *++YYCURSOR; - if (yych != 'l') goto yy33; + if (yych != 'l') goto yy46; yych = *++YYCURSOR; - if (yych != 'l') goto yy33; + if (yych != 'l') goto yy46; ++YYCURSOR; { ZVAL_NULL(&s->value); return PHP_JSON_T_NUL; } -yy41: +yy65: yych = *++YYCURSOR; - if (yych != 'l') goto yy33; + if (yych != 'l') goto yy46; yych = *++YYCURSOR; - if (yych != 's') goto yy33; + if (yych != 's') goto yy46; yych = *++YYCURSOR; - if (yych != 'e') goto yy33; + if (yych != 'e') goto yy46; ++YYCURSOR; { ZVAL_FALSE(&s->value); return PHP_JSON_T_FALSE; } -yy46: +yy70: yyaccept = 0; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; -yy47: +yy71: if (yybm[0+yych] & 64) { - goto yy46; + goto yy70; } if (yych <= 'D') { - if (yych != '.') goto yy17; + if (yych != '.') goto yy20; } else { - if (yych <= 'E') goto yy49; - if (yych == 'e') goto yy49; - goto yy17; + if (yych <= 'E') goto yy73; + if (yych == 'e') goto yy73; + goto yy20; } -yy48: +yy72: yych = *++YYCURSOR; - if (yych <= '/') goto yy33; - if (yych <= '9') goto yy54; - goto yy33; -yy49: + if (yych <= '/') goto yy46; + if (yych <= '9') goto yy78; + goto yy46; +yy73: yych = *++YYCURSOR; if (yych <= ',') { - if (yych != '+') goto yy33; + if (yych != '+') goto yy46; } else { - if (yych <= '-') goto yy50; - if (yych <= '/') goto yy33; - if (yych <= '9') goto yy51; - goto yy33; + if (yych <= '-') goto yy74; + if (yych <= '/') goto yy46; + if (yych <= '9') goto yy75; + goto yy46; } -yy50: +yy74: yych = *++YYCURSOR; - if (yych <= '/') goto yy33; - if (yych >= ':') goto yy33; -yy51: + if (yych <= '/') goto yy46; + if (yych >= ':') goto yy46; +yy75: ++YYCURSOR; yych = *YYCURSOR; - if (yych <= '/') goto yy53; - if (yych <= '9') goto yy51; -yy53: + if (yych <= '/') goto yy77; + if (yych <= '9') goto yy75; +yy77: { ZVAL_DOUBLE(&s->value, zend_strtod((char *) s->token, NULL)); return PHP_JSON_T_DOUBLE; } -yy54: - yyaccept = 2; +yy78: + yyaccept = 3; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; if (yych <= 'D') { - if (yych <= '/') goto yy53; - if (yych <= '9') goto yy54; - goto yy53; + if (yych <= '/') goto yy77; + if (yych <= '9') goto yy78; + goto yy77; } else { - if (yych <= 'E') goto yy49; - if (yych == 'e') goto yy49; - goto yy53; + if (yych <= 'E') goto yy73; + if (yych == 'e') goto yy73; + goto yy77; } -yy56: +yy80: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'D') { - if (yych == '.') goto yy48; - goto yy17; + if (yych == '.') goto yy72; + goto yy20; } else { - if (yych <= 'E') goto yy49; - if (yych == 'e') goto yy49; - goto yy17; + if (yych <= 'E') goto yy73; + if (yych == 'e') goto yy73; + goto yy20; } -yy57: +yy81: ++YYCURSOR; yych = *YYCURSOR; -yy58: +yy82: if (yybm[0+yych] & 128) { - goto yy57; + goto yy81; } goto yy8; -yy59: +yy83: ++YYCURSOR; yych = *YYCURSOR; goto yy8; @@ -440,39 +588,39 @@ yyc_STR_P1: yych = *YYCURSOR; if (yych <= 0xDF) { if (yych <= '[') { - if (yych <= 0x1F) goto yy62; - if (yych == '"') goto yy66; - goto yy64; + if (yych <= 0x1F) goto yy86; + if (yych == '"') goto yy90; + goto yy88; } else { - if (yych <= '\\') goto yy68; - if (yych <= 0x7F) goto yy64; - if (yych <= 0xC1) goto yy70; - goto yy72; + if (yych <= '\\') goto yy92; + if (yych <= 0x7F) goto yy88; + if (yych <= 0xC1) goto yy94; + goto yy96; } } else { if (yych <= 0xEF) { - if (yych <= 0xE0) goto yy73; - if (yych <= 0xEC) goto yy74; - if (yych <= 0xED) goto yy75; - goto yy76; + if (yych <= 0xE0) goto yy97; + if (yych <= 0xEC) goto yy98; + if (yych <= 0xED) goto yy99; + goto yy100; } else { - if (yych <= 0xF0) goto yy77; - if (yych <= 0xF3) goto yy78; - if (yych <= 0xF4) goto yy79; - goto yy70; + if (yych <= 0xF0) goto yy101; + if (yych <= 0xF3) goto yy102; + if (yych <= 0xF4) goto yy103; + goto yy94; } } -yy62: +yy86: ++YYCURSOR; { s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } -yy64: +yy88: ++YYCURSOR; -yy65: +yy89: { PHP_JSON_CONDITION_GOTO(STR_P1); } -yy66: +yy90: ++YYCURSOR; { zend_string *str; @@ -496,392 +644,392 @@ yy66: return PHP_JSON_T_STRING; } } -yy68: +yy92: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'e') { if (yych <= '/') { - if (yych == '"') goto yy92; - if (yych >= '/') goto yy92; + if (yych == '"') goto yy116; + if (yych >= '/') goto yy116; } else { if (yych <= '\\') { - if (yych >= '\\') goto yy92; + if (yych >= '\\') goto yy116; } else { - if (yych == 'b') goto yy92; + if (yych == 'b') goto yy116; } } } else { if (yych <= 'q') { - if (yych <= 'f') goto yy92; - if (yych == 'n') goto yy92; + if (yych <= 'f') goto yy116; + if (yych == 'n') goto yy116; } else { if (yych <= 's') { - if (yych <= 'r') goto yy92; + if (yych <= 'r') goto yy116; } else { - if (yych <= 't') goto yy92; - if (yych <= 'u') goto yy94; + if (yych <= 't') goto yy116; + if (yych <= 'u') goto yy118; } } } -yy69: +yy93: { s->errcode = PHP_JSON_ERROR_SYNTAX; return PHP_JSON_T_ERROR; } -yy70: +yy94: ++YYCURSOR; -yy71: +yy95: { s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } -yy72: +yy96: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy71; - if (yych <= 0xBF) goto yy83; - goto yy71; -yy73: + if (yych <= 0x7F) goto yy95; + if (yych <= 0xBF) goto yy107; + goto yy95; +yy97: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x9F) goto yy71; - if (yych <= 0xBF) goto yy91; - goto yy71; -yy74: + if (yych <= 0x9F) goto yy95; + if (yych <= 0xBF) goto yy115; + goto yy95; +yy98: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy71; - if (yych <= 0xBF) goto yy90; - goto yy71; -yy75: + if (yych <= 0x7F) goto yy95; + if (yych <= 0xBF) goto yy114; + goto yy95; +yy99: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy71; - if (yych <= 0x9F) goto yy89; - goto yy71; -yy76: + if (yych <= 0x7F) goto yy95; + if (yych <= 0x9F) goto yy113; + goto yy95; +yy100: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy71; - if (yych <= 0xBF) goto yy88; - goto yy71; -yy77: + if (yych <= 0x7F) goto yy95; + if (yych <= 0xBF) goto yy112; + goto yy95; +yy101: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x8F) goto yy71; - if (yych <= 0xBF) goto yy86; - goto yy71; -yy78: + if (yych <= 0x8F) goto yy95; + if (yych <= 0xBF) goto yy110; + goto yy95; +yy102: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy71; - if (yych <= 0xBF) goto yy84; - goto yy71; -yy79: + if (yych <= 0x7F) goto yy95; + if (yych <= 0xBF) goto yy108; + goto yy95; +yy103: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x7F) goto yy71; - if (yych >= 0x90) goto yy71; + if (yych <= 0x7F) goto yy95; + if (yych >= 0x90) goto yy95; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy82; -yy81: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy106; +yy105: YYCURSOR = YYMARKER; if (yyaccept <= 1) { if (yyaccept == 0) { - goto yy69; + goto yy93; } else { - goto yy71; + goto yy95; } } else { - goto yy103; + goto yy127; } -yy82: +yy106: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych >= 0xC0) goto yy81; -yy83: + if (yych <= 0x7F) goto yy105; + if (yych >= 0xC0) goto yy105; +yy107: yych = *++YYCURSOR; - goto yy65; -yy84: + goto yy89; +yy108: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych >= 0xC0) goto yy81; + if (yych <= 0x7F) goto yy105; + if (yych >= 0xC0) goto yy105; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy86: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy110: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych >= 0xC0) goto yy81; + if (yych <= 0x7F) goto yy105; + if (yych >= 0xC0) goto yy105; yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy88: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy112: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy89: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy113: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy90: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy114: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy91: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy115: yych = *++YYCURSOR; - if (yych <= 0x7F) goto yy81; - if (yych <= 0xBF) goto yy83; - goto yy81; -yy92: + if (yych <= 0x7F) goto yy105; + if (yych <= 0xBF) goto yy107; + goto yy105; +yy116: ++YYCURSOR; { s->str_esc++; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy94: +yy118: yych = *++YYCURSOR; if (yych <= 'D') { if (yych <= '9') { - if (yych <= '/') goto yy81; - if (yych >= '1') goto yy96; + if (yych <= '/') goto yy105; + if (yych >= '1') goto yy120; } else { - if (yych <= '@') goto yy81; - if (yych <= 'C') goto yy96; - goto yy97; + if (yych <= '@') goto yy105; + if (yych <= 'C') goto yy120; + goto yy121; } } else { if (yych <= 'c') { - if (yych <= 'F') goto yy96; - if (yych <= '`') goto yy81; - goto yy96; + if (yych <= 'F') goto yy120; + if (yych <= '`') goto yy105; + goto yy120; } else { - if (yych <= 'd') goto yy97; - if (yych <= 'f') goto yy96; - goto yy81; + if (yych <= 'd') goto yy121; + if (yych <= 'f') goto yy120; + goto yy105; } } yych = *++YYCURSOR; if (yych <= '9') { - if (yych <= '/') goto yy81; - if (yych <= '0') goto yy116; - if (yych <= '7') goto yy117; - goto yy98; + if (yych <= '/') goto yy105; + if (yych <= '0') goto yy140; + if (yych <= '7') goto yy141; + goto yy122; } else { if (yych <= 'F') { - if (yych <= '@') goto yy81; - goto yy98; + if (yych <= '@') goto yy105; + goto yy122; } else { - if (yych <= '`') goto yy81; - if (yych <= 'f') goto yy98; - goto yy81; + if (yych <= '`') goto yy105; + if (yych <= 'f') goto yy122; + goto yy105; } } -yy96: +yy120: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych <= '9') goto yy98; - goto yy81; + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy122; + goto yy105; } else { - if (yych <= 'F') goto yy98; - if (yych <= '`') goto yy81; - if (yych <= 'f') goto yy98; - goto yy81; + if (yych <= 'F') goto yy122; + if (yych <= '`') goto yy105; + if (yych <= 'f') goto yy122; + goto yy105; } -yy97: +yy121: yych = *++YYCURSOR; if (yych <= 'B') { if (yych <= '7') { - if (yych <= '/') goto yy81; + if (yych <= '/') goto yy105; } else { - if (yych <= '9') goto yy99; - if (yych <= '@') goto yy81; - goto yy99; + if (yych <= '9') goto yy123; + if (yych <= '@') goto yy105; + goto yy123; } } else { if (yych <= '`') { - if (yych <= 'F') goto yy100; - goto yy81; + if (yych <= 'F') goto yy124; + goto yy105; } else { - if (yych <= 'b') goto yy99; - if (yych <= 'f') goto yy100; - goto yy81; + if (yych <= 'b') goto yy123; + if (yych <= 'f') goto yy124; + goto yy105; } } -yy98: +yy122: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych <= '9') goto yy113; - goto yy81; + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy137; + goto yy105; } else { - if (yych <= 'F') goto yy113; - if (yych <= '`') goto yy81; - if (yych <= 'f') goto yy113; - goto yy81; + if (yych <= 'F') goto yy137; + if (yych <= '`') goto yy105; + if (yych <= 'f') goto yy137; + goto yy105; } -yy99: +yy123: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych <= '9') goto yy104; - goto yy81; + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy128; + goto yy105; } else { - if (yych <= 'F') goto yy104; - if (yych <= '`') goto yy81; - if (yych <= 'f') goto yy104; - goto yy81; + if (yych <= 'F') goto yy128; + if (yych <= '`') goto yy105; + if (yych <= 'f') goto yy128; + goto yy105; } -yy100: +yy124: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy101; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy125; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy101: +yy125: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy102; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy126; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy102: +yy126: ++YYCURSOR; -yy103: +yy127: { s->errcode = PHP_JSON_ERROR_UTF16; return PHP_JSON_T_ERROR; } -yy104: +yy128: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy105; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy129; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy105: +yy129: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if (yych != '\\') goto yy103; + if (yych != '\\') goto yy127; yych = *++YYCURSOR; - if (yych != 'u') goto yy81; + if (yych != 'u') goto yy105; yych = *++YYCURSOR; - if (yych == 'D') goto yy108; - if (yych != 'd') goto yy81; -yy108: + if (yych == 'D') goto yy132; + if (yych != 'd') goto yy105; +yy132: yych = *++YYCURSOR; - if (yych <= 'B') goto yy81; - if (yych <= 'F') goto yy109; - if (yych <= 'b') goto yy81; - if (yych >= 'g') goto yy81; -yy109: + if (yych <= 'B') goto yy105; + if (yych <= 'F') goto yy133; + if (yych <= 'b') goto yy105; + if (yych >= 'g') goto yy105; +yy133: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy110; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy134; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy110: +yy134: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy111; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy135; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy111: +yy135: ++YYCURSOR; { s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy113: +yy137: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy114; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy138; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy114: +yy138: ++YYCURSOR; { s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy116: +yy140: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych <= '7') goto yy121; - if (yych <= '9') goto yy118; - goto yy81; + if (yych <= '/') goto yy105; + if (yych <= '7') goto yy145; + if (yych <= '9') goto yy142; + goto yy105; } else { - if (yych <= 'F') goto yy118; - if (yych <= '`') goto yy81; - if (yych <= 'f') goto yy118; - goto yy81; + if (yych <= 'F') goto yy142; + if (yych <= '`') goto yy105; + if (yych <= 'f') goto yy142; + goto yy105; } -yy117: +yy141: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy118; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy142; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy118: +yy142: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy119; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy143; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy119: +yy143: ++YYCURSOR; { s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } -yy121: +yy145: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy81; - if (yych >= ':') goto yy81; + if (yych <= '/') goto yy105; + if (yych >= ':') goto yy105; } else { - if (yych <= 'F') goto yy122; - if (yych <= '`') goto yy81; - if (yych >= 'g') goto yy81; + if (yych <= 'F') goto yy146; + if (yych <= '`') goto yy105; + if (yych >= 'g') goto yy105; } -yy122: +yy146: ++YYCURSOR; { s->str_esc += 5; @@ -890,22 +1038,22 @@ yy122: /* *********************************** */ yyc_STR_P2: yych = *YYCURSOR; - if (yych == '"') goto yy128; - if (yych == '\\') goto yy130; + if (yych == '"') goto yy152; + if (yych == '\\') goto yy154; ++YYCURSOR; { PHP_JSON_CONDITION_GOTO(STR_P2); } -yy128: +yy152: ++YYCURSOR; YYSETCONDITION(yycJS); { PHP_JSON_SCANNER_COPY_ESC(); return PHP_JSON_T_STRING; } -yy130: +yy154: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych == 'u') goto yy132; -yy131: + if (yych == 'u') goto yy156; +yy155: { char esc; PHP_JSON_SCANNER_COPY_ESC(); @@ -939,103 +1087,103 @@ yy131: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy132: +yy156: yych = *++YYCURSOR; if (yych <= 'D') { if (yych <= '9') { - if (yych <= '/') goto yy133; - if (yych <= '0') goto yy134; - goto yy135; + if (yych <= '/') goto yy157; + if (yych <= '0') goto yy158; + goto yy159; } else { - if (yych <= '@') goto yy133; - if (yych <= 'C') goto yy135; - goto yy136; + if (yych <= '@') goto yy157; + if (yych <= 'C') goto yy159; + goto yy160; } } else { if (yych <= 'c') { - if (yych <= 'F') goto yy135; - if (yych >= 'a') goto yy135; + if (yych <= 'F') goto yy159; + if (yych >= 'a') goto yy159; } else { - if (yych <= 'd') goto yy136; - if (yych <= 'f') goto yy135; + if (yych <= 'd') goto yy160; + if (yych <= 'f') goto yy159; } } -yy133: +yy157: YYCURSOR = YYMARKER; - goto yy131; -yy134: + goto yy155; +yy158: yych = *++YYCURSOR; if (yych <= '9') { - if (yych <= '/') goto yy133; - if (yych <= '0') goto yy151; - if (yych <= '7') goto yy152; - goto yy138; + if (yych <= '/') goto yy157; + if (yych <= '0') goto yy175; + if (yych <= '7') goto yy176; + goto yy162; } else { if (yych <= 'F') { - if (yych <= '@') goto yy133; - goto yy138; + if (yych <= '@') goto yy157; + goto yy162; } else { - if (yych <= '`') goto yy133; - if (yych <= 'f') goto yy138; - goto yy133; + if (yych <= '`') goto yy157; + if (yych <= 'f') goto yy162; + goto yy157; } } -yy135: +yy159: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych <= '9') goto yy138; - goto yy133; + if (yych <= '/') goto yy157; + if (yych <= '9') goto yy162; + goto yy157; } else { - if (yych <= 'F') goto yy138; - if (yych <= '`') goto yy133; - if (yych <= 'f') goto yy138; - goto yy133; + if (yych <= 'F') goto yy162; + if (yych <= '`') goto yy157; + if (yych <= 'f') goto yy162; + goto yy157; } -yy136: +yy160: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych <= '7') goto yy138; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych <= '7') goto yy162; + if (yych >= ':') goto yy157; } else { - if (yych <= 'B') goto yy137; - if (yych <= '`') goto yy133; - if (yych >= 'c') goto yy133; + if (yych <= 'B') goto yy161; + if (yych <= '`') goto yy157; + if (yych >= 'c') goto yy157; } -yy137: +yy161: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych <= '9') goto yy142; - goto yy133; + if (yych <= '/') goto yy157; + if (yych <= '9') goto yy166; + goto yy157; } else { - if (yych <= 'F') goto yy142; - if (yych <= '`') goto yy133; - if (yych <= 'f') goto yy142; - goto yy133; + if (yych <= 'F') goto yy166; + if (yych <= '`') goto yy157; + if (yych <= 'f') goto yy166; + goto yy157; } -yy138: +yy162: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy139; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy163; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy139: +yy163: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy140; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy164; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy140: +yy164: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 4); @@ -1046,51 +1194,51 @@ yy140: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy142: +yy166: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy143; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy167; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy143: +yy167: yych = *++YYCURSOR; - if (yych != '\\') goto yy133; + if (yych != '\\') goto yy157; yych = *++YYCURSOR; - if (yych != 'u') goto yy133; + if (yych != 'u') goto yy157; yych = *++YYCURSOR; - if (yych == 'D') goto yy146; - if (yych != 'd') goto yy133; -yy146: + if (yych == 'D') goto yy170; + if (yych != 'd') goto yy157; +yy170: yych = *++YYCURSOR; - if (yych <= 'B') goto yy133; - if (yych <= 'F') goto yy147; - if (yych <= 'b') goto yy133; - if (yych >= 'g') goto yy133; -yy147: + if (yych <= 'B') goto yy157; + if (yych <= 'F') goto yy171; + if (yych <= 'b') goto yy157; + if (yych >= 'g') goto yy157; +yy171: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy148; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy172; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy148: +yy172: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy149; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy173; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy149: +yy173: ++YYCURSOR; { int utf32, utf16_hi, utf16_lo; @@ -1105,40 +1253,40 @@ yy149: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy151: +yy175: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych <= '7') goto yy156; - if (yych <= '9') goto yy153; - goto yy133; + if (yych <= '/') goto yy157; + if (yych <= '7') goto yy180; + if (yych <= '9') goto yy177; + goto yy157; } else { - if (yych <= 'F') goto yy153; - if (yych <= '`') goto yy133; - if (yych <= 'f') goto yy153; - goto yy133; + if (yych <= 'F') goto yy177; + if (yych <= '`') goto yy157; + if (yych <= 'f') goto yy177; + goto yy157; } -yy152: +yy176: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy153; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy177; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy153: +yy177: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy154; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy178; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy154: +yy178: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 3); @@ -1148,17 +1296,17 @@ yy154: s->str_start = s->cursor; PHP_JSON_CONDITION_GOTO(STR_P2); } -yy156: +yy180: yych = *++YYCURSOR; if (yych <= '@') { - if (yych <= '/') goto yy133; - if (yych >= ':') goto yy133; + if (yych <= '/') goto yy157; + if (yych >= ':') goto yy157; } else { - if (yych <= 'F') goto yy157; - if (yych <= '`') goto yy133; - if (yych >= 'g') goto yy133; + if (yych <= 'F') goto yy181; + if (yych <= '`') goto yy157; + if (yych >= 'g') goto yy157; } -yy157: +yy181: ++YYCURSOR; { int utf16 = php_json_ucs2_to_int(s, 2); diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index 82cf69b457..1a8a68dca8 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -138,7 +138,7 @@ std: UTF16_2 = UTFPREF "0" HEX7 HEX{2} ; UTF16_3 = UTFPREF ( ( ( HEXC | [efEF] ) HEX ) | ( [dD] HEX7 ) ) HEX{2} ; UTF16_4 = UTFPREF [dD] [89abAB] HEX{2} UTFPREF [dD] [c-fC-F] HEX{2} ; - + "{" { return '{'; } "}" { return '}'; } "[" { return '['; } @@ -190,7 +190,7 @@ std: if (s->limit < s->cursor) { return PHP_JSON_T_EOI; } else { - s->errcode = PHP_JSON_ERROR_SYNTAX; + s->errcode = PHP_JSON_ERROR_CTRL_CHAR; return PHP_JSON_T_ERROR; } } @@ -200,6 +200,18 @@ std: PHP_JSON_CONDITION_SET(STR_P1); PHP_JSON_CONDITION_GOTO(STR_P1); } + CTRL { + s->errcode = PHP_JSON_ERROR_CTRL_CHAR; + return PHP_JSON_T_ERROR; + } + UTF8 { + s->errcode = PHP_JSON_ERROR_SYNTAX; + return PHP_JSON_T_ERROR; + } + ANY { + s->errcode = PHP_JSON_ERROR_UTF8; + return PHP_JSON_T_ERROR; + } CTRL { s->errcode = PHP_JSON_ERROR_CTRL_CHAR; diff --git a/ext/json/tests/bug69187.phpt b/ext/json/tests/bug69187.phpt index bc1883e605..d39dbe522d 100644 --- a/ext/json/tests/bug69187.phpt +++ b/ext/json/tests/bug69187.phpt @@ -17,6 +17,18 @@ var_dump(json_decode(1)); var_dump(json_last_error()); var_dump(json_decode(TRUE)); var_dump(json_last_error()); + +json_decode("\xED\xA0\xB4"); +var_dump(json_last_error()); + +json_decode("\x00"); +var_dump(json_last_error()); + +json_decode("\"\xED\xA0\xB4\""); +var_dump(json_last_error()); + +json_decode("\"\x00\""); +var_dump(json_last_error()); ?> --EXPECT-- NULL @@ -31,3 +43,7 @@ int(1) int(0) int(1) int(0) +int(5) +int(3) +int(5) +int(3) -- 2.40.0