Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 69036aa

Browse files
committed
Simplify jsonfuncs.c code by using strtoint() not strtol().
Explicitly testing for INT_MIN and INT_MAX isn't particularly good style; it's tedious and may draw useless compiler warnings on machines where int and long are the same width. We invented strtoint() precisely for this usage, so use that instead. While here, remove gratuitous variations in the way the tests for did-strtoint-succeed were spelled. Also, avoid attempting to negate INT_MIN; that would probably work given that the result is implicitly cast to uint32, but I think it's nominally undefined behavior. Per gripe from Ranier Vilela, though this isn't his proposed patch. Discussion: https://postgr.es/m/CAEudQAqge3QfzoBRhe59QrB_5g+NmQUj2QpzqZ9Nc7QepXGAEw@mail.gmail.com
1 parent d4c7465 commit 69036aa

File tree

1 file changed

+15
-20
lines changed

1 file changed

+15
-20
lines changed

src/backend/utils/adt/jsonfuncs.c

+15-20
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "access/htup_details.h"
2020
#include "catalog/pg_type.h"
2121
#include "common/jsonapi.h"
22+
#include "common/string.h"
2223
#include "fmgr.h"
2324
#include "funcapi.h"
2425
#include "lib/stringinfo.h"
@@ -1026,15 +1027,15 @@ get_path_all(FunctionCallInfo fcinfo, bool as_text)
10261027
*/
10271028
if (*tpath[i] != '\0')
10281029
{
1029-
long ind;
1030+
int ind;
10301031
char *endptr;
10311032

10321033
errno = 0;
1033-
ind = strtol(tpath[i], &endptr, 10);
1034-
if (*endptr == '\0' && errno == 0 && ind <= INT_MAX && ind >= INT_MIN)
1035-
ipath[i] = (int) ind;
1036-
else
1034+
ind = strtoint(tpath[i], &endptr, 10);
1035+
if (endptr == tpath[i] || *endptr != '\0' || errno != 0)
10371036
ipath[i] = INT_MIN;
1037+
else
1038+
ipath[i] = ind;
10381039
}
10391040
else
10401041
ipath[i] = INT_MIN;
@@ -1533,15 +1534,14 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
15331534
}
15341535
else if (have_array)
15351536
{
1536-
long lindex;
1537+
int lindex;
15371538
uint32 index;
15381539
char *indextext = TextDatumGetCString(path[i]);
15391540
char *endptr;
15401541

15411542
errno = 0;
1542-
lindex = strtol(indextext, &endptr, 10);
1543-
if (endptr == indextext || *endptr != '\0' || errno != 0 ||
1544-
lindex > INT_MAX || lindex < INT_MIN)
1543+
lindex = strtoint(indextext, &endptr, 10);
1544+
if (endptr == indextext || *endptr != '\0' || errno != 0)
15451545
{
15461546
*isnull = true;
15471547
return PointerGetDatum(NULL);
@@ -1562,7 +1562,7 @@ jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text)
15621562

15631563
nelements = JsonContainerSize(container);
15641564

1565-
if (-lindex > nelements)
1565+
if (lindex == INT_MIN || -lindex > nelements)
15661566
{
15671567
*isnull = true;
15681568
return PointerGetDatum(NULL);
@@ -1675,7 +1675,6 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
16751675
* end, the access index must be normalized by level.
16761676
*/
16771677
enum jbvType *tpath = palloc0((path_len - level) * sizeof(enum jbvType));
1678-
long lindex;
16791678
JsonbValue newkey;
16801679

16811680
/*
@@ -1687,6 +1686,7 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
16871686
{
16881687
char *c,
16891688
*badp;
1689+
int lindex;
16901690

16911691
if (path_nulls[i])
16921692
break;
@@ -1697,9 +1697,8 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
16971697
*/
16981698
c = TextDatumGetCString(path_elems[i]);
16991699
errno = 0;
1700-
lindex = strtol(c, &badp, 10);
1701-
if (errno != 0 || badp == c || *badp != '\0' || lindex > INT_MAX ||
1702-
lindex < INT_MIN)
1700+
lindex = strtoint(c, &badp, 10);
1701+
if (badp == c || *badp != '\0' || errno != 0)
17031702
{
17041703
/* text, an object is expected */
17051704
newkey.type = jbvString;
@@ -1720,7 +1719,6 @@ push_path(JsonbParseState **st, int level, Datum *path_elems,
17201719

17211720
tpath[i - level] = jbvArray;
17221721
}
1723-
17241722
}
17251723

17261724
/* Insert an actual value for either an object or array */
@@ -5138,18 +5136,15 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
51385136
if (level < path_len && !path_nulls[level])
51395137
{
51405138
char *c = TextDatumGetCString(path_elems[level]);
5141-
long lindex;
51425139
char *badp;
51435140

51445141
errno = 0;
5145-
lindex = strtol(c, &badp, 10);
5146-
if (errno != 0 || badp == c || *badp != '\0' || lindex > INT_MAX ||
5147-
lindex < INT_MIN)
5142+
idx = strtoint(c, &badp, 10);
5143+
if (badp == c || *badp != '\0' || errno != 0)
51485144
ereport(ERROR,
51495145
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
51505146
errmsg("path element at position %d is not an integer: \"%s\"",
51515147
level + 1, c)));
5152-
idx = lindex;
51535148
}
51545149
else
51555150
idx = nelems;

0 commit comments

Comments
 (0)