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)