#include "tool_easysrc.h"
#include "tool_setopt.h"
#include "tool_msgs.h"
+#include "dynbuf.h"
#include "memdebug.h" /* keep this as LAST include */
static char *c_escape(const char *str, curl_off_t len)
{
const char *s;
- unsigned char c;
- char *escaped, *e;
unsigned int cutoff = 0;
+ CURLcode result;
+ struct curlx_dynbuf escaped;
+
+ curlx_dyn_init(&escaped, 4 * MAX_STRING_LENGTH_OUTPUT + 3);
if(len == ZERO_TERMINATED)
len = strlen(str);
cutoff = 3;
}
- /* Allocate space based on worst-case */
- escaped = malloc(4 * (size_t)len + 1 + cutoff);
- if(!escaped)
- return NULL;
-
- e = escaped;
- for(s = str; len; s++, len--) {
- c = *s;
- if(c == '\n') {
- strcpy(e, "\\n");
- e += 2;
- }
- else if(c == '\r') {
- strcpy(e, "\\r");
- e += 2;
- }
- else if(c == '\t') {
- strcpy(e, "\\t");
- e += 2;
- }
- else if(c == '\\') {
- strcpy(e, "\\\\");
- e += 2;
- }
- else if(c == '"') {
- strcpy(e, "\\\"");
- e += 2;
- }
- else if(c == '?') {
- /* escape question marks as well, to prevent generating accidental
- trigraphs */
- strcpy(e, "\\?");
- e += 2;
- }
- else if(ISPRINT(c))
- *e++ = c;
- else if(len > 1 && ISXDIGIT(s[1])) {
- /* Octal escape to avoid >2 digit hex. */
- msnprintf(e, 5, "\\%03o", (unsigned)c);
- e += 4;
- }
- else {
- msnprintf(e, 5, "\\x%02x", (unsigned)c);
- e += 4;
+ result = curlx_dyn_addn(&escaped, STRCONST(""));
+ for(s = str; !result && len; s++, len--) {
+ /* escape question marks as well, to prevent generating accidental
+ trigraphs */
+ static const char from[] = "\t\r\n?\"\\";
+ static const char to[] = "\\t\\r\\n\\?\\\"\\\\";
+ const char *p = strchr(from, *s);
+
+ if(!p && ISPRINT(*s))
+ continue;
+
+ result = curlx_dyn_addn(&escaped, str, s - str);
+ str = s + 1;
+
+ if(!result) {
+ if(p && *p)
+ result = curlx_dyn_addn(&escaped, to + 2 * (p - from), 2);
+ else {
+ const char *format = "\\x%02x";
+
+ if(len > 1 && ISXDIGIT(s[1])) {
+ /* Octal escape to avoid >2 digit hex. */
+ format = "\\%03o";
+ }
+
+ result = curlx_dyn_addf(&escaped, format,
+ (unsigned int) *(unsigned char *) s);
+ }
}
}
- while(cutoff--)
- *e++ = '.';
- *e = '\0';
- return escaped;
+
+ if(!result)
+ result = curlx_dyn_addn(&escaped, str, s - str);
+
+ if(!result)
+ (void) !curlx_dyn_addn(&escaped, "...", cutoff);
+
+ return curlx_dyn_ptr(&escaped);
}
/* setopt wrapper for enum types */