Avoid reading outside buffer

Current str_replace code will read outside buffer if `isspace` and `from` occurs at the start of `buffer`
This commit is contained in:
Neil Rickards
2018-02-15 18:02:59 +00:00
committed by GitHub
parent c3483747eb
commit 8ee36fb78c

View File

@@ -157,17 +157,18 @@ transliteration( PG_FUNCTION_ARGS )
PG_RETURN_TEXT_P(result); PG_RETURN_TEXT_P(result);
} }
// Set isspace=1 if the replacement _only_ adds a space before the search string. I.e. to == " " + from
void str_replace(char* buffer, int* len, int* changes, char* from, int fromlen, char* to, int tolen, int isspace) void str_replace(char* buffer, int* len, int* changes, char* from, int fromlen, char* to, int tolen, int isspace)
{ {
char *p; char *p;
// Search string is too long to be pressent // Search string is too long to be present
if (fromlen > *len) return; if (fromlen > *len) return;
p = strstr(buffer, from); p = strstr(buffer, from);
while(p) while(p)
{ {
if (!isspace || *(p-1) != ' ') if (!isspace || p == buffer || *(p-1) != ' ')
{ {
(*changes)++; (*changes)++;
if (tolen != fromlen) memmove(p+tolen, p+fromlen, *len-(p-buffer)+1); if (tolen != fromlen) memmove(p+tolen, p+fromlen, *len-(p-buffer)+1);
@@ -230,7 +231,7 @@ gettokenstring( PG_FUNCTION_ARGS )
sourcedata = (unsigned char *)VARDATA(source); sourcedata = (unsigned char *)VARDATA(source);
sourcedatalength = VARSIZE(source) - VARHDRSZ; sourcedatalength = VARSIZE(source) - VARHDRSZ;
// Buffer for doing the replace in - string could get slightly longer (double is mastive overkill) // Buffer for doing the replace in - string could get slightly longer (double is massive overkill)
buffer = (char *)palloc((sourcedatalength*2)*sizeof(char)); buffer = (char *)palloc((sourcedatalength*2)*sizeof(char));
memcpy(buffer+1, sourcedata, sourcedatalength); memcpy(buffer+1, sourcedata, sourcedatalength);
buffer[0] = 32; buffer[0] = 32;