diff --git a/jsmn.c b/jsmn.c index 1b918f5..a9aa5fe 100644 --- a/jsmn.c +++ b/jsmn.c @@ -115,7 +115,19 @@ static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js, break; /* Allows escaped symbol \uXXXX */ case 'u': - /* TODO */ + parser->pos++; + int i=0; + for(;i<4&&js[parser->pos] != '\0';i++) { + // If it isn't a hex character we have an error + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || // 0-9 + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || // A-F + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { // a-f + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; break; /* Unexpected symbol */ default: diff --git a/jsmn_test.c b/jsmn_test.c index 308faf6..c381fcb 100644 --- a/jsmn_test.c +++ b/jsmn_test.c @@ -348,6 +348,50 @@ int test_objects_arrays() { return 0; } +int test_unicode_characters() { + jsmn_parser p; + jsmntok_t tokens[10]; + const char *js; + + int r; + js = "{\"a\":\"\\uAbcD\"}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_SUCCESS); + + js = "{\"a\":\"str\\u0000\"}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_SUCCESS); + + js = "{\"a\":\"\\uFFFFstr\"}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_SUCCESS); + + js = "{\"a\":\"str\\uFFGFstr\"}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_ERROR_INVAL); + + js = "{\"a\":\"str\\u@FfF\"}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_ERROR_INVAL); + + js = "{\"a\":[\"\\u028\"]}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_ERROR_INVAL); + + js = "{\"a\":[\"\\u0280\"]}"; + jsmn_init(&p); + r = jsmn_parse(&p, js, tokens, 10); + check(r == JSMN_SUCCESS); + + return 0; +} + int main() { test(test_empty, "general test for a empty JSON objects/arrays"); test(test_simple, "general test for a simple JSON string"); @@ -358,6 +402,7 @@ int main() { test(test_array_nomem, "test array reading with a smaller number of tokens"); test(test_unquoted_keys, "test unquoted keys (like in JavaScript)"); test(test_objects_arrays, "test objects and arrays"); + test(test_unicode_characters, "test unicode characters"); printf("\nPASSED: %d\nFAILED: %d\n", test_passed, test_failed); return 0; }