Skip to content

Commit a4445cf

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 6a698b4 + 2c65856 commit a4445cf

File tree

118 files changed

+5197
-676
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+5197
-676
lines changed

configure

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10780,10 +10780,6 @@ rm -rf conftest*
1078010780

1078110781
fi
1078210782

10783-
# Autoconf 2.69's AC_SYS_LARGEFILE believes it's a good idea to #define
10784-
# _DARWIN_USE_64_BIT_INODE, but it isn't: on OS X 10.5 that activates a
10785-
# bug that causes readdir() to sometimes return EINVAL. On later OS X
10786-
# versions where the feature actually works, it's on by default anyway.
1078710783

1078810784
fi
1078910785

configure.in

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,10 +1156,10 @@ esac
11561156
# defines can affect what is generated for that.
11571157
if test "$PORTNAME" != "win32"; then
11581158
AC_SYS_LARGEFILE
1159-
# Autoconf 2.69's AC_SYS_LARGEFILE believes it's a good idea to #define
1160-
# _DARWIN_USE_64_BIT_INODE, but it isn't: on OS X 10.5 that activates a
1161-
# bug that causes readdir() to sometimes return EINVAL. On later OS X
1162-
# versions where the feature actually works, it's on by default anyway.
1159+
dnl Autoconf 2.69's AC_SYS_LARGEFILE believes it's a good idea to #define
1160+
dnl _DARWIN_USE_64_BIT_INODE, but it isn't: on OS X 10.5 that activates a
1161+
dnl bug that causes readdir() to sometimes return EINVAL. On later OS X
1162+
dnl versions where the feature actually works, it's on by default anyway.
11631163
AH_VERBATIM([_DARWIN_USE_64_BIT_INODE],[])
11641164
fi
11651165

contrib/chkpass/chkpass.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,13 @@ chkpass_in(PG_FUNCTION_ARGS)
9494
mysalt[2] = 0; /* technically the terminator is not necessary
9595
* but I like to play safe */
9696

97-
if ((crypt_output = crypt(str, mysalt)) == NULL)
97+
crypt_output = crypt(str, mysalt);
98+
if (crypt_output == NULL)
9899
ereport(ERROR,
99100
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
100101
errmsg("crypt() failed")));
101-
strcpy(result->password, crypt_output);
102+
103+
strlcpy(result->password, crypt_output, sizeof(result->password));
102104

103105
PG_RETURN_POINTER(result);
104106
}
@@ -148,9 +150,16 @@ chkpass_eq(PG_FUNCTION_ARGS)
148150
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
149151
text *a2 = PG_GETARG_TEXT_PP(1);
150152
char str[9];
153+
char *crypt_output;
151154

152155
text_to_cstring_buffer(a2, str, sizeof(str));
153-
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
156+
crypt_output = crypt(str, a1->password);
157+
if (crypt_output == NULL)
158+
ereport(ERROR,
159+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
160+
errmsg("crypt() failed")));
161+
162+
PG_RETURN_BOOL(strcmp(a1->password, crypt_output) == 0);
154163
}
155164

156165
PG_FUNCTION_INFO_V1(chkpass_ne);
@@ -160,7 +169,14 @@ chkpass_ne(PG_FUNCTION_ARGS)
160169
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
161170
text *a2 = PG_GETARG_TEXT_PP(1);
162171
char str[9];
172+
char *crypt_output;
163173

164174
text_to_cstring_buffer(a2, str, sizeof(str));
165-
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);
175+
crypt_output = crypt(str, a1->password);
176+
if (crypt_output == NULL)
177+
ereport(ERROR,
178+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
179+
errmsg("crypt() failed")));
180+
181+
PG_RETURN_BOOL(strcmp(a1->password, crypt_output) != 0);
166182
}

contrib/hstore/hstore.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,25 @@ typedef struct
4949
} HStore;
5050

5151
/*
52-
* it's not possible to get more than 2^28 items into an hstore,
53-
* so we reserve the top few bits of the size field. See hstore_compat.c
54-
* for one reason why. Some bits are left for future use here.
52+
* It's not possible to get more than 2^28 items into an hstore, so we reserve
53+
* the top few bits of the size field. See hstore_compat.c for one reason
54+
* why. Some bits are left for future use here. MaxAllocSize makes the
55+
* practical count limit slightly more than 2^28 / 3, or INT_MAX / 24, the
56+
* limit for an hstore full of 4-byte keys and null values. Therefore, we
57+
* don't explicitly check the format-imposed limit.
5558
*/
5659
#define HS_FLAG_NEWVERSION 0x80000000
5760

5861
#define HS_COUNT(hsp_) ((hsp_)->size_ & 0x0FFFFFFF)
5962
#define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
6063

6164

65+
/*
66+
* "x" comes from an existing HS_COUNT() (as discussed, <= INT_MAX/24) or a
67+
* Pairs array length (due to MaxAllocSize, <= INT_MAX/40). "lenstr" is no
68+
* more than INT_MAX, that extreme case arising in hstore_from_arrays().
69+
* Therefore, this calculation is limited to about INT_MAX / 5 + INT_MAX.
70+
*/
6271
#define HSHRDSIZE (sizeof(HStore))
6372
#define CALCDATASIZE(x, lenstr) ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
6473

contrib/hstore/hstore_io.c

Lines changed: 62 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "utils/builtins.h"
1414
#include "utils/json.h"
1515
#include "utils/lsyscache.h"
16+
#include "utils/memutils.h"
1617
#include "utils/typcache.h"
1718

1819
#include "hstore.h"
@@ -439,6 +440,11 @@ hstore_recv(PG_FUNCTION_ARGS)
439440
PG_RETURN_POINTER(out);
440441
}
441442

443+
if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
444+
ereport(ERROR,
445+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
446+
errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
447+
pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
442448
pairs = palloc(pcount * sizeof(Pairs));
443449

444450
for (i = 0; i < pcount; ++i)
@@ -554,6 +560,13 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
554560
TEXTOID, -1, false, 'i',
555561
&key_datums, &key_nulls, &key_count);
556562

563+
/* see discussion in hstoreArrayToPairs() */
564+
if (key_count > MaxAllocSize / sizeof(Pairs))
565+
ereport(ERROR,
566+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
567+
errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
568+
key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
569+
557570
/* value_array might be NULL */
558571

559572
if (PG_ARGISNULL(1))
@@ -676,6 +689,13 @@ hstore_from_array(PG_FUNCTION_ARGS)
676689

677690
count = in_count / 2;
678691

692+
/* see discussion in hstoreArrayToPairs() */
693+
if (count > MaxAllocSize / sizeof(Pairs))
694+
ereport(ERROR,
695+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
696+
errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
697+
count, (int) (MaxAllocSize / sizeof(Pairs)))));
698+
679699
pairs = palloc(count * sizeof(Pairs));
680700

681701
for (i = 0; i < count; ++i)
@@ -807,6 +827,7 @@ hstore_from_record(PG_FUNCTION_ARGS)
807827
my_extra->ncolumns = ncolumns;
808828
}
809829

830+
Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
810831
pairs = palloc(ncolumns * sizeof(Pairs));
811832

812833
if (rec)
@@ -1224,77 +1245,49 @@ Datum
12241245
hstore_to_json_loose(PG_FUNCTION_ARGS)
12251246
{
12261247
HStore *in = PG_GETARG_HS(0);
1227-
int buflen,
1228-
i;
1248+
int i;
12291249
int count = HS_COUNT(in);
1230-
char *out,
1231-
*ptr;
12321250
char *base = STRPTR(in);
12331251
HEntry *entries = ARRPTR(in);
12341252
bool is_number;
1235-
StringInfo src,
1253+
StringInfoData tmp,
12361254
dst;
12371255

12381256
if (count == 0)
12391257
PG_RETURN_TEXT_P(cstring_to_text_with_len("{}",2));
12401258

1241-
buflen = 3;
1242-
1243-
/*
1244-
* Formula adjusted slightly from the logic in hstore_out. We have to take
1245-
* account of out treatment of booleans to be a bit more pessimistic about
1246-
* the length of values.
1247-
*/
1248-
1249-
for (i = 0; i < count; i++)
1250-
{
1251-
/* include "" and colon-space and comma-space */
1252-
buflen += 6 + 2 * HS_KEYLEN(entries, i);
1253-
/* include "" only if nonnull */
1254-
buflen += 3 + (HS_VALISNULL(entries, i)
1255-
? 1
1256-
: 2 * HS_VALLEN(entries, i));
1257-
}
1259+
initStringInfo(&tmp);
1260+
initStringInfo(&dst);
12581261

1259-
out = ptr = palloc(buflen);
1260-
1261-
src = makeStringInfo();
1262-
dst = makeStringInfo();
1263-
1264-
*ptr++ = '{';
1262+
appendStringInfoChar(&dst, '{');
12651263

12661264
for (i = 0; i < count; i++)
12671265
{
1268-
resetStringInfo(src);
1269-
resetStringInfo(dst);
1270-
appendBinaryStringInfo(src, HS_KEY(entries, base, i), HS_KEYLEN(entries, i));
1271-
escape_json(dst, src->data);
1272-
strncpy(ptr, dst->data, dst->len);
1273-
ptr += dst->len;
1274-
*ptr++ = ':';
1275-
*ptr++ = ' ';
1276-
resetStringInfo(dst);
1266+
resetStringInfo(&tmp);
1267+
appendBinaryStringInfo(&tmp, HS_KEY(entries, base, i), HS_KEYLEN(entries, i));
1268+
escape_json(&dst, tmp.data);
1269+
appendStringInfoString(&dst, ": ");
12771270
if (HS_VALISNULL(entries, i))
1278-
appendStringInfoString(dst, "null");
1271+
appendStringInfoString(&dst, "null");
12791272
/* guess that values of 't' or 'f' are booleans */
12801273
else if (HS_VALLEN(entries, i) == 1 && *(HS_VAL(entries, base, i)) == 't')
1281-
appendStringInfoString(dst, "true");
1274+
appendStringInfoString(&dst, "true");
12821275
else if (HS_VALLEN(entries, i) == 1 && *(HS_VAL(entries, base, i)) == 'f')
1283-
appendStringInfoString(dst, "false");
1276+
appendStringInfoString(&dst, "false");
12841277
else
12851278
{
12861279
is_number = false;
1287-
resetStringInfo(src);
1288-
appendBinaryStringInfo(src, HS_VAL(entries, base, i), HS_VALLEN(entries, i));
1280+
resetStringInfo(&tmp);
1281+
appendBinaryStringInfo(&tmp, HS_VAL(entries, base, i), HS_VALLEN(entries, i));
12891282

12901283
/*
12911284
* don't treat something with a leading zero followed by another
12921285
* digit as numeric - could be a zip code or similar
12931286
*/
1294-
if (src->len > 0 &&
1295-
!(src->data[0] == '0' &&
1296-
isdigit((unsigned char) src->data[1])) &&
1297-
strspn(src->data, "+-0123456789Ee.") == src->len)
1287+
if (tmp.len > 0 &&
1288+
!(tmp.data[0] == '0' &&
1289+
isdigit((unsigned char) tmp.data[1])) &&
1290+
strspn(tmp.data, "+-0123456789Ee.") == tmp.len)
12981291
{
12991292
/*
13001293
* might be a number. See if we can input it as a numeric
@@ -1303,7 +1296,7 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
13031296
char *endptr = "junk";
13041297
long lval;
13051298

1306-
lval = strtol(src->data, &endptr, 10);
1299+
lval = strtol(tmp.data, &endptr, 10);
13071300
(void) lval;
13081301
if (*endptr == '\0')
13091302
{
@@ -1318,30 +1311,24 @@ hstore_to_json_loose(PG_FUNCTION_ARGS)
13181311
/* not an int - try a double */
13191312
double dval;
13201313

1321-
dval = strtod(src->data, &endptr);
1314+
dval = strtod(tmp.data, &endptr);
13221315
(void) dval;
13231316
if (*endptr == '\0')
13241317
is_number = true;
13251318
}
13261319
}
13271320
if (is_number)
1328-
appendBinaryStringInfo(dst, src->data, src->len);
1321+
appendBinaryStringInfo(&dst, tmp.data, tmp.len);
13291322
else
1330-
escape_json(dst, src->data);
1323+
escape_json(&dst, tmp.data);
13311324
}
1332-
strncpy(ptr, dst->data, dst->len);
1333-
ptr += dst->len;
13341325

13351326
if (i + 1 != count)
1336-
{
1337-
*ptr++ = ',';
1338-
*ptr++ = ' ';
1339-
}
1327+
appendStringInfoString(&dst, ", ");
13401328
}
1341-
*ptr++ = '}';
1342-
*ptr = '\0';
1329+
appendStringInfoChar(&dst, '}');
13431330

1344-
PG_RETURN_TEXT_P(cstring_to_text(out));
1331+
PG_RETURN_TEXT_P(cstring_to_text(dst.data));
13451332
}
13461333

13471334
PG_FUNCTION_INFO_V1(hstore_to_json);
@@ -1350,74 +1337,40 @@ Datum
13501337
hstore_to_json(PG_FUNCTION_ARGS)
13511338
{
13521339
HStore *in = PG_GETARG_HS(0);
1353-
int buflen,
1354-
i;
1340+
int i;
13551341
int count = HS_COUNT(in);
1356-
char *out,
1357-
*ptr;
13581342
char *base = STRPTR(in);
13591343
HEntry *entries = ARRPTR(in);
1360-
StringInfo src,
1344+
StringInfoData tmp,
13611345
dst;
13621346

13631347
if (count == 0)
13641348
PG_RETURN_TEXT_P(cstring_to_text_with_len("{}",2));
13651349

1366-
buflen = 3;
1350+
initStringInfo(&tmp);
1351+
initStringInfo(&dst);
13671352

1368-
/*
1369-
* Formula adjusted slightly from the logic in hstore_out. We have to take
1370-
* account of out treatment of booleans to be a bit more pessimistic about
1371-
* the length of values.
1372-
*/
1353+
appendStringInfoChar(&dst, '{');
13731354

13741355
for (i = 0; i < count; i++)
13751356
{
1376-
/* include "" and colon-space and comma-space */
1377-
buflen += 6 + 2 * HS_KEYLEN(entries, i);
1378-
/* include "" only if nonnull */
1379-
buflen += 3 + (HS_VALISNULL(entries, i)
1380-
? 1
1381-
: 2 * HS_VALLEN(entries, i));
1382-
}
1383-
1384-
out = ptr = palloc(buflen);
1385-
1386-
src = makeStringInfo();
1387-
dst = makeStringInfo();
1388-
1389-
*ptr++ = '{';
1390-
1391-
for (i = 0; i < count; i++)
1392-
{
1393-
resetStringInfo(src);
1394-
resetStringInfo(dst);
1395-
appendBinaryStringInfo(src, HS_KEY(entries, base, i), HS_KEYLEN(entries, i));
1396-
escape_json(dst, src->data);
1397-
strncpy(ptr, dst->data, dst->len);
1398-
ptr += dst->len;
1399-
*ptr++ = ':';
1400-
*ptr++ = ' ';
1401-
resetStringInfo(dst);
1357+
resetStringInfo(&tmp);
1358+
appendBinaryStringInfo(&tmp, HS_KEY(entries, base, i), HS_KEYLEN(entries, i));
1359+
escape_json(&dst, tmp.data);
1360+
appendStringInfoString(&dst, ": ");
14021361
if (HS_VALISNULL(entries, i))
1403-
appendStringInfoString(dst, "null");
1362+
appendStringInfoString(&dst, "null");
14041363
else
14051364
{
1406-
resetStringInfo(src);
1407-
appendBinaryStringInfo(src, HS_VAL(entries, base, i), HS_VALLEN(entries, i));
1408-
escape_json(dst, src->data);
1365+
resetStringInfo(&tmp);
1366+
appendBinaryStringInfo(&tmp, HS_VAL(entries, base, i), HS_VALLEN(entries, i));
1367+
escape_json(&dst, tmp.data);
14091368
}
1410-
strncpy(ptr, dst->data, dst->len);
1411-
ptr += dst->len;
14121369

14131370
if (i + 1 != count)
1414-
{
1415-
*ptr++ = ',';
1416-
*ptr++ = ' ';
1417-
}
1371+
appendStringInfoString(&dst, ", ");
14181372
}
1419-
*ptr++ = '}';
1420-
*ptr = '\0';
1373+
appendStringInfoChar(&dst, '}');
14211374

1422-
PG_RETURN_TEXT_P(cstring_to_text(out));
1375+
PG_RETURN_TEXT_P(cstring_to_text(dst.data));
14231376
}

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