aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-07 19:53:32 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-07 19:53:32 +0000
commitae76ee9af95335ee201b184b69beb78e8c8856c5 (patch)
tree8d1545ec9b760cf83ea437dcebbce7abf6e8fddc
parentc79a6b110cdc1be4df98fd63813b6bb9e7e91bb4 (diff)
downloadpostgresql-ae76ee9af95335ee201b184b69beb78e8c8856c5.tar.gz
postgresql-ae76ee9af95335ee201b184b69beb78e8c8856c5.zip
Make bit/varbit substring() treat any negative length as meaning "all the rest
of the string". The previous coding treated only -1 that way, and would produce an invalid result value for other negative values. We ought to fix it so that 2-parameter bit substring() is a different C function and the 3-parameter form throws error for negative length, but that takes a pg_proc change which is impractical in the back branches; and in any case somebody might be relying on -1 working this way. So just do this as a back-patchable fix.
-rw-r--r--src/backend/utils/adt/varbit.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index e027a017dcc..31b8a7ce204 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.47.2.2 2009/12/12 19:25:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.47.2.3 2010/01/07 19:53:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -864,13 +864,23 @@ bitsubstr(PG_FUNCTION_ARGS)
*ps;
bitlen = VARBITLEN(arg);
- /* If we do not have an upper bound, set bitlen */
- if (l == -1)
- l = bitlen;
- e = s + l;
s1 = Max(s, 1);
- e1 = Min(e, bitlen + 1);
- if (s1 > bitlen || e1 < 1)
+ /* If we do not have an upper bound, use end of string */
+ if (l < 0)
+ {
+ e1 = bitlen + 1;
+ }
+ else
+ {
+ e = s + l;
+ /* guard against overflow, even though we don't allow L<0 here */
+ if (e < s)
+ ereport(ERROR,
+ (errcode(ERRCODE_SUBSTRING_ERROR),
+ errmsg("negative substring length not allowed")));
+ e1 = Min(e, bitlen + 1);
+ }
+ if (s1 > bitlen || e1 <= s1)
{
/* Need to return a zero-length bitstring */
len = VARBITTOTALLEN(0);