Skip to content

Commit b1eb992

Browse files
committed
Fix a *second* buffer overrun bug in to_ascii(). Grumble.
1 parent 6eb27d1 commit b1eb992

File tree

1 file changed

+35
-48
lines changed

1 file changed

+35
-48
lines changed

src/backend/utils/adt/ascii.c

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
/* -----------------------------------------------------------------------
1+
/*-----------------------------------------------------------------------
22
* ascii.c
3+
* The PostgreSQL routine for string to ascii conversion.
34
*
4-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ascii.c,v 1.14 2003/04/02 21:07:59 tgl Exp $
5-
*
6-
* Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
7-
*
5+
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
86
*
9-
* TO_ASCII()
7+
* IDENTIFICATION
8+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ascii.c,v 1.15 2003/07/14 16:41:38 tgl Exp $
109
*
11-
* The PostgreSQL routine for string to ascii conversion.
12-
*
13-
* -----------------------------------------------------------------------
10+
*-----------------------------------------------------------------------
1411
*/
15-
1612
#include "postgres.h"
13+
1714
#include "utils/builtins.h"
1815
#include "mb/pg_wchar.h"
1916
#include "utils/ascii.h"
2017

18+
static void pg_to_ascii(unsigned char *src, unsigned char *src_end,
19+
unsigned char *dest, int enc);
2120
static text *encode_to_ascii(text *data, int enc);
2221

22+
2323
/* ----------
2424
* to_ascii
2525
* ----------
2626
*/
27-
char *
28-
pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *desc, int enc)
27+
static void
28+
pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *dest, int enc)
2929
{
3030
unsigned char *x;
3131
unsigned char *ascii;
@@ -37,7 +37,6 @@ pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *desc, int
3737
#define RANGE_128 128
3838
#define RANGE_160 160
3939

40-
4140
if (enc == PG_LATIN1)
4241
{
4342
/*
@@ -64,9 +63,9 @@ pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *desc, int
6463
}
6564
else
6665
{
67-
elog(ERROR, "pg_to_ascii(): unsupported encoding from %s",
66+
elog(ERROR, "unsupported encoding conversion from %s to ASCII",
6867
pg_encoding_to_char(enc));
69-
return NULL; /* keep compiler quiet */
68+
return; /* keep compiler quiet */
7069
}
7170

7271
/*
@@ -75,27 +74,27 @@ pg_to_ascii(unsigned char *src, unsigned char *src_end, unsigned char *desc, int
7574
for (x = src; x < src_end; x++)
7675
{
7776
if (*x < 128)
78-
*desc++ = *x;
77+
*dest++ = *x;
7978
else if (*x < range)
80-
*desc++ = ' '; /* bogus 128 to 'range' */
79+
*dest++ = ' '; /* bogus 128 to 'range' */
8180
else
82-
*desc++ = ascii[*x - range];
81+
*dest++ = ascii[*x - range];
8382
}
84-
85-
return desc;
8683
}
8784

8885
/* ----------
8986
* encode text
87+
*
88+
* The text datum is overwritten in-place, therefore this coding method
89+
* cannot support conversions that change the string length!
9090
* ----------
9191
*/
9292
static text *
9393
encode_to_ascii(text *data, int enc)
9494
{
95-
pg_to_ascii(
96-
(unsigned char *) VARDATA(data), /* src */
97-
VARDATA(data) + VARSIZE(data), /* src end */
98-
(unsigned char *) VARDATA(data), /* desc */
95+
pg_to_ascii((unsigned char *) VARDATA(data), /* src */
96+
(unsigned char *) (data) + VARSIZE(data), /* src end */
97+
(unsigned char *) VARDATA(data), /* dest */
9998
enc); /* encoding */
10099

101100
return data;
@@ -108,14 +107,10 @@ encode_to_ascii(text *data, int enc)
108107
Datum
109108
to_ascii_encname(PG_FUNCTION_ARGS)
110109
{
111-
PG_RETURN_TEXT_P
112-
(
113-
encode_to_ascii
114-
(
115-
PG_GETARG_TEXT_P_COPY(0),
116-
pg_char_to_encoding(NameStr(*PG_GETARG_NAME(1)))
117-
)
118-
);
110+
text *data = PG_GETARG_TEXT_P_COPY(0);
111+
int enc = pg_char_to_encoding(NameStr(*PG_GETARG_NAME(1)));
112+
113+
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
119114
}
120115

121116
/* ----------
@@ -125,14 +120,10 @@ to_ascii_encname(PG_FUNCTION_ARGS)
125120
Datum
126121
to_ascii_enc(PG_FUNCTION_ARGS)
127122
{
128-
PG_RETURN_TEXT_P
129-
(
130-
encode_to_ascii
131-
(
132-
PG_GETARG_TEXT_P_COPY(0),
133-
PG_GETARG_INT32(1)
134-
)
135-
);
123+
text *data = PG_GETARG_TEXT_P_COPY(0);
124+
int enc = PG_GETARG_INT32(1);
125+
126+
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
136127
}
137128

138129
/* ----------
@@ -142,12 +133,8 @@ to_ascii_enc(PG_FUNCTION_ARGS)
142133
Datum
143134
to_ascii_default(PG_FUNCTION_ARGS)
144135
{
145-
PG_RETURN_TEXT_P
146-
(
147-
encode_to_ascii
148-
(
149-
PG_GETARG_TEXT_P_COPY(0),
150-
GetDatabaseEncoding()
151-
)
152-
);
136+
text *data = PG_GETARG_TEXT_P_COPY(0);
137+
int enc = GetDatabaseEncoding();
138+
139+
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
153140
}

0 commit comments

Comments
 (0)