mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Fix busted TRANSLATE() code --- it coredumped due to pfree()'ing the
wrong pointer.
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Edmund Mergl <E.Mergl@bawue.de>
|
* Edmund Mergl <E.Mergl@bawue.de>
|
||||||
*
|
*
|
||||||
* $Id: oracle_compat.c,v 1.21 2000/03/14 23:06:37 thomas Exp $
|
* $Id: oracle_compat.c,v 1.22 2000/03/15 17:24:18 tgl Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -500,64 +500,76 @@ substr(text *string, int4 m, int4 n)
|
|||||||
*
|
*
|
||||||
* Purpose:
|
* Purpose:
|
||||||
*
|
*
|
||||||
* Returns string after replacing all occurences of from with
|
* Returns string after replacing all occurrences of characters in from
|
||||||
* the corresponding character in to. TRANSLATE will not remove
|
* with the corresponding character in to. If from is longer than to,
|
||||||
* characters.
|
* occurrences of the extra characters in from are deleted.
|
||||||
* Modified to work with strings rather than single character
|
* Improved by Edwin Ramirez <ramirez@doc.mssm.edu>.
|
||||||
* for the substitution arguments.
|
|
||||||
* Modifications from Edwin Ramirez <ramirez@doc.mssm.edu>.
|
|
||||||
*
|
*
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
text *
|
text *
|
||||||
translate(text *string, text *from, text *to)
|
translate(text *string, text *from, text *to)
|
||||||
{
|
{
|
||||||
text *ret;
|
text *result;
|
||||||
char *ptr_ret, *from_ptr, *to_ptr;
|
char *from_ptr, *to_ptr;
|
||||||
char *source, *target, *temp, rep;
|
char *source, *target;
|
||||||
int m, fromlen, tolen, retlen, i;
|
int m, fromlen, tolen, retlen, i;
|
||||||
|
|
||||||
if ((string == (text *) NULL) ||
|
if (string == (text *) NULL ||
|
||||||
((m = VARSIZE(string) - VARHDRSZ) <= 0))
|
from == (text *) NULL ||
|
||||||
return string;
|
to == (text *) NULL)
|
||||||
|
return (text *) NULL;
|
||||||
|
|
||||||
target = (char *) palloc(VARSIZE(string) - VARHDRSZ);
|
if ((m = VARSIZE(string) - VARHDRSZ) <= 0)
|
||||||
source = VARDATA(string);
|
return string;
|
||||||
temp = target;
|
|
||||||
|
|
||||||
fromlen = VARSIZE(from) - VARHDRSZ;
|
fromlen = VARSIZE(from) - VARHDRSZ;
|
||||||
from_ptr = VARDATA(from);
|
from_ptr = VARDATA(from);
|
||||||
tolen = VARSIZE(to) - VARHDRSZ;
|
tolen = VARSIZE(to) - VARHDRSZ;
|
||||||
to_ptr = VARDATA(to);
|
to_ptr = VARDATA(to);
|
||||||
|
|
||||||
|
result = (text *) palloc(VARSIZE(string));
|
||||||
|
|
||||||
|
source = VARDATA(string);
|
||||||
|
target = VARDATA(result);
|
||||||
retlen = 0;
|
retlen = 0;
|
||||||
while (m--)
|
|
||||||
|
while (m-- > 0)
|
||||||
{
|
{
|
||||||
rep = *source;
|
char rep = *source++;
|
||||||
for(i=0;i<fromlen;i++) {
|
|
||||||
if(from_ptr[i] == *source) {
|
for (i = 0; i < fromlen; i++)
|
||||||
if(i < tolen) {
|
{
|
||||||
rep = to_ptr[i];
|
if (from_ptr[i] == rep)
|
||||||
} else {
|
|
||||||
rep = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(rep != 0) {
|
if (i < fromlen)
|
||||||
*target++ = rep;
|
{
|
||||||
retlen++;
|
if (i < tolen)
|
||||||
|
{
|
||||||
|
/* substitute */
|
||||||
|
*target++ = to_ptr[i];
|
||||||
|
retlen++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* discard */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* no match, so copy */
|
||||||
|
*target++ = rep;
|
||||||
|
retlen++;
|
||||||
}
|
}
|
||||||
source++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (text *) palloc(retlen + VARHDRSZ);
|
VARSIZE(result) = retlen + VARHDRSZ;
|
||||||
VARSIZE(ret) = retlen + VARHDRSZ;
|
/*
|
||||||
ptr_ret = VARDATA(ret);
|
* There may be some wasted space in the result if deletions occurred,
|
||||||
for(i=0;i<retlen;i++) {
|
* but it's not worth reallocating it; the function result probably
|
||||||
*ptr_ret++ = temp[i];
|
* won't live long anyway.
|
||||||
}
|
*/
|
||||||
pfree(target);
|
|
||||||
return ret;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
Reference in New Issue
Block a user