Skip to content

Commit 5fa960d

Browse files
committed
updated with utils.c
1 parent 7ceda50 commit 5fa960d

File tree

2 files changed

+116
-2
lines changed

2 files changed

+116
-2
lines changed

jsonwriter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
#include <stdio.h>
2+
#include <string.h>
13
#include <jsonwriter.h>
2-
#include <scan.h>
4+
5+
#ifdef INCLUDE_UTILS
6+
#include "utils.c"
7+
#endif
38

49
#define JSONWRITER_MAX_NESTING 256
510
struct jsonwriter_data {
@@ -198,4 +203,3 @@ int jsonwriter_start_object(jsonwriter_handle h) {
198203
int jsonwriter_start_array(jsonwriter_handle h) {
199204
return jsonwriter_go_deeper((struct jsonwriter_data *)h, '[', ']');
200205
}
201-

utils.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
void str2hex(char *to, const unsigned char *p, size_t len) {
2+
static const char *hex = "0123456789abcdef";
3+
4+
for (; len--; p++) {
5+
*to++ = hex[p[0] >> 4];
6+
*to++ = hex[p[0] & 0x0f];
7+
}
8+
}
9+
10+
static char UTF8_charLenC(int firstChar) { /* return 0 on eof, -1 on error, > 0 if char read) */
11+
char len;
12+
if(firstChar == EOF) len = 0;
13+
else if(!(firstChar & 128)) len = 1;
14+
else if((firstChar & 224) == 192) len = 2; /* 110xxxxx */
15+
else if((firstChar & 240) == 224) len = 3; /* 1110xxxx */
16+
else if((firstChar & 248) == 240) len = 4; /* 11110xxx */
17+
else if((firstChar & 252) == 248) len = 5; /* 111110xx */
18+
else if((firstChar & 254) == 252) len = 6; /* 1111110x */
19+
else len = -1; /* error */
20+
return len;
21+
}
22+
23+
#define JSON_ESC_CHAR(c) (c == '"' || c == '\\' || c < 32)
24+
25+
static unsigned int json_esc1(const char *s, unsigned int slen,
26+
unsigned int *replacelen,
27+
char replace[], // replace buff should be at least 8 bytes long
28+
const char **new_s,
29+
size_t max_output_size) {
30+
unsigned char c;
31+
char c_len;
32+
const char *orig_s = s;
33+
34+
if(!max_output_size) {
35+
*new_s = s + slen;
36+
*replacelen = 0;
37+
return 0;
38+
}
39+
40+
while(slen && (c = (unsigned char)*s) && (size_t)(s - orig_s) < max_output_size) {
41+
c_len = UTF8_charLenC(*s);
42+
43+
if(c_len > 0 && ((unsigned char)c_len > slen || (size_t)((s - orig_s) + c_len) > max_output_size))
44+
break; // roll back and return
45+
46+
if(c_len > 1) {
47+
s += c_len;
48+
slen -= c_len;
49+
continue;
50+
} else if(c_len < 0) { // bad utf8
51+
*replacelen = 0;
52+
*new_s = s + 1;
53+
return (unsigned int)(s - orig_s);
54+
} else if(JSON_ESC_CHAR(c)) {
55+
char hex = 0;
56+
switch(c) {
57+
case '"':
58+
replace[1] = '"';
59+
break;
60+
case '\\':
61+
replace[1] = '\\';
62+
break;
63+
case '\b':
64+
replace[1] = 'b';
65+
break;
66+
case '\f':
67+
replace[1] = 'f';
68+
break;
69+
case '\n':
70+
replace[1] = 'n';
71+
break;
72+
case '\r':
73+
replace[1] = 'r';
74+
break;
75+
case '\t':
76+
replace[1] = 't';
77+
break;
78+
default:
79+
hex=1;
80+
}
81+
82+
replace[0] = '\\';
83+
if(hex) {
84+
// unicode-hex: but 2/3 are not always zeroes...
85+
replace[1] = 'u';
86+
replace[2] = '0';
87+
replace[3] = '0';
88+
str2hex(replace+4, &c, 1);
89+
*replacelen = 6;
90+
replace[6] = '\0';
91+
} else {
92+
*replacelen = 2;
93+
replace[2] = '\0';
94+
}
95+
96+
if((size_t)((s - orig_s) + *replacelen) > max_output_size) {
97+
*replacelen = 0; // roll back and return
98+
break;
99+
}
100+
101+
*new_s = s+1;
102+
return (unsigned int)(s - orig_s);
103+
}
104+
s++, slen--;
105+
}
106+
107+
*replacelen = 0;
108+
*new_s = s;
109+
return (unsigned int)(s - orig_s);
110+
}

0 commit comments

Comments
 (0)