Re: upper() problem in 7.0.2

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: "Christopher L. Cousins" <chris@impulse.net>, pgsql-bugs@postgresql.org
Date: 2000-07-07T21:34:10Z
Lists: pgsql-bugs
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