Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a potential UAF caused by JSON parser cache spill. Forum post b25edc1d46. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a163fecca90cab9d1b7bf8ebac78d498 |
User & Date: | drh 2023-10-09 12:46:53 |
Context
2023-11-10
| ||
13:13 | Fix a potential UAF caused by JSON parser cache spill. (Leaf check-in: ce3fc4fc user: drh tags: bedrock-3.43) | |
2023-10-09
| ||
14:05 | Turn on SEH by default when building using MSVC. (check-in: f57e8275 user: drh tags: trunk) | |
12:57 | Merge the latest trunk fixes and enhancements into the jsonb branch, and especially the JSON cache spill UAF fix. (check-in: 9422c24f user: drh tags: jsonb) | |
12:51 | Fix a potential UAF caused by JSON parser cache spill. (check-in: 5b09212a user: drh tags: branch-3.43) | |
12:46 | Fix a potential UAF caused by JSON parser cache spill. Forum post b25edc1d46. (check-in: a163fecc user: drh tags: trunk) | |
12:45 | Flesh out the error state captured by SqliteException.java. Doc additions. (check-in: 5c5397ff user: stephan tags: trunk) | |
Changes
Changes to src/json.c.
︙ | ︙ | |||
2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 | if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, "replace"); return; } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pParse->useMod = 1; pNode = jsonLookup(pParse, zPath, 0, ctx); if( pParse->nErr ) goto replace_err; if( pNode ){ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } jsonReturnJson(pParse, pParse->aNode, ctx, 1); replace_err: jsonDebugPrintParse(pParse); } /* ** json_set(JSON, PATH, VALUE, ...) ** ** Set the value at PATH to VALUE. Create the PATH if it does not already | > > | 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 | if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, "replace"); return; } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); pParse->useMod = 1; pNode = jsonLookup(pParse, zPath, 0, ctx); if( pParse->nErr ) goto replace_err; if( pNode ){ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } jsonReturnJson(pParse, pParse->aNode, ctx, 1); replace_err: jsonDebugPrintParse(pParse); jsonParseFree(pParse); } /* ** json_set(JSON, PATH, VALUE, ...) ** ** Set the value at PATH to VALUE. Create the PATH if it does not already |
︙ | ︙ | |||
2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 | if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; pParse->useMod = 1; pNode = jsonLookup(pParse, zPath, &bApnd, ctx); if( pParse->oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; }else if( pParse->nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } jsonDebugPrintParse(pParse); jsonReturnJson(pParse, pParse->aNode, ctx, 1); | > < < > | 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 | if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); if( pParse==0 ) return; pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; pParse->useMod = 1; pNode = jsonLookup(pParse, zPath, &bApnd, ctx); if( pParse->oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; }else if( pParse->nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } jsonDebugPrintParse(pParse); jsonReturnJson(pParse, pParse->aNode, ctx, 1); jsonSetDone: jsonParseFree(pParse); } /* ** json_type(JSON) ** json_type(JSON, PATH) ** ** Return the top-level "type" of a JSON string. json_type() raises an |
︙ | ︙ |
Changes to test/json101.test.
︙ | ︙ | |||
1009 1010 1011 1012 1013 1014 1015 | SELECT json_group_array(x) FROM c; } {[1,2.0,null,"three"]} do_execsql_test json101-21.27 { WITH c(x,y) AS (VALUES('a',1),('b',2.0),('c',NULL),(NULL,'three'),('e','four')) SELECT json_group_object(x,y) FROM c; } {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}} | | > | > > > > > > > > > > > > > > > > > > > > > > | 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | SELECT json_group_array(x) FROM c; } {[1,2.0,null,"three"]} do_execsql_test json101-21.27 { WITH c(x,y) AS (VALUES('a',1),('b',2.0),('c',NULL),(NULL,'three'),('e','four')) SELECT json_group_object(x,y) FROM c; } {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}} # 2023-10-09 https://sqlite.org/forum/forumpost/b25edc1d46 # UAF due to JSON cache overflow # do_execsql_test json101-22.1 { SELECT json_set( '{}', '$.a', json('1'), '$.a', json('2'), '$.b', json('3'), '$.b', json('4'), '$.c', json('5'), '$.c', json('6') ); } {{{"a":2,"b":4,"c":6}}} do_execsql_test json101-22.2 { SELECT json_replace( '{"a":7,"b":8,"c":9}', '$.a', json('1'), '$.a', json('2'), '$.b', json('3'), '$.b', json('4'), '$.c', json('5'), '$.c', json('6') ); } {{{"a":2,"b":4,"c":6}}} finish_test |