ignore : separators in hex input
This commit is contained in:
parent
a4a3632c30
commit
c4e252c55b
|
@ -62,98 +62,123 @@ const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t
|
||||||
int skipSpace = 0;
|
int skipSpace = 0;
|
||||||
|
|
||||||
if (srclen == 0)
|
if (srclen == 0)
|
||||||
|
{
|
||||||
srclen = strlen(src);
|
srclen = strlen(src);
|
||||||
|
}
|
||||||
if (dstlen == 0)
|
if (dstlen == 0)
|
||||||
|
{
|
||||||
dst = buf; /* point it somewhere valid */
|
dst = buf; /* point it somewhere valid */
|
||||||
|
}
|
||||||
stop = dst + dstlen;
|
stop = dst + dstlen;
|
||||||
|
|
||||||
if (base == 0) {
|
if (base == 0)
|
||||||
|
{
|
||||||
if (srclen < 2)
|
if (srclen < 2)
|
||||||
|
{
|
||||||
return "input too short to be valid";
|
return "input too short to be valid";
|
||||||
|
}
|
||||||
if (*src++ != '0')
|
if (*src++ != '0')
|
||||||
|
{
|
||||||
return "input does not begin with format prefix";
|
return "input does not begin with format prefix";
|
||||||
switch (*src++) {
|
}
|
||||||
case 'x':
|
switch (*src++)
|
||||||
case 'X':
|
{
|
||||||
base = 16;
|
case 'x':
|
||||||
break;
|
case 'X':
|
||||||
case 's':
|
base = 16;
|
||||||
case 'S':
|
break;
|
||||||
base = 64;
|
case 's':
|
||||||
break;
|
case 'S':
|
||||||
case 't':
|
base = 64;
|
||||||
case 'T':
|
break;
|
||||||
base = 256;
|
case 't':
|
||||||
break;
|
case 'T':
|
||||||
default:
|
base = 256;
|
||||||
return "unknown format prefix";
|
break;
|
||||||
|
default:
|
||||||
|
return "unknown format prefix";
|
||||||
}
|
}
|
||||||
srclen -= 2;
|
srclen -= 2;
|
||||||
}
|
}
|
||||||
switch (base) {
|
switch (base)
|
||||||
case 16:
|
{
|
||||||
decode = unhex;
|
case 16:
|
||||||
underscoreok = 1;
|
decode = unhex;
|
||||||
ingroup = 2;
|
underscoreok = 1;
|
||||||
break;
|
ingroup = 2;
|
||||||
case 64:
|
break;
|
||||||
decode = unb64;
|
case 64:
|
||||||
underscoreok = 0;
|
decode = unb64;
|
||||||
ingroup = 4;
|
underscoreok = 0;
|
||||||
if(flags & TTODATAV_IGNORESPACE) {
|
ingroup = 4;
|
||||||
skipSpace = 1;
|
if(flags & TTODATAV_IGNORESPACE)
|
||||||
}
|
{
|
||||||
break;
|
skipSpace = 1;
|
||||||
|
}
|
||||||
case 256:
|
break;
|
||||||
decode = untext;
|
case 256:
|
||||||
ingroup = 1;
|
decode = untext;
|
||||||
underscoreok = 0;
|
ingroup = 1;
|
||||||
break;
|
underscoreok = 0;
|
||||||
default:
|
break;
|
||||||
return "unknown base";
|
default:
|
||||||
|
return "unknown base";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* proceed */
|
/* proceed */
|
||||||
ndone = 0;
|
ndone = 0;
|
||||||
while (srclen > 0) {
|
while (srclen > 0)
|
||||||
|
{
|
||||||
char stage[4]; /* staging area for group */
|
char stage[4]; /* staging area for group */
|
||||||
size_t sl = 0;
|
size_t sl = 0;
|
||||||
|
|
||||||
/* Grab ingroup characters into stage,
|
/* Grab ingroup characters into stage,
|
||||||
* squeezing out blanks if we are supposed to ignore them.
|
* squeezing out blanks if we are supposed to ignore them.
|
||||||
*/
|
*/
|
||||||
for (sl = 0; sl < ingroup; src++, srclen--) {
|
for (sl = 0; sl < ingroup; src++, srclen--)
|
||||||
|
{
|
||||||
if (srclen == 0)
|
if (srclen == 0)
|
||||||
|
{
|
||||||
return "input ends in mid-byte, perhaps truncated";
|
return "input ends in mid-byte, perhaps truncated";
|
||||||
|
}
|
||||||
else if (!(skipSpace && (*src == ' ' || *src == '\t')))
|
else if (!(skipSpace && (*src == ' ' || *src == '\t')))
|
||||||
|
{
|
||||||
stage[sl++] = *src;
|
stage[sl++] = *src;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nbytes = (*decode)(stage, buf, sizeof(buf));
|
nbytes = (*decode)(stage, buf, sizeof(buf));
|
||||||
switch (nbytes) {
|
switch (nbytes)
|
||||||
case BADCH0:
|
{
|
||||||
case BADCH1:
|
case BADCH0:
|
||||||
case BADCH2:
|
case BADCH1:
|
||||||
case BADCH3:
|
case BADCH2:
|
||||||
return badch(stage, nbytes, errp, errlen);
|
case BADCH3:
|
||||||
case SHORT:
|
return badch(stage, nbytes, errp, errlen);
|
||||||
return "internal buffer too short (\"can't happen\")";
|
case SHORT:
|
||||||
case BADPAD:
|
return "internal buffer too short (\"can't happen\")";
|
||||||
return "bad (non-zero) padding at end of base64 input";
|
case BADPAD:
|
||||||
|
return "bad (non-zero) padding at end of base64 input";
|
||||||
}
|
}
|
||||||
if (nbytes <= 0)
|
if (nbytes <= 0)
|
||||||
|
{
|
||||||
return "unknown internal error";
|
return "unknown internal error";
|
||||||
for (i = 0; i < nbytes; i++) {
|
}
|
||||||
|
for (i = 0; i < nbytes; i++)
|
||||||
|
{
|
||||||
if (dst < stop)
|
if (dst < stop)
|
||||||
|
{
|
||||||
*dst++ = buf[i];
|
*dst++ = buf[i];
|
||||||
|
}
|
||||||
ndone++;
|
ndone++;
|
||||||
}
|
}
|
||||||
while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
|
while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t'))
|
||||||
|
{
|
||||||
src++;
|
src++;
|
||||||
srclen--;
|
srclen--;
|
||||||
}
|
}
|
||||||
if (underscoreok && srclen > 1 && *src == '_') {
|
if (underscoreok && srclen > 1 && (*src == '_' || *src == ':'))
|
||||||
|
{
|
||||||
/* srclen > 1 means not last character */
|
/* srclen > 1 means not last character */
|
||||||
src++;
|
src++;
|
||||||
srclen--;
|
srclen--;
|
||||||
|
@ -161,9 +186,13 @@ const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ndone == 0)
|
if (ndone == 0)
|
||||||
|
{
|
||||||
return "no data bytes specified by input";
|
return "no data bytes specified by input";
|
||||||
|
}
|
||||||
if (lenp != NULL)
|
if (lenp != NULL)
|
||||||
|
{
|
||||||
*lenp = ndone;
|
*lenp = ndone;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,9 +230,7 @@ size_t atodata(const char *src, size_t srclen, char *dst, size_t dstlen)
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
err = ttodata(src, srclen, 0, dst, dstlen, &len);
|
err = ttodata(src, srclen, 0, dst, dstlen, &len);
|
||||||
if (err != NULL)
|
return (err)? 0:len;
|
||||||
return 0;
|
|
||||||
return len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -231,21 +258,31 @@ static int unhex(const char *src, char *dst, size_t dstlen)
|
||||||
static char hex[] = "0123456789abcdef";
|
static char hex[] = "0123456789abcdef";
|
||||||
|
|
||||||
if (dstlen < 1)
|
if (dstlen < 1)
|
||||||
|
{
|
||||||
return SHORT;
|
return SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
p = strchr(hex, *src);
|
p = strchr(hex, *src);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
{
|
||||||
p = strchr(hex, tolower(*src));
|
p = strchr(hex, tolower(*src));
|
||||||
|
}
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
{
|
||||||
return BADCH0;
|
return BADCH0;
|
||||||
|
}
|
||||||
byte = (p - hex) << 4;
|
byte = (p - hex) << 4;
|
||||||
src++;
|
src++;
|
||||||
|
|
||||||
p = strchr(hex, *src);
|
p = strchr(hex, *src);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
{
|
||||||
p = strchr(hex, tolower(*src));
|
p = strchr(hex, tolower(*src));
|
||||||
|
}
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
{
|
||||||
return BADCH1;
|
return BADCH1;
|
||||||
|
}
|
||||||
byte |= (p - hex);
|
byte |= (p - hex);
|
||||||
|
|
||||||
*dst = byte;
|
*dst = byte;
|
||||||
|
@ -272,16 +309,20 @@ static int unb64(const char *src, char *dst, size_t dstlen)
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
if (dstlen < 3)
|
if (dstlen < 3)
|
||||||
|
{
|
||||||
return SHORT;
|
return SHORT;
|
||||||
|
}
|
||||||
p = strchr(base64, *src++);
|
p = strchr(base64, *src++);
|
||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
{
|
||||||
return BADCH0;
|
return BADCH0;
|
||||||
|
}
|
||||||
byte1 = (p - base64) << 2; /* first six bits */
|
byte1 = (p - base64) << 2; /* first six bits */
|
||||||
|
|
||||||
p = strchr(base64, *src++);
|
p = strchr(base64, *src++);
|
||||||
if (p == NULL) {
|
if (p == NULL)
|
||||||
|
{
|
||||||
return BADCH1;
|
return BADCH1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,10 +331,14 @@ static int unb64(const char *src, char *dst, size_t dstlen)
|
||||||
byte1 = (byte2 & 0xf) << 4;
|
byte1 = (byte2 & 0xf) << 4;
|
||||||
|
|
||||||
p = strchr(base64, *src++);
|
p = strchr(base64, *src++);
|
||||||
if (p == NULL) {
|
if (p == NULL)
|
||||||
if (*(src-1) == '=' && *src == '=') {
|
{
|
||||||
|
if (*(src-1) == '=' && *src == '=')
|
||||||
|
{
|
||||||
if (byte1 != 0) /* bad padding */
|
if (byte1 != 0) /* bad padding */
|
||||||
|
{
|
||||||
return BADPAD;
|
return BADPAD;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return BADCH2;
|
return BADCH2;
|
||||||
|
@ -304,10 +349,14 @@ static int unb64(const char *src, char *dst, size_t dstlen)
|
||||||
byte1 = (byte2 & 0x3) << 6;
|
byte1 = (byte2 & 0x3) << 6;
|
||||||
|
|
||||||
p = strchr(base64, *src++);
|
p = strchr(base64, *src++);
|
||||||
if (p == NULL) {
|
if (p == NULL)
|
||||||
if (*(src-1) == '=') {
|
{
|
||||||
|
if (*(src-1) == '=')
|
||||||
|
{
|
||||||
if (byte1 != 0) /* bad padding */
|
if (byte1 != 0) /* bad padding */
|
||||||
|
{
|
||||||
return BADPAD;
|
return BADPAD;
|
||||||
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return BADCH3;
|
return BADCH3;
|
||||||
|
@ -329,8 +378,9 @@ static int unb64(const char *src, char *dst, size_t dstlen)
|
||||||
static int untext(const char *src, char *dst, size_t dstlen)
|
static int untext(const char *src, char *dst, size_t dstlen)
|
||||||
{
|
{
|
||||||
if (dstlen < 1)
|
if (dstlen < 1)
|
||||||
|
{
|
||||||
return SHORT;
|
return SHORT;
|
||||||
|
}
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -359,13 +409,18 @@ static const char *badch(const char *src, int errcode, char *errp, size_t errlen
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
if (errp == NULL || errlen < REQD)
|
if (errp == NULL || errlen < REQD)
|
||||||
|
{
|
||||||
return "unknown character in input";
|
return "unknown character in input";
|
||||||
|
}
|
||||||
strcpy(errp, pre);
|
strcpy(errp, pre);
|
||||||
ch = *(src + BADOFF(errcode));
|
ch = *(src + BADOFF(errcode));
|
||||||
if (isprint(ch)) {
|
if (isprint(ch))
|
||||||
|
{
|
||||||
buf[0] = ch;
|
buf[0] = ch;
|
||||||
buf[1] = '\0';
|
buf[1] = '\0';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
buf[0] = '\\';
|
buf[0] = '\\';
|
||||||
buf[1] = ((ch & 0700) >> 6) + '0';
|
buf[1] = ((ch & 0700) >> 6) + '0';
|
||||||
buf[2] = ((ch & 0070) >> 3) + '0';
|
buf[2] = ((ch & 0070) >> 3) + '0';
|
||||||
|
|
Loading…
Reference in New Issue