Commit 616bae1a authored by v0-e's avatar v0-e

jer: UTF-8 escape control chars and handle escaped unicodes

parent 1c56d4d7
...@@ -53,42 +53,43 @@ static const struct OCTET_STRING__jer_escape_table_s { ...@@ -53,42 +53,43 @@ static const struct OCTET_STRING__jer_escape_table_s {
const char *string; const char *string;
int size; int size;
} OCTET_STRING__jer_escape_table[] = { } OCTET_STRING__jer_escape_table[] = {
#define OSXET(s) { s, sizeof(s) - 1 } #define OSXBT(s) { "\\"s"", sizeof(s) + 1 - 1 }
{ 0, 0 }, /* NULL */ #define OSXUT(s) { "\\u00"s"", sizeof(s) + 4 - 1 }
{ 0, 0 }, /* Start of header */ OSXUT("00"), /* NULL */
{ 0, 0 }, /* Start of text */ OSXUT("01"), /* Start of header */
{ 0, 0 }, /* End of text */ OSXUT("02"), /* Start of text */
{ 0, 0 }, /* End of transmission */ OSXUT("03"), /* End of text */
{ 0, 0 }, /* Enquiry */ OSXUT("04"), /* End of transmission */
{ 0, 0 }, /* Ack */ OSXUT("05"), /* Enquiry */
{ 0, 0 }, /* Bell */ OSXUT("06"), /* Ack */
OSXET("\134\142"), /* \b */ OSXUT("07"), /* Bell */
OSXET("\134\164"), /* \t */ OSXBT("b"), /* \b */
OSXET("\134\156"), /* \n */ OSXBT("t"), /* \t */
{ 0, 0 }, /* Vertical tab */ OSXBT("n"), /* \n */
OSXET("\134\146"), /* \f */ OSXUT("0b"), /* Vertical tab */
OSXET("\134\162"), /* \r */ OSXBT("f"), /* \f */
{ 0, 0 }, /* Shift out */ OSXBT("r"), /* \r */
{ 0, 0 }, /* Shift in */ OSXUT("0e"), /* Shift out */
{ 0, 0 }, /* Data link escape */ OSXUT("0f"), /* Shift in */
{ 0, 0 }, /* Device control 1 */ OSXUT("10"), /* Data link escape */
{ 0, 0 }, /* Device control 2 */ OSXUT("11"), /* Device control 1 */
{ 0, 0 }, /* Device control 3 */ OSXUT("12"), /* Device control 2 */
{ 0, 0 }, /* Device control 4 */ OSXUT("13"), /* Device control 3 */
{ 0, 0 }, /* Negative ack */ OSXUT("14"), /* Device control 4 */
{ 0, 0 }, /* Synchronous idle */ OSXUT("15"), /* Negative ack */
{ 0, 0 }, /* End of transmission block */ OSXUT("16"), /* Synchronous idle */
{ 0, 0 }, /* Cancel */ OSXUT("17"), /* End of transmission block */
{ 0, 0 }, /* End of medium */ OSXUT("18"), /* Cancel */
{ 0, 0 }, /* Substitute */ OSXUT("19"), /* End of medium */
{ 0, 0 }, /* Escape */ OSXUT("1a"), /* Substitute */
{ 0, 0 }, /* File separator */ OSXUT("1b"), /* Escape */
{ 0, 0 }, /* Group separator */ OSXUT("1c"), /* File separator */
{ 0, 0 }, /* Record separator */ OSXUT("1d"), /* Group separator */
{ 0, 0 }, /* Unit separator */ OSXUT("1e"), /* Record separator */
OSXUT("1f"), /* Unit separator */
{ 0, 0 }, /* " " */ { 0, 0 }, /* " " */
{ 0, 0 }, /* ! */ { 0, 0 }, /* ! */
OSXET("\134\042"), /* \" */ OSXBT("\""), /* \" */
{ 0, 0 }, /* # */ { 0, 0 }, /* # */
{ 0, 0 }, /* $ */ { 0, 0 }, /* $ */
{ 0, 0 }, /* % */ { 0, 0 }, /* % */
...@@ -107,7 +108,7 @@ static const struct OCTET_STRING__jer_escape_table_s { ...@@ -107,7 +108,7 @@ static const struct OCTET_STRING__jer_escape_table_s {
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* QRSTUVWX */ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* QRSTUVWX */
{0,0},{0,0}, /* YZ */ {0,0},{0,0}, /* YZ */
{ 0, 0 }, /* [ */ { 0, 0 }, /* [ */
OSXET("\134\134"), /* \\ */ OSXBT("\\"), /* \\ */
}; };
static int static int
...@@ -299,7 +300,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b ...@@ -299,7 +300,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b
* Something like strtod(), but with stricter rules. * Something like strtod(), but with stricter rules.
*/ */
static int static int
OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { OS__strtoent(const char *buf, const char *end, int32_t *ret_value) {
const int32_t last_unicode_codepoint = 0x10ffff; const int32_t last_unicode_codepoint = 0x10ffff;
int32_t val = 0; int32_t val = 0;
const char *p; const char *p;
...@@ -310,19 +311,16 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { ...@@ -310,19 +311,16 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
switch(ch) { switch(ch) {
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
val = val * base + (ch - 0x30); val = val * 16 + (ch - 0x30);
break; break;
case 0x41: case 0x42: case 0x43: /* ABC */ case 0x41: case 0x42: case 0x43: /* ABC */
case 0x44: case 0x45: case 0x46: /* DEF */ case 0x44: case 0x45: case 0x46: /* DEF */
val = val * base + (ch - 0x41 + 10); val = val * 16 + (ch - 0x41 + 10);
break; break;
case 0x61: case 0x62: case 0x63: /* abc */ case 0x61: case 0x62: case 0x63: /* abc */
case 0x64: case 0x65: case 0x66: /* def */ case 0x64: case 0x65: case 0x66: /* def */
val = val * base + (ch - 0x61 + 10); val = val * 16 + (ch - 0x61 + 10);
break; break;
case 0x3b: /* ';' */
*ret_value = val;
return (p - buf) + 1;
default: default:
return -1; /* Character set error */ return -1; /* Character set error */
} }
...@@ -333,7 +331,7 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { ...@@ -333,7 +331,7 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
} }
} }
*ret_value = -1; *ret_value = val;
return (p - buf); return (p - buf);
} }
...@@ -371,7 +369,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -371,7 +369,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
buf = st->buf + st->size; buf = st->buf + st->size;
/* /*
* Convert series of 0 and 1 into the octet string. * Convert into the octet string.
*/ */
for(; p < pend; p++) { for(; p < pend; p++) {
int ch = *(const unsigned char *)p; int ch = *(const unsigned char *)p;
...@@ -392,21 +390,16 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -392,21 +390,16 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
; ;
const char *pval; /* Pointer to start of digits */ const char *pval; /* Pointer to start of digits */
int32_t val = 0; /* Entity reference value */ int32_t val = 0; /* Entity reference value */
int base;
if(len - 6 < 0) goto want_more;
if(len == 2 /* "&#" */) goto want_more; pval = p + 2;
if(p[2] == 0x78 /* 'x' */) len = OS__strtoent(pval, pval + 4, &val);
pval = p + 3, base = 16;
else
pval = p + 2, base = 10;
len = OS__strtoent(base, pval, p + len, &val);
if(len == -1) { if(len == -1) {
/* Invalid charset. Just copy verbatim. */ /* Invalid charset. Just copy verbatim. */
*buf++ = ch; *buf++ = ch;
continue; continue;
} }
if(!len || pval[len-1] != 0x3b) goto want_more; if(!len) goto want_more;
assert(val > 0);
p += (pval - p) + len - 1; /* Advance past entref */ p += (pval - p) + len - 1; /* Advance past entref */
if(val < 0x80) { if(val < 0x80) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment