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

Commit221e92f

Browse files
committed
Make sure float4in/float8in accept all standard spellings of "infinity".
The C99 and POSIX standards require strtod() to accept all these spellings(case-insensitively): "inf", "+inf", "-inf", "infinity", "+infinity","-infinity". However, pre-C99 systems might accept only some or none ofthese, and apparently Windows still doesn't accept "inf". To avoidsurprising cross-platform behavioral differences, manually check for eachof these spellings if strtod() fails. We were previously handling just"infinity" and "-infinity" that way, but since C99 is most of the worldnow, it seems likely that applications are expecting all these spellingsto work.Per bug #8355 from Basil Peace. It turns out this fix won't actuallyresolve his problem, because Python isn't being this careful; but thatdoesn't mean we shouldn't be.
1 parent706f9dd commit221e92f

File tree

1 file changed

+75
-23
lines changed

1 file changed

+75
-23
lines changed

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

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,7 @@ is_infinite(double val)
176176

177177

178178
/*
179-
*float4in- converts "num" to float
180-
* restricted syntax:
181-
* {<sp>} [+|-] {digit} [.{digit}] [<exp>]
182-
* where <sp> is a space, digit is 0-9,
183-
* <exp> is "e" or "E" followed by an integer.
179+
*float4in- converts "num" to float4
184180
*/
185181
Datum
186182
float4in(PG_FUNCTION_ARGS)
@@ -197,6 +193,10 @@ float4in(PG_FUNCTION_ARGS)
197193
*/
198194
orig_num=num;
199195

196+
/* skip leading whitespace */
197+
while (*num!='\0'&&isspace((unsignedchar)*num))
198+
num++;
199+
200200
/*
201201
* Check for an empty-string input to begin with, to avoid the vagaries of
202202
* strtod() on different platforms.
@@ -207,10 +207,6 @@ float4in(PG_FUNCTION_ARGS)
207207
errmsg("invalid input syntax for type real: \"%s\"",
208208
orig_num)));
209209

210-
/* skip leading whitespace */
211-
while (*num!='\0'&&isspace((unsignedchar)*num))
212-
num++;
213-
214210
errno=0;
215211
val=strtod(num,&endptr);
216212

@@ -220,9 +216,14 @@ float4in(PG_FUNCTION_ARGS)
220216
intsave_errno=errno;
221217

222218
/*
223-
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
224-
* platforms support that yet (and some accept them but set ERANGE
225-
* anyway...) Therefore, we check for these inputs ourselves.
219+
* C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
220+
* but not all platforms support all of these (and some accept them
221+
* but set ERANGE anyway...) Therefore, we check for these inputs
222+
* ourselves if strtod() fails.
223+
*
224+
* Note: C99 also requires hexadecimal input as well as some extended
225+
* forms of NaN, but we consider these forms unportable and don't try
226+
* to support them. You can use 'em if your strtod() takes 'em.
226227
*/
227228
if (pg_strncasecmp(num,"NaN",3)==0)
228229
{
@@ -234,11 +235,31 @@ float4in(PG_FUNCTION_ARGS)
234235
val=get_float4_infinity();
235236
endptr=num+8;
236237
}
238+
elseif (pg_strncasecmp(num,"+Infinity",9)==0)
239+
{
240+
val=get_float4_infinity();
241+
endptr=num+9;
242+
}
237243
elseif (pg_strncasecmp(num,"-Infinity",9)==0)
238244
{
239245
val=-get_float4_infinity();
240246
endptr=num+9;
241247
}
248+
elseif (pg_strncasecmp(num,"inf",3)==0)
249+
{
250+
val=get_float4_infinity();
251+
endptr=num+3;
252+
}
253+
elseif (pg_strncasecmp(num,"+inf",4)==0)
254+
{
255+
val=get_float4_infinity();
256+
endptr=num+4;
257+
}
258+
elseif (pg_strncasecmp(num,"-inf",4)==0)
259+
{
260+
val=-get_float4_infinity();
261+
endptr=num+4;
262+
}
242263
elseif (save_errno==ERANGE)
243264
{
244265
/*
@@ -287,6 +308,11 @@ float4in(PG_FUNCTION_ARGS)
287308
val=get_float4_infinity();
288309
endptr=num+8;
289310
}
311+
elseif (pg_strncasecmp(num,"+Infinity",9)==0)
312+
{
313+
val=get_float4_infinity();
314+
endptr=num+9;
315+
}
290316
elseif (pg_strncasecmp(num,"-Infinity",9)==0)
291317
{
292318
val=-get_float4_infinity();
@@ -382,10 +408,6 @@ float4send(PG_FUNCTION_ARGS)
382408

383409
/*
384410
*float8in- converts "num" to float8
385-
* restricted syntax:
386-
* {<sp>} [+|-] {digit} [.{digit}] [<exp>]
387-
* where <sp> is a space, digit is 0-9,
388-
* <exp> is "e" or "E" followed by an integer.
389411
*/
390412
Datum
391413
float8in(PG_FUNCTION_ARGS)
@@ -402,6 +424,10 @@ float8in(PG_FUNCTION_ARGS)
402424
*/
403425
orig_num=num;
404426

427+
/* skip leading whitespace */
428+
while (*num!='\0'&&isspace((unsignedchar)*num))
429+
num++;
430+
405431
/*
406432
* Check for an empty-string input to begin with, to avoid the vagaries of
407433
* strtod() on different platforms.
@@ -412,10 +438,6 @@ float8in(PG_FUNCTION_ARGS)
412438
errmsg("invalid input syntax for type double precision: \"%s\"",
413439
orig_num)));
414440

415-
/* skip leading whitespace */
416-
while (*num!='\0'&&isspace((unsignedchar)*num))
417-
num++;
418-
419441
errno=0;
420442
val=strtod(num,&endptr);
421443

@@ -425,9 +447,14 @@ float8in(PG_FUNCTION_ARGS)
425447
intsave_errno=errno;
426448

427449
/*
428-
* C99 requires that strtod() accept NaN and [-]Infinity, but not all
429-
* platforms support that yet (and some accept them but set ERANGE
430-
* anyway...) Therefore, we check for these inputs ourselves.
450+
* C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
451+
* but not all platforms support all of these (and some accept them
452+
* but set ERANGE anyway...) Therefore, we check for these inputs
453+
* ourselves if strtod() fails.
454+
*
455+
* Note: C99 also requires hexadecimal input as well as some extended
456+
* forms of NaN, but we consider these forms unportable and don't try
457+
* to support them. You can use 'em if your strtod() takes 'em.
431458
*/
432459
if (pg_strncasecmp(num,"NaN",3)==0)
433460
{
@@ -439,11 +466,31 @@ float8in(PG_FUNCTION_ARGS)
439466
val=get_float8_infinity();
440467
endptr=num+8;
441468
}
469+
elseif (pg_strncasecmp(num,"+Infinity",9)==0)
470+
{
471+
val=get_float8_infinity();
472+
endptr=num+9;
473+
}
442474
elseif (pg_strncasecmp(num,"-Infinity",9)==0)
443475
{
444476
val=-get_float8_infinity();
445477
endptr=num+9;
446478
}
479+
elseif (pg_strncasecmp(num,"inf",3)==0)
480+
{
481+
val=get_float8_infinity();
482+
endptr=num+3;
483+
}
484+
elseif (pg_strncasecmp(num,"+inf",4)==0)
485+
{
486+
val=get_float8_infinity();
487+
endptr=num+4;
488+
}
489+
elseif (pg_strncasecmp(num,"-inf",4)==0)
490+
{
491+
val=-get_float8_infinity();
492+
endptr=num+4;
493+
}
447494
elseif (save_errno==ERANGE)
448495
{
449496
/*
@@ -492,6 +539,11 @@ float8in(PG_FUNCTION_ARGS)
492539
val=get_float8_infinity();
493540
endptr=num+8;
494541
}
542+
elseif (pg_strncasecmp(num,"+Infinity",9)==0)
543+
{
544+
val=get_float8_infinity();
545+
endptr=num+9;
546+
}
495547
elseif (pg_strncasecmp(num,"-Infinity",9)==0)
496548
{
497549
val=-get_float8_infinity();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp