/** * Return true iff the all the lines in <b>line</b> can be encoded * using <b>flags</b>. **/ static bool kvline_can_encode_lines(const config_line_t *line, unsigned flags) { for ( ; line; line = line->next) { const bool keyless = line_has_no_key(line); if (keyless) { if (! (flags & KV_OMIT_KEYS)) { /* If KV_OMIT_KEYS is not set, we can't encode a line with no key. */ return false; } if (strchr(line->value, '=') && !( flags & KV_QUOTED)) { /* We can't have a keyless value with = without quoting it. */ return false; } } if (needs_escape(line->value, keyless) && ! (flags & KV_QUOTED)) { /* If KV_QUOTED is false, we can't encode a value that needs quotes. */ return false; } if (line->key && strlen(line->key) && (needs_escape(line->key, false) || strchr(line->key, '='))) { /* We can't handle keys that need quoting. */ return false; } } return true; }
LOG_SANITIZE_HEADER(sanitized_char_pointer, char *) { char *v = container.value; os << "(char *)"; if (v == nullptr) return os << "NULL"; bool needsEscaping = false; while (*v) if (needs_escape(*v++)) { needsEscaping = true; break; } v = container.value; os << hexstring32 << (uint32_t)v << " = \""; if (needsEscaping) { while (*v) output_char(os, *v++); } else os << v; return os << "\""; }
int main(void) { int i; build_needs_escape(); for(i = 0; i <= NEEDS_ESCAPE_BITS; ++i) { if (needs_escape(i)) { fprintf(stdout, "%3d needs escape.\n", i); } } return(0); }
static uint8_t next_txdata(void) { static enum {TX_IDLE, TX_DATA, TX_ESCAPE, TX_END} tx_state = TX_IDLE; static uint8_t tx_count = 0; uint8_t ret; switch (tx_state) { case TX_IDLE: if (transmitting) { ret = START; if (tx_buffer_count == 0) tx_state = TX_END; else tx_state = TX_DATA; tx_count = 0; } else { ret = 0; } break; case TX_DATA: { uint8_t data = tx_buffer[tx_count]; if (needs_escape(data)) { ret = ESCAPE; tx_state = TX_ESCAPE; } else { ret = data; tx_count += 1; if (tx_count >= tx_buffer_count) tx_state = TX_END; } break; } case TX_ESCAPE: ret = tx_buffer[tx_count]; tx_count += 1; if (tx_count >= tx_buffer_count) tx_state = TX_END; else tx_state = TX_DATA; break; case TX_END: default: ret = END; tx_state = TX_IDLE; transmitting = 0; break; } return ret; }
/* * Name: req_write_escape_http * Description: Buffers and "escapes" data before sending to client. * as above, but translates as it copies, into a form suitably * encoded for URLs in HTTP headers. * Returns: -1 for error, otherwise how much is stored */ int req_write_escape_http(request * req, char *msg) { char c, *inp, *dest; int left; inp = msg; dest = req->buffer + req->buffer_end; /* 3 is a guard band, since we don't check the destination pointer * in the middle of a transfer of up to 3 bytes */ left = BUFFER_SIZE - req->buffer_end - 3; while ((c = *inp++) && left > 0) { if (needs_escape((unsigned int) c)) { *dest++ = '%'; *dest++ = INT_TO_HEX(c >> 4); *dest++ = INT_TO_HEX(c & 15); left -= 3; } else {
/** * Encode a linked list of lines in <b>line</b> as a series of 'Key=Value' * pairs, using the provided <b>flags</b> to encode it. Return a newly * allocated string on success, or NULL on failure. * * If KV_QUOTED is set in <b>flags</b>, then all values that contain * spaces or unusual characters are escaped and quoted. Otherwise, such * values are not allowed. * * If KV_OMIT_KEYS is set in <b>flags</b>, then pairs with empty keys are * allowed, and are encoded as 'Value'. Otherwise, such pairs are not * allowed. */ char * kvline_encode(const config_line_t *line, unsigned flags) { if (!kvline_can_encode_lines(line, flags)) return NULL; smartlist_t *elements = smartlist_new(); for (; line; line = line->next) { const char *k = ""; const char *eq = "="; const char *v = ""; const bool keyless = line_has_no_key(line); bool esc = needs_escape(line->value, keyless); char *tmp = NULL; if (! keyless) { k = line->key; } else { eq = ""; if (strchr(line->value, '=')) { esc = true; } } if (esc) { tmp = esc_for_log(line->value); v = tmp; } else { v = line->value; } smartlist_add_asprintf(elements, "%s%s%s", k, eq, v); tor_free(tmp); } char *result = smartlist_join_strings(elements, " ", 0, NULL); SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp)); smartlist_free(elements); return result; }
char *http_escape_string(char *inp, char *buf, const int len) { int max; char *index; unsigned char c; max = len * 3; if (buf == NULL && max) buf = malloc(sizeof (unsigned char) * (max + 1)); if (buf == NULL) return NULL; index = buf; while ((c = *inp++)) { if (needs_escape((unsigned int) c)) { *index++ = '%'; *index++ = INT_TO_HEX(c >> 4); *index++ = INT_TO_HEX(c & 15); } else
LOG_SANITIZE_HEADER(sanitized_wchar_pointer, wchar_t *) { wchar_t *v = container.value; os << "(wchar *)"; if (v == nullptr) return os << "NULL"; bool needsEscaping = false; while (*v) if (needs_escape(*v++)) { needsEscaping = true; break; } v = container.value; os << hexstring32 << (uint32_t)v << " = \""; if (needsEscaping) { while (*v) output_wchar(os, *v++); } else #if 0 os << v; // TODO : FIXME - VS2015 doesn''t render this string (instead, it shows a hexadecimal memory address) #else // For now, render unicode as ANSI (replacing non-printables with '?') { while (*v) { output_char(os, *v <= 0xFF ? (char)*v : '?'); v++; } } #endif return os << "\""; }
inline void output_wchar(std::ostream& os, wchar_t c) { if (needs_escape((wint_t)c)) { switch (c) { // Render escaped double quote as \", and escaped backslash as \\ : case '"': os << "\\\""; break; case '\\': os << "\\\\"; break; // See https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences case '\a': os << "\\t"; break; case '\b': os << "\\b"; break; case '\f': os << "\\f"; break; case '\n': os << "\\n"; break; case '\r': os << "\\r"; break; case '\t': os << "\\t"; break; case '\v': os << "\\v"; break; // All other to-escape-characters are rendered as hexadecimal : default: os << "\\x" << std::setfill('0') << std::setw(4) << std::right << std::hex << std::uppercase << (wint_t)c; } } else os << c; }
static char *escape_pathname(const char *inp) { const unsigned char *s; char *escaped, *d; if (!inp) { return NULL; } escaped = malloc (4 * strlen(inp) + 1); if (!escaped) { perror("malloc"); return NULL; } for (d = escaped, s = (const unsigned char *)inp; *s; s++) { if (needs_escape (*s)) { snprintf (d, 5, "\\x%02x", *s); d += strlen (d); } else { *d++ = *s; } } *d++ = '\0'; return escaped; }