#include "warnless.h"
#include "escape.h"
#include "strdup.h"
+#include "strparse.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
}
else {
/* encode it */
- const char hex[] = "0123456789ABCDEF";
- char out[3]={'%'};
- out[1] = hex[in >> 4];
- out[2] = hex[in & 0xf];
+ unsigned char out[3]={'%'};
+ Curl_hexbyte(&out[1], in, FALSE);
if(Curl_dyn_addn(&d, out, 3))
return NULL;
}
return Curl_dyn_ptr(&d);
}
-static const unsigned char hextable[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
- 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
- 0, 10, 11, 12, 13, 14, 15 /* 0x60 - 0x66 */
-};
-
-/* the input is a single hex digit */
-#define onehex2dec(x) hextable[x - '0']
-
/*
* Curl_urldecode() URL decodes the given string.
*
if(('%' == in) && (alloc > 2) &&
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
- in = (unsigned char)(onehex2dec(string[1]) << 4) | onehex2dec(string[2]);
-
+ in = (unsigned char)((Curl_hexval(string[1]) << 4) |
+ Curl_hexval(string[2]));
string += 3;
alloc -= 3;
}
void Curl_hexencode(const unsigned char *src, size_t len, /* input length */
unsigned char *out, size_t olen) /* output buffer size */
{
- const char *hex = "0123456789abcdef";
DEBUGASSERT(src && len && (olen >= 3));
if(src && len && (olen >= 3)) {
while(len-- && (olen >= 3)) {
- *out++ = (unsigned char)hex[(*src & 0xF0) >> 4];
- *out++ = (unsigned char)hex[*src & 0x0F];
+ Curl_hexbyte(out, *src, TRUE);
++src;
+ out += 2;
olen -= 2;
}
*out = 0;
else if(olen)
*out = 0;
}
+
+/* Curl_hexbyte
+ *
+ * Output a single unsigned char as a two-digit hex number, lowercase or
+ * uppercase
+ */
+void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */
+ unsigned char val,
+ bool lowercase)
+{
+ const unsigned char uhex[] = "0123456789ABCDEF";
+ const unsigned char lhex[] = "0123456789abcdef";
+ const unsigned char *t = lowercase ? lhex : uhex;
+ dest[0] = t[val >> 4];
+ dest[1] = t[val & 0x0F];
+}
void Curl_hexencode(const unsigned char *src, size_t len, /* input length */
unsigned char *out, size_t olen); /* output buffer size */
+void Curl_hexbyte(unsigned char *dest, /* must fit two bytes */
+ unsigned char val,
+ bool lowercase);
+
#endif /* HEADER_CURL_ESCAPE_H */
result = Curl_dyn_addn(dq, "%25", 3);
break;
default: {
- const char hex[] = "0123456789ABCDEF";
- char out[3]={'%'};
+ unsigned char out[3]={'%'};
if(!found_equals) {
/* if found_equals is NULL assuming, been in path */
}
}
/* URL encode */
- out[1] = hex[((unsigned char)*q) >> 4];
- out[2] = hex[*q & 0xf];
+ Curl_hexbyte(&out[1], *q, FALSE);
result = Curl_dyn_addn(dq, out, 3);
break;
}
*/
#include "curl_setup.h"
+#include "curl_ctype.h"
+#include "strparse.h"
#ifndef HAVE_INET_PTON
static int
inet_pton4(const char *src, unsigned char *dst)
{
- static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
tp = tmp;
*tp = 0;
while((ch = *src++) != '\0') {
- const char *pch;
-
- pch = strchr(digits, ch);
- if(pch) {
- unsigned int val = (unsigned int)(*tp * 10) +
- (unsigned int)(pch - digits);
+ if(ISDIGIT(ch)) {
+ unsigned int val = (*tp * 10) + (ch - '0');
if(saw_digit && *tp == 0)
return 0;
static int
inet_pton6(const char *src, unsigned char *dst)
{
- static const char xdigits_l[] = "0123456789abcdef",
- xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *curtok;
int ch, saw_xdigit;
saw_xdigit = 0;
val = 0;
while((ch = *src++) != '\0') {
- const char *xdigits;
- const char *pch;
-
- pch = strchr((xdigits = xdigits_l), ch);
- if(!pch)
- pch = strchr((xdigits = xdigits_u), ch);
- if(pch) {
+ if(ISXDIGIT(ch)) {
val <<= 4;
- val |= (pch - xdigits);
+ val |= Curl_hexval(ch);
if(++saw_xdigit > 4)
return 0;
continue;
/* given an ASCII character and max ascii, return TRUE if valid */
#define valid_digit(x,m) \
- (((x) >= '0') && ((x) <= m) && hexasciitable[(x)-'0'])
+ (((x) >= '0') && ((x) <= m) && Curl_hexasciitable[(x)-'0'])
+
+/* We use 16 for the zero index (and the necessary bitwise AND in the loop)
+ to be able to have a non-zero value there to make valid_digit() able to
+ use the info */
+const unsigned char Curl_hexasciitable[] = {
+ 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 0x30: 0 - 9 */
+ 0, 0, 0, 0, 0, 0, 0,
+ 10, 11, 12, 13, 14, 15, /* 0x41: A - F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 11, 12, 13, 14, 15 /* 0x61: a - f */
+};
/* no support for 0x prefix nor leading spaces */
static int str_num_base(const char **linep, curl_off_t *nump, curl_off_t max,
int base) /* 8, 10 or 16, nothing else */
{
- /* We use 16 for the zero index (and the necessary bitwise AND in the loop)
- to be able to have a non-zero value there to make valid_digit() able to
- use the info */
- static const unsigned char hexasciitable[] = {
- 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* 0x30: 0 - 9 */
- 0, 0, 0, 0, 0, 0, 0,
- 10, 11, 12, 13, 14, 15, /* 0x41: A - F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 10, 11, 12, 13, 14, 15 /* 0x61: a - f */
- };
-
curl_off_t num = 0;
const char *p;
int m = (base == 10) ? '9' : /* the largest digit possible */
if(max < base) {
/* special-case low max scenario because check needs to be different */
do {
- int n = hexasciitable[*p++ - '0'] & 0x0f;
+ int n = Curl_hexval(*p++);
num = num * base + n;
if(num > max)
return STRE_OVERFLOW;
}
else {
do {
- int n = hexasciitable[*p++ - '0'] & 0x0f;
+ int n = Curl_hexval(*p++);
if(num > ((max - n) / base))
return STRE_OVERFLOW;
num = num * base + n;
void Curl_str_trimblanks(struct Curl_str *out);
void Curl_str_passblanks(const char **linep);
+/* given a hexadecimal letter, return the binary value. '0' returns 0, 'a'
+ returns 10. THIS ONLY WORKS ON VALID HEXADECIMAL LETTER INPUT. Verify
+ before calling this!
+*/
+extern const unsigned char Curl_hexasciitable[];
+#define Curl_hexval(x) (unsigned char)(Curl_hexasciitable[(x) - '0'] & 0x0f)
+
#define curlx_str_number(x,y,z) Curl_str_number(x,y,z)
#define curlx_str_octal(x,y,z) Curl_str_octal(x,y,z)
#define curlx_str_single(x,y) Curl_str_single(x,y)
#define cc2cu(x) ((x) == CURLE_TOO_LARGE ? CURLUE_TOO_LARGE : \
CURLUE_OUT_OF_MEMORY)
-static const char hexdigits[] = "0123456789abcdef";
/* urlencode_str() writes data into an output dynbuf and URL-encodes the
* spaces in the source URL accordingly.
*
result = Curl_dyn_addn(o, "+", 1);
}
else if((*iptr < ' ') || (*iptr >= 0x7f)) {
- char out[3]={'%'};
- out[1] = hexdigits[*iptr >> 4];
- out[2] = hexdigits[*iptr & 0xf];
+ unsigned char out[3]={'%'};
+ Curl_hexbyte(&out[1], *iptr, TRUE);
result = Curl_dyn_addn(o, out, 3);
}
else {
return cc2cu(result);
}
else {
- char out[3]={'%'};
- out[1] = hexdigits[*i >> 4];
- out[2] = hexdigits[*i & 0xf];
+ unsigned char out[3]={'%'};
+ Curl_hexbyte(&out[1], *i, TRUE);
result = Curl_dyn_addn(&enc, out, 3);
if(result)
return cc2cu(result);
#include "keylog.h"
#include <curl/curl.h>
+#include "escape.h"
/* The last #include files should be: */
#include "curl_memory.h"
const unsigned char client_random[CLIENT_RANDOM_SIZE],
const unsigned char *secret, size_t secretlen)
{
- const char *hex = "0123456789ABCDEF";
size_t pos, i;
- char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 +
- 2 * SECRET_MAXLEN + 1 + 1];
+ unsigned char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 +
+ 2 * SECRET_MAXLEN + 1 + 1];
if(!keylog_file_fp) {
return FALSE;
/* Client Random */
for(i = 0; i < CLIENT_RANDOM_SIZE; i++) {
- line[pos++] = hex[client_random[i] >> 4];
- line[pos++] = hex[client_random[i] & 0xF];
+ Curl_hexbyte(&line[pos], client_random[i], FALSE);
+ pos += 2;
}
line[pos++] = ' ';
/* Secret */
for(i = 0; i < secretlen; i++) {
- line[pos++] = hex[secret[i] >> 4];
- line[pos++] = hex[secret[i] & 0xF];
+ Curl_hexbyte(&line[pos], secret[i], FALSE);
+ pos += 2;
}
line[pos++] = '\n';
line[pos] = '\0';
/* Using fputs here instead of fprintf since libcurl's fprintf replacement
may not be thread-safe. */
- fputs(line, keylog_file_fp);
+ fputs((char *)line, keylog_file_fp);
return TRUE;
}