1
+
2
+ # Copyright (c) 2021-2024, PostgreSQL Global Development Group
3
+
4
+ # Test success or failure of the incremental (table-driven) JSON parser
5
+ # for a variety of small inputs.
6
+
1
7
use strict;
2
8
use warnings;
3
9
6
12
7
13
use File::Temp qw( tempfile) ;
8
14
15
+ my $dir = PostgreSQL::Test::Utils::tempdir;
16
+
9
17
sub test
10
18
{
11
19
local $Test::Builder::Level = $Test::Builder::Level + 1;
@@ -14,27 +22,32 @@ sub test
14
22
my $exe = " test_json_parser_incremental" ;
15
23
my $chunk = length ($json );
16
24
25
+ # Test the input with chunk sizes from max(input_size, 64) down to 1
26
+
17
27
if ($chunk > 64)
18
28
{
19
29
$chunk = 64;
20
30
}
21
31
22
- my ($fh , $fname ) = tempfile(UNLINK => 1 );
32
+ my ($fh , $fname ) = tempfile(DIR => $dir );
23
33
print $fh " $json " ;
24
34
close ($fh );
25
35
26
- foreach my $size (reverse (1.. $chunk ))
36
+ foreach my $size (reverse (1 .. $chunk ))
27
37
{
28
- my ($stdout , $stderr ) = run_command( [ $exe , " -c" , $size , $fname ] );
38
+ my ($stdout , $stderr ) = run_command([ $exe , " -c" , $size , $fname ] );
29
39
30
40
if (defined ($params {error }))
31
41
{
32
- unlike($stdout , qr / SUCCESS/ , " $name , chunk size $size : test fails" );
33
- like($stderr , $params {error }, " $name , chunk size $size : correct error output" );
42
+ unlike($stdout , qr / SUCCESS/ ,
43
+ " $name , chunk size $size : test fails" );
44
+ like($stderr , $params {error },
45
+ " $name , chunk size $size : correct error output" );
34
46
}
35
47
else
36
48
{
37
- like($stdout , qr / SUCCESS/ , " $name , chunk size $size : test succeeds" );
49
+ like($stdout , qr / SUCCESS/ ,
50
+ " $name , chunk size $size : test succeeds" );
38
51
is($stderr , " " , " $name , chunk size $size : no error output" );
39
52
}
40
53
}
@@ -58,26 +71,60 @@ sub test
58
71
test(" interrupted escapes" , ' "\\\\\\ "\\\\\\\\\\ "\\\\ "' );
59
72
test(" whitespace" , ' "" ' );
60
73
61
- test(" unclosed empty object" , " {" , error => qr / input string ended unexpectedly/ );
74
+ test(" unclosed empty object" ,
75
+ " {" , error => qr / input string ended unexpectedly/ );
62
76
test(" bad key" , " {{" , error => qr / Expected string or "}", but found "\{ "/ );
63
77
test(" bad key" , " {{}" , error => qr / Expected string or "}", but found "\{ "/ );
64
- test(" numeric key" , " {1234: 2}" , error => qr / Expected string or "}", but found "1234"/ );
65
- test(" second numeric key" , ' {"a": "a", 1234: 2}' , error => qr / Expected string, but found "1234"/ );
66
- test(" unclosed object with pair" , ' {"key": "value"' , error => qr / input string ended unexpectedly/ );
67
- test(" missing key value" , ' {"key": }' , error => qr / Expected JSON value, but found "}"/ );
68
- test(" missing colon" , ' {"key" 12345}' , error => qr / Expected ":", but found "12345"/ );
69
- test(" missing comma" , ' {"key": 12345 12345}' , error => qr / Expected "," or "}", but found "12345"/ );
70
- test(" overnested array" , " [" x 6401 , error => qr / maximum permitted depth is 6400/ );
71
- test(" overclosed array" , " []]" , error => qr / Expected end of input, but found "]"/ );
72
- test(" unexpected token in array" , " [ }}} ]" , error => qr / Expected array element or "]", but found "}"/ );
78
+ test(" numeric key" , " {1234: 2}" ,
79
+ error => qr / Expected string or "}", but found "1234"/ );
80
+ test(
81
+ " second numeric key" ,
82
+ ' {"a": "a", 1234: 2}' ,
83
+ error => qr / Expected string, but found "1234"/ );
84
+ test(
85
+ " unclosed object with pair" ,
86
+ ' {"key": "value"' ,
87
+ error => qr / input string ended unexpectedly/ );
88
+ test(" missing key value" ,
89
+ ' {"key": }' , error => qr / Expected JSON value, but found "}"/ );
90
+ test(
91
+ " missing colon" ,
92
+ ' {"key" 12345}' ,
93
+ error => qr / Expected ":", but found "12345"/ );
94
+ test(
95
+ " missing comma" ,
96
+ ' {"key": 12345 12345}' ,
97
+ error => qr / Expected "," or "}", but found "12345"/ );
98
+ test(" overnested array" ,
99
+ " [" x 6401 , error => qr / maximum permitted depth is 6400/ );
100
+ test(" overclosed array" ,
101
+ " []]" , error => qr / Expected end of input, but found "]"/ );
102
+ test(" unexpected token in array" ,
103
+ " [ }}} ]" , error => qr / Expected array element or "]", but found "}"/ );
73
104
test(" junk punctuation" , " [ ||| ]" , error => qr / Token "|" is invalid/ );
74
- test(" missing comma in array" , " [123 123]" , error => qr / Expected "," or "]", but found "123"/ );
105
+ test(" missing comma in array" ,
106
+ " [123 123]" , error => qr / Expected "," or "]", but found "123"/ );
75
107
test(" misspelled boolean" , " tru" , error => qr / Token "tru" is invalid/ );
76
- test(" misspelled boolean in array" , " [tru]" , error => qr / Token "tru" is invalid/ );
77
- test(" smashed top-level scalar" , " 12zz" , error => qr / Token "12zz" is invalid/ );
78
- test(" smashed scalar in array" , " [12zz]" , error => qr / Token "12zz" is invalid/ );
79
- test(" unknown escape sequence" , ' "hello\vworld"' , error => qr / Escape sequence "\\ v" is invalid/ );
80
- test(" unescaped control" , " \" hello\t world\" " , error => qr / Character with value 0x09 must be escaped/ );
81
- test(" incorrect escape count" , ' "\\\\\\\\\\\\\\ "' , error => qr / Token ""\\\\\\\\\\\\\\ "" is invalid/ );
108
+ test(
109
+ " misspelled boolean in array" ,
110
+ " [tru]" ,
111
+ error => qr / Token "tru" is invalid/ );
112
+ test(" smashed top-level scalar" , " 12zz" ,
113
+ error => qr / Token "12zz" is invalid/ );
114
+ test(
115
+ " smashed scalar in array" ,
116
+ " [12zz]" ,
117
+ error => qr / Token "12zz" is invalid/ );
118
+ test(
119
+ " unknown escape sequence" ,
120
+ ' "hello\vworld"' ,
121
+ error => qr / Escape sequence "\\ v" is invalid/ );
122
+ test(" unescaped control" ,
123
+ " \" hello\t world\" " ,
124
+ error => qr / Character with value 0x09 must be escaped/ );
125
+ test(
126
+ " incorrect escape count" ,
127
+ ' "\\\\\\\\\\\\\\ "' ,
128
+ error => qr / Token ""\\\\\\\\\\\\\\ "" is invalid/ );
82
129
83
130
done_testing();
0 commit comments