mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
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>
This commit is contained in:
@ -39,6 +39,26 @@ SELECT testSVToJsonb();
|
|||||||
1
|
1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION testInf() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'Inf';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
SELECT testInf();
|
||||||
|
ERROR: cannot convert infinity to jsonb
|
||||||
|
CONTEXT: PL/Perl function "testinf"
|
||||||
|
CREATE FUNCTION testNaN() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'NaN';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
SELECT testNaN();
|
||||||
|
ERROR: cannot convert NaN to jsonb
|
||||||
|
CONTEXT: PL/Perl function "testnan"
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperl
|
LANGUAGE plperl
|
||||||
@ -71,7 +91,7 @@ SELECT roundtrip('1');
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT roundtrip('1E+131071');
|
SELECT roundtrip('1E+131071');
|
||||||
ERROR: cannot convert infinite value to jsonb
|
ERROR: cannot convert infinity to jsonb
|
||||||
CONTEXT: PL/Perl function "roundtrip"
|
CONTEXT: PL/Perl function "roundtrip"
|
||||||
SELECT roundtrip('-1');
|
SELECT roundtrip('-1');
|
||||||
roundtrip
|
roundtrip
|
||||||
@ -207,4 +227,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
|
|||||||
|
|
||||||
\set VERBOSITY terse \\ -- suppress cascade details
|
\set VERBOSITY terse \\ -- suppress cascade details
|
||||||
DROP EXTENSION plperl CASCADE;
|
DROP EXTENSION plperl CASCADE;
|
||||||
NOTICE: drop cascades to 6 other objects
|
NOTICE: drop cascades to 8 other objects
|
||||||
|
@ -39,6 +39,26 @@ SELECT testSVToJsonb();
|
|||||||
1
|
1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION testInf() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'Inf';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
SELECT testInf();
|
||||||
|
ERROR: cannot convert infinity to jsonb
|
||||||
|
CONTEXT: PL/Perl function "testinf"
|
||||||
|
CREATE FUNCTION testNaN() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'NaN';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
SELECT testNaN();
|
||||||
|
ERROR: cannot convert NaN to jsonb
|
||||||
|
CONTEXT: PL/Perl function "testnan"
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperlu
|
LANGUAGE plperlu
|
||||||
@ -71,7 +91,7 @@ SELECT roundtrip('1');
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT roundtrip('1E+131071');
|
SELECT roundtrip('1E+131071');
|
||||||
ERROR: cannot convert infinite value to jsonb
|
ERROR: cannot convert infinity to jsonb
|
||||||
CONTEXT: PL/Perl function "roundtrip"
|
CONTEXT: PL/Perl function "roundtrip"
|
||||||
SELECT roundtrip('-1');
|
SELECT roundtrip('-1');
|
||||||
roundtrip
|
roundtrip
|
||||||
@ -207,4 +227,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}');
|
|||||||
|
|
||||||
\set VERBOSITY terse \\ -- suppress cascade details
|
\set VERBOSITY terse \\ -- suppress cascade details
|
||||||
DROP EXTENSION plperlu CASCADE;
|
DROP EXTENSION plperlu CASCADE;
|
||||||
NOTICE: drop cascades to 6 other objects
|
NOTICE: drop cascades to 8 other objects
|
||||||
|
@ -211,10 +211,22 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem)
|
|||||||
{
|
{
|
||||||
double nval = SvNV(in);
|
double nval = SvNV(in);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* jsonb doesn't allow infinity or NaN (per JSON
|
||||||
|
* specification), but the numeric type that is used for the
|
||||||
|
* storage accepts NaN, so we have to prevent it here
|
||||||
|
* explicitly. We don't really have to check for isinf()
|
||||||
|
* here, as numeric doesn't allow it and it would be caught
|
||||||
|
* later, but it makes for a nicer error message.
|
||||||
|
*/
|
||||||
if (isinf(nval))
|
if (isinf(nval))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
(errmsg("cannot convert infinite value to jsonb"))));
|
(errmsg("cannot convert infinity to jsonb"))));
|
||||||
|
if (isnan(nval))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||||
|
(errmsg("cannot convert NaN to jsonb"))));
|
||||||
|
|
||||||
out.type = jbvNumeric;
|
out.type = jbvNumeric;
|
||||||
out.val.numeric =
|
out.val.numeric =
|
||||||
|
@ -34,6 +34,28 @@ $$;
|
|||||||
SELECT testSVToJsonb();
|
SELECT testSVToJsonb();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testInf() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'Inf';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT testInf();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testNaN() RETURNS jsonb
|
||||||
|
LANGUAGE plperl
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'NaN';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT testNaN();
|
||||||
|
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperl
|
LANGUAGE plperl
|
||||||
|
@ -34,6 +34,28 @@ $$;
|
|||||||
SELECT testSVToJsonb();
|
SELECT testSVToJsonb();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testInf() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'Inf';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT testInf();
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION testNaN() RETURNS jsonb
|
||||||
|
LANGUAGE plperlu
|
||||||
|
TRANSFORM FOR TYPE jsonb
|
||||||
|
AS $$
|
||||||
|
$val = 0 + 'NaN';
|
||||||
|
return $val;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT testNaN();
|
||||||
|
|
||||||
|
|
||||||
-- this revealed a bug in the original implementation
|
-- this revealed a bug in the original implementation
|
||||||
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb
|
||||||
LANGUAGE plperlu
|
LANGUAGE plperlu
|
||||||
|
Reference in New Issue
Block a user