]> granicus.if.org Git - postgresql/commitdiff
Avoid generating invalid character encoding sequences in make_greater_string.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 2 Feb 2004 03:07:14 +0000 (03:07 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 2 Feb 2004 03:07:14 +0000 (03:07 +0000)
Not sure how this mistake evaded detection for so long.

src/backend/utils/adt/selfuncs.c

index dbe930618bdc8f94442ac70f087fb3447597a541..77986d4ca8bdcc3d04375d49a35bc2aaf33807a5 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.147.2.1 2003/12/07 04:12:50 joe Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.147.2.2 2004/02/02 03:07:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3738,6 +3738,11 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
  *
  * This could be rather slow in the worst case, but in most cases we
  * won't have to try more than one or two strings before succeeding.
+ *
+ * NOTE: at present this assumes we are in the C locale, so that simple
+ * bytewise comparison applies.  However, we might be in a multibyte
+ * encoding such as UTF-8, so we do have to watch out for generating
+ * invalid encoding sequences.
  */
 Const *
 make_greater_string(const Const *str_const)
@@ -3784,13 +3789,20 @@ make_greater_string(const Const *str_const)
                /*
                 * Try to generate a larger string by incrementing the last byte.
                 */
-               if (*lastchar < (unsigned char) 255)
+               while (*lastchar < (unsigned char) 255)
                {
                        Const      *workstr_const;
 
                        (*lastchar)++;
+
                        if (datatype != BYTEAOID)
+                       {
+                               /* do not generate invalid encoding sequences */
+                               if (!pg_verifymbstr((const unsigned char *) workstr,
+                                                                       len, true))
+                                       continue;
                                workstr_const = string_to_const(workstr, datatype);
+                       }
                        else
                                workstr_const = string_to_bytea_const(workstr, len);