Skip to content

Commit e348e7a

Browse files
committed
Prevent infinity and NaN in jsonb/plperl transform
jsonb uses numeric internally, and numeric can store NaN, but that is not allowed by jsonb on input, so we shouldn't store it. Also prevent infinity to get a consistent error message. (numeric input would reject infinity anyway.) Reported-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
1 parent f7df804 commit e348e7a

File tree

5 files changed

+102
-6
lines changed

5 files changed

+102
-6
lines changed

contrib/jsonb_plperl/expected/jsonb_plperl.out

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ SELECT testSVToJsonb();
3939
1
4040
(1 row)
4141

42+
CREATE FUNCTION testInf() RETURNS jsonb
43+
LANGUAGE plperl
44+
TRANSFORM FOR TYPE jsonb
45+
AS $$
46+
$val = 0 + 'Inf';
47+
return $val;
48+
$$;
49+
SELECT testInf();
50+
ERROR: cannot convert infinity to jsonb
51+
CONTEXT: PL/Perl function "testinf"
52+
CREATE FUNCTION testNaN() RETURNS jsonb
53+
LANGUAGE plperl
54+
TRANSFORM FOR TYPE jsonb
55+
AS $$
56+
$val = 0 + 'NaN';
57+
return $val;
58+
$$;
59+
SELECT testNaN();
60+
ERROR: cannot convert NaN to jsonb
61+
CONTEXT: PL/Perl function "testnan"
4262
-- this revealed a bug in the original implementation
4363
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
4464
LANGUAGE plperl
@@ -71,7 +91,7 @@ SELECT roundtrip('1');
7191
(1 row)
7292

7393
SELECT roundtrip('1E+131071');
74-
ERROR: cannot convert infinite value to jsonb
94+
ERROR: cannot convert infinity to jsonb
7595
CONTEXT: PL/Perl function "roundtrip"
7696
SELECT roundtrip('-1');
7797
roundtrip
@@ -207,4 +227,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
207227

208228
\set VERBOSITY terse \\ -- suppress cascade details
209229
DROP EXTENSION plperl CASCADE;
210-
NOTICE: drop cascades to 6 other objects
230+
NOTICE: drop cascades to 8 other objects

contrib/jsonb_plperl/expected/jsonb_plperlu.out

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ SELECT testSVToJsonb();
3939
1
4040
(1 row)
4141

42+
CREATE FUNCTION testInf() RETURNS jsonb
43+
LANGUAGE plperlu
44+
TRANSFORM FOR TYPE jsonb
45+
AS $$
46+
$val = 0 + 'Inf';
47+
return $val;
48+
$$;
49+
SELECT testInf();
50+
ERROR: cannot convert infinity to jsonb
51+
CONTEXT: PL/Perl function "testinf"
52+
CREATE FUNCTION testNaN() RETURNS jsonb
53+
LANGUAGE plperlu
54+
TRANSFORM FOR TYPE jsonb
55+
AS $$
56+
$val = 0 + 'NaN';
57+
return $val;
58+
$$;
59+
SELECT testNaN();
60+
ERROR: cannot convert NaN to jsonb
61+
CONTEXT: PL/Perl function "testnan"
4262
-- this revealed a bug in the original implementation
4363
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
4464
LANGUAGE plperlu
@@ -71,7 +91,7 @@ SELECT roundtrip('1');
7191
(1 row)
7292

7393
SELECT roundtrip('1E+131071');
74-
ERROR: cannot convert infinite value to jsonb
94+
ERROR: cannot convert infinity to jsonb
7595
CONTEXT: PL/Perl function "roundtrip"
7696
SELECT roundtrip('-1');
7797
roundtrip
@@ -207,4 +227,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
207227

208228
\set VERBOSITY terse \\ -- suppress cascade details
209229
DROP EXTENSION plperlu CASCADE;
210-
NOTICE: drop cascades to 6 other objects
230+
NOTICE: drop cascades to 8 other objects

contrib/jsonb_plperl/jsonb_plperl.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,22 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
211211
{
212212
double nval = SvNV(in);
213213

214+
/*
215+
* jsonb doesn't allow infinity or NaN (per JSON
216+
* specification), but the numeric type that is used for the
217+
* storage accepts NaN, so we have to prevent it here
218+
* explicitly. We don't really have to check for isinf()
219+
* here, as numeric doesn't allow it and it would be caught
220+
* later, but it makes for a nicer error message.
221+
*/
214222
if (isinf(nval))
215223
ereport(ERROR,
216-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
217-
(errmsg("cannot convert infinite value to jsonb"))));
224+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
225+
(errmsg("cannot convert infinity to jsonb"))));
226+
if (isnan(nval))
227+
ereport(ERROR,
228+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
229+
(errmsg("cannot convert NaN to jsonb"))));
218230

219231
out.type = jbvNumeric;
220232
out.val.numeric =

contrib/jsonb_plperl/sql/jsonb_plperl.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ $$;
3434
SELECT testSVToJsonb();
3535

3636

37+
CREATE FUNCTION testInf() RETURNS jsonb
38+
LANGUAGE plperl
39+
TRANSFORM FOR TYPE jsonb
40+
AS $$
41+
$val = 0 + 'Inf';
42+
return $val;
43+
$$;
44+
45+
SELECT testInf();
46+
47+
48+
CREATE FUNCTION testNaN() RETURNS jsonb
49+
LANGUAGE plperl
50+
TRANSFORM FOR TYPE jsonb
51+
AS $$
52+
$val = 0 + 'NaN';
53+
return $val;
54+
$$;
55+
56+
SELECT testNaN();
57+
58+
3759
-- this revealed a bug in the original implementation
3860
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
3961
LANGUAGE plperl

contrib/jsonb_plperl/sql/jsonb_plperlu.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ $$;
3434
SELECT testSVToJsonb();
3535

3636

37+
CREATE FUNCTION testInf() RETURNS jsonb
38+
LANGUAGE plperlu
39+
TRANSFORM FOR TYPE jsonb
40+
AS $$
41+
$val = 0 + 'Inf';
42+
return $val;
43+
$$;
44+
45+
SELECT testInf();
46+
47+
48+
CREATE FUNCTION testNaN() RETURNS jsonb
49+
LANGUAGE plperlu
50+
TRANSFORM FOR TYPE jsonb
51+
AS $$
52+
$val = 0 + 'NaN';
53+
return $val;
54+
$$;
55+
56+
SELECT testNaN();
57+
58+
3759
-- this revealed a bug in the original implementation
3860
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
3961
LANGUAGE plperlu

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy