Skip to content

Commit 77f4885

Browse files
committed
Fix busted TRANSLATE() code --- it coredumped due to pfree()'ing the
wrong pointer.
1 parent 795878d commit 77f4885

File tree

1 file changed

+53
-41
lines changed

1 file changed

+53
-41
lines changed

src/backend/utils/adt/oracle_compat.c

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Edmund Mergl <E.Mergl@bawue.de>
33
*
4-
* $Id: oracle_compat.c,v 1.21 2000/03/14 23:06:37 thomas Exp $
4+
* $Id: oracle_compat.c,v 1.22 2000/03/15 17:24:18 tgl Exp $
55
*
66
*/
77

@@ -500,64 +500,76 @@ substr(text *string, int4 m, int4 n)
500500
*
501501
* Purpose:
502502
*
503-
* Returns string after replacing all occurences of from with
504-
* the corresponding character in to. TRANSLATE will not remove
505-
* characters.
506-
* Modified to work with strings rather than single character
507-
* for the substitution arguments.
508-
* Modifications from Edwin Ramirez <ramirez@doc.mssm.edu>.
503+
* Returns string after replacing all occurrences of characters in from
504+
* with the corresponding character in to. If from is longer than to,
505+
* occurrences of the extra characters in from are deleted.
506+
* Improved by Edwin Ramirez <ramirez@doc.mssm.edu>.
509507
*
510508
********************************************************************/
511509

512510
text *
513511
translate(text *string, text *from, text *to)
514512
{
515-
text *ret;
516-
char *ptr_ret, *from_ptr, *to_ptr;
517-
char *source, *target, *temp, rep;
513+
text *result;
514+
char *from_ptr, *to_ptr;
515+
char *source, *target;
518516
int m, fromlen, tolen, retlen, i;
519517

520-
if ((string == (text *) NULL) ||
521-
((m = VARSIZE(string) - VARHDRSZ) <= 0))
522-
return string;
518+
if (string == (text *) NULL ||
519+
from == (text *) NULL ||
520+
to == (text *) NULL)
521+
return (text *) NULL;
523522

524-
target = (char *) palloc(VARSIZE(string) - VARHDRSZ);
525-
source = VARDATA(string);
526-
temp = target;
523+
if ((m = VARSIZE(string) - VARHDRSZ) <= 0)
524+
return string;
527525

528526
fromlen = VARSIZE(from) - VARHDRSZ;
529527
from_ptr = VARDATA(from);
530528
tolen = VARSIZE(to) - VARHDRSZ;
531-
to_ptr = VARDATA(to);
529+
to_ptr = VARDATA(to);
530+
531+
result = (text *) palloc(VARSIZE(string));
532+
533+
source = VARDATA(string);
534+
target = VARDATA(result);
532535
retlen = 0;
533-
while (m--)
536+
537+
while (m-- > 0)
534538
{
535-
rep = *source;
536-
for(i=0;i<fromlen;i++) {
537-
if(from_ptr[i] == *source) {
538-
if(i < tolen) {
539-
rep = to_ptr[i];
540-
} else {
541-
rep = 0;
542-
}
539+
char rep = *source++;
540+
541+
for (i = 0; i < fromlen; i++)
542+
{
543+
if (from_ptr[i] == rep)
543544
break;
544-
}
545545
}
546-
if(rep != 0) {
547-
*target++ = rep;
548-
retlen++;
546+
if (i < fromlen)
547+
{
548+
if (i < tolen)
549+
{
550+
/* substitute */
551+
*target++ = to_ptr[i];
552+
retlen++;
553+
}
554+
else
555+
{
556+
/* discard */
557+
}
558+
}
559+
else
560+
{
561+
/* no match, so copy */
562+
*target++ = rep;
563+
retlen++;
549564
}
550-
source++;
551565
}
552566

553-
ret = (text *) palloc(retlen + VARHDRSZ);
554-
VARSIZE(ret) = retlen + VARHDRSZ;
555-
ptr_ret = VARDATA(ret);
556-
for(i=0;i<retlen;i++) {
557-
*ptr_ret++ = temp[i];
558-
}
559-
pfree(target);
560-
return ret;
561-
}
567+
VARSIZE(result) = retlen + VARHDRSZ;
568+
/*
569+
* There may be some wasted space in the result if deletions occurred,
570+
* but it's not worth reallocating it; the function result probably
571+
* won't live long anyway.
572+
*/
562573

563-
/* EOF */
574+
return result;
575+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy