From b196b7fb721440ae814c0215ff889dce00fd26a2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 8 Oct 2007 20:25:40 +0000 Subject: [PATCH] Get rid of dependency on strtoull() --- Marko Kreen. Some additional minor editorializing by Tom. --- contrib/txid/expected/txid.out | 21 ++++++++++----- contrib/txid/sql/txid.sql | 3 +++ contrib/txid/txid.c | 48 +++++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/contrib/txid/expected/txid.out b/contrib/txid/expected/txid.out index c0220bb525..1b0da20b5f 100644 --- a/contrib/txid/expected/txid.out +++ b/contrib/txid/expected/txid.out @@ -8,18 +8,18 @@ select '12:13:'::txid_snapshot; (1 row) select '12:13:1,2'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "12:13:1,2" -- errors select '31:12:'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "31:12:" select '0:1:'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "0:1:" select '12:13:0'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "12:13:0" select '12:16:14,13'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "12:16:14,13" select '12:16:14,14'::txid_snapshot; -ERROR: illegal txid_snapshot input format +ERROR: invalid input for txid_snapshot: "12:16:14,14" create table snapshot_test ( nr integer, snap txid_snapshot @@ -210,3 +210,12 @@ select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010 t (1 row) +-- test 64bit overflow +SELECT txid_snapshot '1:9223372036854775807:3'; + txid_snapshot +------------------------- + 1:9223372036854775807:3 +(1 row) + +SELECT txid_snapshot '1:9223372036854775808:3'; +ERROR: invalid input for txid_snapshot: "1:9223372036854775808:3" diff --git a/contrib/txid/sql/txid.sql b/contrib/txid/sql/txid.sql index b86bfffb05..efedb86bfa 100644 --- a/contrib/txid/sql/txid.sql +++ b/contrib/txid/sql/txid.sql @@ -56,3 +56,6 @@ select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100 select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); +-- test 64bit overflow +SELECT txid_snapshot '1:9223372036854775807:3'; +SELECT txid_snapshot '1:9223372036854775808:3'; diff --git a/contrib/txid/txid.c b/contrib/txid/txid.c index 8a4b5e797b..606fb40040 100644 --- a/contrib/txid/txid.c +++ b/contrib/txid/txid.c @@ -225,6 +225,39 @@ buf_finalize(StringInfo buf) return snap; } +/* + * simple number parser. + * + * We return 0 on error, which is invalid value for txid. + */ +static txid +str2txid(const char *s, const char **endp) +{ + txid val = 0; + + for (; *s; s++) + { + txid last = val; + + if (*s < '0' || *s > '9') + break; + + val = val * 10 + (*s - '0'); + + /* + * check for overflow + */ + if (val > MAX_TXID || (val / 10) != last) + { + val = 0; + break; + } + } + if (endp) + *endp = s; + return val; +} + /* * parse snapshot from cstring */ @@ -234,21 +267,22 @@ parse_snapshot(const char *str) txid xmin; txid xmax; txid last_val = 0, val; - char *endp; + const char *str_start = str; + const char *endp; StringInfo buf; - xmin = (txid) strtoull(str, &endp, 0); + xmin = str2txid(str, &endp); if (*endp != ':') goto bad_format; str = endp + 1; - xmax = (txid) strtoull(str, &endp, 0); + xmax = str2txid(str, &endp); if (*endp != ':') goto bad_format; str = endp + 1; /* it should look sane */ - if (xmin > xmax || xmin == 0 || xmax > MAX_TXID) + if (xmin == 0 || xmax == 0 || xmin > xmax) goto bad_format; /* allocate buffer */ @@ -258,11 +292,11 @@ parse_snapshot(const char *str) while (*str != '\0') { /* read next value */ - val = (txid) strtoull(str, &endp, 0); + val = str2txid(str, &endp); str = endp; /* require the input to be in order */ - if (val < xmin || val <= last_val || val >= xmax) + if (val < xmin || val >= xmax || val <= last_val) goto bad_format; buf_add_txid(buf, val); @@ -277,7 +311,7 @@ parse_snapshot(const char *str) return buf_finalize(buf); bad_format: - elog(ERROR, "illegal txid_snapshot input format"); + elog(ERROR, "invalid input for txid_snapshot: \"%s\"", str_start); return NULL; }