I wrote:
> Oooh, I see it ... nasty!  fixedlen_like is effectively assuming that
> it can access one byte beyond the end of the data string.  You've
> managed to set up a situation where one byte beyond falls off the
> end of the world (or the end of the backend's allocated memory, anyway).

Turns out there were several places with this problem.  Attached is a
patch against 7.0.* sources.

                        regards, tom lane

*** src/backend/utils/adt/like.c.orig   Wed Apr 12 13:15:50 2000
--- src/backend/utils/adt/like.c        Fri Jul  7 17:29:57 2000
***************
*** 50,56 ****
        (void) pg_mb2wchar_with_len((unsigned char *) s, sterm, charlen);
  #else
        sterm = (char *) palloc(charlen + 1);
!       StrNCpy(sterm, s, charlen + 1);
  #endif
  
        /*
--- 50,57 ----
        (void) pg_mb2wchar_with_len((unsigned char *) s, sterm, charlen);
  #else
        sterm = (char *) palloc(charlen + 1);
!       memcpy(sterm, s, charlen);
!       sterm[charlen] = '\0';
  #endif
  
        /*
*** src/backend/utils/adt/regexp.c.orig Wed Jan 26 00:57:14 2000
--- src/backend/utils/adt/regexp.c      Fri Jul  7 17:29:57 2000
***************
*** 182,188 ****
  
        /* be sure sterm is null-terminated */
        sterm = (char *) palloc(charlen + 1);
!       StrNCpy(sterm, s, charlen + 1);
  
        result = RE_compile_and_execute(p, sterm, cflags);
  
--- 182,189 ----
  
        /* be sure sterm is null-terminated */
        sterm = (char *) palloc(charlen + 1);
!       memcpy(sterm, s, charlen);
!       sterm[charlen] = '\0';
  
        result = RE_compile_and_execute(p, sterm, cflags);
  
*** src/backend/utils/adt/varchar.c.orig        Wed Apr 12 13:15:52 2000
--- src/backend/utils/adt/varchar.c     Fri Jul  7 17:29:57 2000
***************
*** 117,123 ****
        {
                len = VARSIZE(s) - VARHDRSZ;
                result = (char *) palloc(len + 1);
!               StrNCpy(result, VARDATA(s), len + 1);   /* these are blank-padded */
        }
  
  #ifdef CYR_RECODE
--- 117,124 ----
        {
                len = VARSIZE(s) - VARHDRSZ;
                result = (char *) palloc(len + 1);
!               memcpy(result, VARDATA(s), len);
!               result[len] = '\0';
        }
  
  #ifdef CYR_RECODE
***************
*** 249,256 ****
                return NULL;
  
        len = VARSIZE(s) - VARHDRSZ;
!       if (len > NAMEDATALEN)
!               len = NAMEDATALEN;
  
        while (len > 0)
        {
--- 250,257 ----
                return NULL;
  
        len = VARSIZE(s) - VARHDRSZ;
!       if (len >= NAMEDATALEN)
!               len = NAMEDATALEN-1;
  
        while (len > 0)
        {
***************
*** 265,271 ****
  #endif
  
        result = (NameData *) palloc(NAMEDATALEN);
!       StrNCpy(NameStr(*result), VARDATA(s), NAMEDATALEN);
  
        /* now null pad to full length... */
        while (len < NAMEDATALEN)
--- 266,272 ----
  #endif
  
        result = (NameData *) palloc(NAMEDATALEN);
!       memcpy(NameStr(*result), VARDATA(s), len);
  
        /* now null pad to full length... */
        while (len < NAMEDATALEN)
***************
*** 297,303 ****
  #endif
  
        result = (char *) palloc(VARHDRSZ + len);
!       strncpy(VARDATA(result), NameStr(*s), len);
        VARSIZE(result) = len + VARHDRSZ;
  
        return result;
--- 298,304 ----
  #endif
  
        result = (char *) palloc(VARHDRSZ + len);
!       memcpy(VARDATA(result), NameStr(*s), len);
        VARSIZE(result) = len + VARHDRSZ;
  
        return result;
***************
*** 354,360 ****
        {
                len = VARSIZE(s) - VARHDRSZ;
                result = (char *) palloc(len + 1);
!               StrNCpy(result, VARDATA(s), len + 1);
        }
  
  #ifdef CYR_RECODE
--- 355,362 ----
        {
                len = VARSIZE(s) - VARHDRSZ;
                result = (char *) palloc(len + 1);
!               memcpy(result, VARDATA(s), len);
!               result[len] = '\0';
        }
  
  #ifdef CYR_RECODE

Reply via email to