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