Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit72d4fd0

Browse files
committed
Fix behavior when converting a float infinity to numeric.
float8_numeric() and float4_numeric() failed to consider the possibilitythat the input is an IEEE infinity. The results depended on theplatform-specific behavior of sprintf(): on most platforms you'd getsomething likeERROR: invalid input syntax for type numeric: "inf"but at least on Windows it's possible for the conversion to succeed anddeliver a finite value (typically 1), due to a nonstandard output formatfrom sprintf and lack of syntax error checking in these functions.Since our numeric type lacks the concept of infinity, a suitable conversionis impossible; the best thing to do is throw an explicit error beforeletting sprintf do its thing.While at it, let's use snprintf not sprintf. Overrunning the buffershould be impossible if sprintf does what it's supposed to, but thisis cheap insurance against a stack smash if it doesn't.Problem reported by Taiki Kondo. Patch by me based on fix suggestionfrom KaiGai Kohei. Back-patch to all supported branches.Discussion:https://postgr.es/m/12A9442FBAE80D4E8953883E0B84E088C8C7A2@BPXM01GP.gisp.nec.co.jp
1 parent6525a3a commit72d4fd0

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

‎src/backend/utils/adt/numeric.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,7 +2438,12 @@ float8_numeric(PG_FUNCTION_ARGS)
24382438
if (isnan(val))
24392439
PG_RETURN_NUMERIC(make_result(&const_nan));
24402440

2441-
sprintf(buf,"%.*g",DBL_DIG,val);
2441+
if (isinf(val))
2442+
ereport(ERROR,
2443+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2444+
errmsg("cannot convert infinity to numeric")));
2445+
2446+
snprintf(buf,sizeof(buf),"%.*g",DBL_DIG,val);
24422447

24432448
init_var(&result);
24442449

@@ -2500,7 +2505,12 @@ float4_numeric(PG_FUNCTION_ARGS)
25002505
if (isnan(val))
25012506
PG_RETURN_NUMERIC(make_result(&const_nan));
25022507

2503-
sprintf(buf,"%.*g",FLT_DIG,val);
2508+
if (isinf(val))
2509+
ereport(ERROR,
2510+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2511+
errmsg("cannot convert infinity to numeric")));
2512+
2513+
snprintf(buf,sizeof(buf),"%.*g",FLT_DIG,val);
25042514

25052515
init_var(&result);
25062516

‎src/test/regress/expected/numeric.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,27 @@ SELECT * FROM fract_only;
708708
(6 rows)
709709

710710
DROP TABLE fract_only;
711+
-- Check inf/nan conversion behavior
712+
SELECT 'NaN'::float8::numeric;
713+
numeric
714+
---------
715+
NaN
716+
(1 row)
717+
718+
SELECT 'Infinity'::float8::numeric;
719+
ERROR: cannot convert infinity to numeric
720+
SELECT '-Infinity'::float8::numeric;
721+
ERROR: cannot convert infinity to numeric
722+
SELECT 'NaN'::float4::numeric;
723+
numeric
724+
---------
725+
NaN
726+
(1 row)
727+
728+
SELECT 'Infinity'::float4::numeric;
729+
ERROR: cannot convert infinity to numeric
730+
SELECT '-Infinity'::float4::numeric;
731+
ERROR: cannot convert infinity to numeric
711732
-- Simple check that ceil(), floor(), and round() work correctly
712733
CREATE TABLE ceil_floor_round (a numeric);
713734
INSERT INTO ceil_floor_round VALUES ('-5.5');

‎src/test/regress/sql/numeric.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,14 @@ INSERT INTO fract_only VALUES (8, '0.00017');
655655
SELECT*FROM fract_only;
656656
DROPTABLE fract_only;
657657

658+
-- Check inf/nan conversion behavior
659+
SELECT'NaN'::float8::numeric;
660+
SELECT'Infinity'::float8::numeric;
661+
SELECT'-Infinity'::float8::numeric;
662+
SELECT'NaN'::float4::numeric;
663+
SELECT'Infinity'::float4::numeric;
664+
SELECT'-Infinity'::float4::numeric;
665+
658666
-- Simple check that ceil(), floor(), and round() work correctly
659667
CREATETABLEceil_floor_round (anumeric);
660668
INSERT INTO ceil_floor_roundVALUES ('-5.5');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp