/* Decode string %xx -> char (in place) */ static void urldecode(char *buf) { int v; char *p, *s, *w; w = p = buf; while (*p) { v = 0; if (*p == '%') { s = p; s++; if (isxdigit((int) s[0]) && isxdigit((int) s[1])) { v = hexit(s[0]) * 16 + hexit(s[1]); if (v) { /* do not decode %00 to null char */ *w = (char)v; p = &s[1]; } } } if (!v) *w = *p; p++; w++; } *w = '\0'; }
/* * ccn_append_uri_component: * This takes as input the escaped URI component at s and appends it * to c. This does not do any ccnb-related stuff. * Processing stops at an error or if an unescaped nul, '/', '?', or '#' is found. * A component that consists solely of dots gets special treatment to reverse * the addition of ... by ccn_uri_append_percentescaped. Since '.' is an unreserved * character, percent-encoding is not supposed to change meaning and hence * the dot processing happens after percent-encoding is removed. * A positive return value indicates there were unescaped reserved or * non-printable characters found. This might warrant some extra checking * by the caller. * A return value of -1 indicates the component was "..", so the caller * will need to do something extra to handle this as appropriate. * A return value of -2 indicates the component was empty or ".", so the caller * should do nothing with it. * A return value of -3 indicates a bad %-escaped sequence. * If cont is not NULL, *cont is set to the number of input characters processed. */ int ccn_append_uri_component(struct ccn_charbuf *c, const char *s, size_t limit, size_t *cont) { size_t start = c->length; size_t i; int err = 0; int d1, d2; unsigned char ch; for (i = 0; i < limit; i++) { ch = s[i]; switch (ch) { case 0: case '/': case '?': case '#': limit = i; break; case '%': if (i + 3 > limit || (d1 = hexit(s[i+1])) < 0 || (d2 = hexit(s[i+2])) < 0 ) { return(-3); } ch = d1 * 16 + d2; i += 2; ccn_charbuf_append(c, &ch, 1); break; case ':': case '[': case ']': case '@': case '!': case '$': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case ';': case '=': err++; /* FALLTHROUGH */ default: if (ch <= ' ' || ch > '~') err++; ccn_charbuf_append(c, &ch, 1); break; } } for (i = start; i < c->length && c->buf[i] == '.'; i++) continue; if (i == c->length) { /* all dots */ i -= start; if (i <= 1) { c->length = start; err = -2; } else if (i == 2) { c->length = start; err = -1; } else c->length -= 3; } if (cont != NULL) *cont = limit; return(err); }
/* Copies and decodes a string. It's ok for from and to to be the ** same string. */ static void strdecode( char* to, char* from ) { for ( ; *from != '\0'; ++to, ++from ) { if ( from[0] == '%' && isxdigit( from[1] ) && isxdigit( from[2] ) ) { *to = hexit( from[1] ) * 16 + hexit( from[2] ); from += 2; } else *to = *from; } *to = '\0'; }
static void decode_url(struct http_request *req, int8 *url) { int8 *cp = url; int8 *to = url; req->path = url; for (; *cp != '\0'; ++to, ++cp) { if (cp[0] == '%' && isxdigit(cp[1]) && isxdigit(cp[2])) { *to = (hexit(cp[1]) << 4) | hexit(cp[2]); cp += 2; } else if (cp[0] == '?') { *to = '\0'; req->query = cp + 1; break; } else { *to = *cp; } } *to = '\0'; }
int main( int argc, char **argv) { char *b; char *c; char **p; char *d; char *e; char *ee; int did; int fd = 0; int offset; int lth; int count; int little; long start; long pos; long left; union { short x; char y[2]; } end_test; (void)argc; end_test.x = 1; little = (end_test.y[0] > 0); for (c = obuf; c < &obuf[66]; *c++ = ' '); *c++ = '\n'; for (p = &argv[1], pos = left = 0; *p; p++) { b = &(c = *p)[1]; if (*c == '-') { if (*b == 'a' || *b == 'A') { if (aflag) FATAL(MSG_INVAL); aflag = (*b == 'a') ? 1 : -1; } else if (*b == 'l') little = 1; else if (*b == 'b') little = 0; else pos = -getd(&b, 0); } else if (*c == '+') pos = getd(&b, 0); else if (is_numeric(c)) left = getd(&c, 0); else fname = c; } if (fname && (fd = open(fname, O_RDONLY)) < 0) FATAL(MSG_OPEN); if (aflag) dump_asn1(fd, pos); if (pos < 0) start = lseek(fd, 0L, 2); else start = 0; lseek(fd, ((start + pos) & ~(BSIZE - 1)), 0); c = &ibuf[((pos += start) & (BSIZE - 1))]; if (!left) left = 1000000000; left += (c - ibuf); did = 16 - (offset = pos & 0xF); for (; left; c = ibuf) { for (lth = 0; (count = read(fd, &ibuf[lth], (int)((left > BSIZE - lth) ? BSIZE - lth : left))); lth += count); if (!lth) break; if (c > ibuf) { lth -= (c - ibuf); left -= (c - ibuf); } if (lth > left) lth = left; for (e = &c[lth]; c < e && left;) /* each input block */ { if (!little) for (; lth > 0;) /* each output line */ { for (*(b = &obuf[5]) = '0', start = pos; start; start >>= 4) *b-- = hex[start & 0xF]; b = &obuf[8]; d = &obuf[50]; if (offset) { b += (2 * offset + (offset / 2)); d += offset; if (offset & 1) { b = hexit(b, *c); *d++ = *c++; *b++ = ' '; } offset = 0; } for (ee = &c[lth]; d < &obuf[66] && c < ee;) { b = hexit(b, *c); *d++ = *c++; if (c >= ee) break; b = hexit(b, *c); *d++ = *c++; *b++ = ' '; } while (b < &obuf[50]) *b++ = ' '; for (b = &obuf[50]; b < d; b++) if (*b < ' ' || (unsigned char)*b > '~') *b = '.'; while (d < &obuf[66]) *d++ = ' '; if (write(1, obuf, 67) != 67) abort(); pos += did; lth -= did; left -= did; did = (left > 16) ? 16 : left; } else for (; lth > 0;) /* each output line */ { for (*(b = &obuf[47]) = '0', start = pos; start; start >>= 4) *b-- = hex[start & 0xF]; b = &obuf[38]; d = &obuf[50]; if (offset) { b -= (2 * offset + (offset / 2)); d += offset; if (offset & 1) { b--; b = &hexit(b, *c)[-4]; *d++ = *c++; } offset = 0; } for (ee = &c[lth]; d < &obuf[66] && c < ee;) { *b-- = ' '; b = &hexit(b, *c)[-4]; *d++ = *c++; if (c >= ee) break; b = &hexit(b, *c)[-4]; *d++ = *c++; } if (b > obuf) b[1] = ' '; while (b >= obuf) *b-- = ' '; for (b = &obuf[50]; b < d; b++) if (*b < ' ' || (unsigned char)*b > '~') *b = '.'; while (d < &obuf[66]) *d++ = ' '; if (write(1, obuf, 67) != 67) abort(); pos += did; lth -= did; left -= did; did = (left > 16) ? 16 : left; } } }