* <map> with the hexadecimal representation of their ASCII-code (2 digits)
* prefixed by <escape>, and will store the result between <start> (included)
* and <stop> (excluded), and will always terminate the string with a '\0'
- * before <stop>. If bytes are missing between <start> and <stop>, then the
- * conversion will be incomplete and truncated.
+ * before <stop>. If bytes are missing between <start> and <stop>, if
+ * <truncate> is non zero, then the conversion will be incomplete and
+ * truncated. Otherwise an error is returned.
* The input string must also be zero-terminated.
*
* Return the address of the \0 character, or NULL on error
extern long query_encode_map[];
char *encode_string(char *start, char *stop,
const char escape, const long *map,
- const char *string);
+ const char *string, int truncate);
/*
* Same behavior, except that it encodes chunk <chunk> instead of a string.
*/
char *encode_chunk(char *start, char *stop,
const char escape, const long *map,
- const struct buffer *chunk);
+ const struct buffer *chunk, int truncate);
/*
* Tries to prefix characters tagged in the <map> with the <escape>
return 0;
ret = encode_chunk(trash->area, trash->area + trash->size, '%',
- encode_map, &smp->data.u.str);
+ encode_map, &smp->data.u.str, 0);
if (ret == NULL || *ret != '\0')
return 0;
trash->data = ret - trash->area;
b64buf->data = base64_ret;
ret = encode_chunk((char*)b_stop(req_url), b_orig(req_url) + b_size(req_url), '%',
- query_encode_map, b64buf);
+ query_encode_map, b64buf, 0);
if (ret && *ret == '\0') {
req_url->data = ret - b_orig(req_url);
errcode = 0;
* <map> with the hexadecimal representation of their ASCII-code (2 digits)
* prefixed by <escape>, and will store the result between <start> (included)
* and <stop> (excluded), and will always terminate the string with a '\0'
- * before <stop>. If bytes are missing between <start> and <stop>, then the
- * conversion will be incomplete and truncated.
+ * before <stop>. If bytes are missing between <start> and <stop>, if
+ * <truncate> is non zero, then the conversion will be incomplete and
+ * truncated. Otherwise an error is returned.
* The input string must also be zero-terminated.
*
* Return the address of the \0 character, or NULL on error
const char hextab[16] __nonstring = "0123456789ABCDEF";
char *encode_string(char *start, char *stop,
const char escape, const long *map,
- const char *string)
+ const char *string, int truncate)
{
if (start < stop) {
stop--; /* reserve one byte for the final '\0' */
if (!ha_bit_test((unsigned char)(*string), map))
*start++ = *string;
else {
- if (start + 3 >= stop)
- break;
+ if (start + 3 >= stop) {
+ if (truncate)
+ break;
+ goto error;
+ }
*start++ = escape;
*start++ = hextab[(*string >> 4) & 15];
*start++ = hextab[*string & 15];
*start = '\0';
return start;
}
+ error:
return NULL;
}
* <chunk> instead of a string.
*/
char *encode_chunk(char *start, char *stop,
- const char escape, const long *map,
- const struct buffer *chunk)
+ const char escape, const long *map,
+ const struct buffer *chunk, int truncate)
{
char *str = chunk->area;
char *end = chunk->area + chunk->data;
if (!ha_bit_test((unsigned char)(*str), map))
*start++ = *str;
else {
- if (start + 3 >= stop)
- break;
+ if (start + 3 >= stop) {
+ if (truncate)
+ break;
+ goto error;
+ }
*start++ = escape;
*start++ = hextab[(*str >> 4) & 15];
*start++ = hextab[*str & 15];
*start = '\0';
return start;
}
+ error:
return NULL;
}