File tree 3 files changed +28
-3
lines changed 3 files changed +28
-3
lines changed Original file line number Diff line number Diff line change 19
19
20
20
#include "common/jsonapi.h"
21
21
#include "mb/pg_wchar.h"
22
+ #include "port/pg_lfind.h"
22
23
23
24
#ifndef FRONTEND
24
25
#include "miscadmin.h"
@@ -844,7 +845,7 @@ json_lex_string(JsonLexContext *lex)
844
845
}
845
846
else
846
847
{
847
- char * p ;
848
+ char * p = s ;
848
849
849
850
if (hi_surrogate != -1 )
850
851
return JSON_UNICODE_LOW_SURROGATE ;
@@ -853,11 +854,17 @@ json_lex_string(JsonLexContext *lex)
853
854
* Skip to the first byte that requires special handling, so we
854
855
* can batch calls to appendBinaryStringInfo.
855
856
*/
856
- for (p = s ; p < end ; p ++ )
857
+ while (p < end - sizeof (Vector8 ) &&
858
+ !pg_lfind8 ('\\' , (uint8 * ) p , sizeof (Vector8 )) &&
859
+ !pg_lfind8 ('"' , (uint8 * ) p , sizeof (Vector8 )) &&
860
+ !pg_lfind8_le (31 , (uint8 * ) p , sizeof (Vector8 )))
861
+ p += sizeof (Vector8 );
862
+
863
+ for (; p < end ; p ++ )
857
864
{
858
865
if (* p == '\\' || * p == '"' )
859
866
break ;
860
- else if ((unsigned char ) * p < 32 )
867
+ else if ((unsigned char ) * p <= 31 )
861
868
{
862
869
/* Per RFC4627, these characters MUST be escaped. */
863
870
/*
Original file line number Diff line number Diff line change @@ -42,6 +42,19 @@ LINE 1: SELECT '"\v"'::json;
42
42
^
43
43
DETAIL: Escape sequence "\v" is invalid.
44
44
CONTEXT: JSON data, line 1: "\v...
45
+ -- Check fast path for longer strings (at least 16 bytes long)
46
+ SELECT ('"'||repeat('.', 12)||'abc"')::json; -- OK
47
+ json
48
+ -------------------
49
+ "............abc"
50
+ (1 row)
51
+
52
+ SELECT ('"'||repeat('.', 12)||'abc\n"')::json; -- OK, legal escapes
53
+ json
54
+ ---------------------
55
+ "............abc\n"
56
+ (1 row)
57
+
45
58
-- see json_encoding test for input with unicode escapes
46
59
-- Numbers.
47
60
SELECT '1'::json; -- OK
Original file line number Diff line number Diff line change @@ -7,6 +7,11 @@ SELECT '"abc
7
7
def"' ::json; -- ERROR, unescaped newline in string constant
8
8
SELECT ' "\n\"\\ "' ::json; -- OK, legal escapes
9
9
SELECT ' "\v "' ::json; -- ERROR, not a valid JSON escape
10
+
11
+ -- Check fast path for longer strings (at least 16 bytes long)
12
+ SELECT (' "' || repeat(' .' , 12 )|| ' abc"' )::json; -- OK
13
+ SELECT (' "' || repeat(' .' , 12 )|| ' abc\n "' )::json; -- OK, legal escapes
14
+
10
15
-- see json_encoding test for input with unicode escapes
11
16
12
17
-- Numbers.
You can’t perform that action at this time.
0 commit comments