diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-01-07 19:53:11 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-01-07 19:53:11 +0000 |
commit | e4a6ebf7dece1481b1432c8ac43124487bebf3d9 (patch) | |
tree | 8ce7c3f3b35016daeaf0a569c628deddd7154708 /src | |
parent | 82170c747bf74e31f7083849c07a53ec643356b4 (diff) | |
download | postgresql-e4a6ebf7dece1481b1432c8ac43124487bebf3d9.tar.gz postgresql-e4a6ebf7dece1481b1432c8ac43124487bebf3d9.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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/varbit.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index 6882231e617..d98a8a613ee 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.61 2010/01/07 04:53:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.62 2010/01/07 19:53:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -945,13 +945,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); |