--- fe-exec.c Thu May 8 11:49:34 2003 +++ fe-exec.c.latest Thu May 8 11:45:17 2003 @@ -180,6 +180,8 @@ return result; } +#define VAL(CH) ((CH) - '0') + /* * PQunescapeBytea - converts the null terminated string representation * of a bytea, strtext, into binary, filling a buffer. It returns a @@ -187,101 +189,66 @@ * buffer in retbuflen. The pointer may subsequently be used as an * argument to the function free(3). It is the reverse of PQescapeBytea. * - * The following transformations are reversed: - * '\0' == ASCII 0 == \000 - * '\'' == ASCII 39 == \' - * '\\' == ASCII 92 == \\ + * The following transformations are made: + * \' == ASCII 39 == ' + * \\ == ASCII 92 == \ + * \ooo == a byte whose value = ooo (ooo is an octal number) + * \x == x (x is any character not matched by the above transformations) * - * States: - * 0 normal 0->1->2->3->4 - * 1 \ 1->5 - * 2 \0 1->6 - * 3 \00 - * 4 \000 - * 5 \' - * 6 \\ */ unsigned char * PQunescapeBytea(unsigned char *strtext, size_t *retbuflen) { - size_t buflen; - unsigned char *buffer, - *sp, - *bp; - unsigned int state = 0; + size_t strtextlen, buflen; + unsigned char *buffer, *tmpbuf; + int i, j, byte; - if (strtext == NULL) + if (strtext == NULL) { return NULL; - buflen = strlen(strtext); /* will shrink, also we discover if - * strtext */ - buffer = (unsigned char *) malloc(buflen); /* isn't NULL terminated */ + } + + strtextlen = strlen(strtext); /* will shrink, also we discover if + * strtext isn't NULL terminated */ + buffer = (unsigned char *)malloc(strtextlen); if (buffer == NULL) return NULL; - for (bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++) + + for (i = j = buflen = 0; i < strtextlen;) { - switch (state) + switch (strtext[i]) { - case 0: - if (*sp == '\\') - state = 1; - *bp = *sp; - break; - case 1: - if (*sp == '\'') /* state=5 */ - { /* replace \' with 39 */ - bp--; - *bp = '\''; - buflen--; - state = 0; - } - else if (*sp == '\\') /* state=6 */ - { /* replace \\ with 92 */ - bp--; - *bp = '\\'; - buflen--; - state = 0; - } + case '\\': + i++; + if (strtext[i] == '\\') + buffer[j++] = strtext[i++]; else { - if (isdigit(*sp)) - state = 2; - else - state = 0; - *bp = *sp; + if ((isdigit(strtext[i])) && + (isdigit(strtext[i+1])) && + (isdigit(strtext[i+2]))) + { + byte = VAL(strtext[i++]); + byte = (byte << 3) + VAL(strtext[i++]); + buffer[j++] = (byte << 3) + VAL(strtext[i++]); + } } break; - case 2: - if (isdigit(*sp)) - state = 3; - else - state = 0; - *bp = *sp; - break; - case 3: - if (isdigit(*sp)) /* state=4 */ - { - int v; - bp -= 3; - sscanf(sp - 2, "%03o", &v); - *bp = v; - buflen -= 3; - state = 0; - } - else - { - *bp = *sp; - state = 0; - } - break; + default: + buffer[j++] = strtext[i++]; } } - buffer = realloc(buffer, buflen); - if (buffer == NULL) - return NULL; + buflen = j; /* buflen is the length of the unquoted data */ + tmpbuf = realloc(buffer, buflen); + + if (!tmpbuf) + { + free(buffer); + return 0; + } *retbuflen = buflen; - return buffer; + return tmpbuf; } /* ----------------