aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Lehtinen <petri@digip.org>2009-07-04 22:02:16 +0300
committerPetri Lehtinen <petri@digip.org>2009-07-09 20:59:52 +0300
commit6b14df13cc1b453d0cc277d0ba50cbabc2745089 (patch)
tree9da899e230d896bfa4dc4766e9e0f142f858d314
parentf9c2a113bb09a4ccff3f7ba92d639ad3b40ee693 (diff)
downloadjansson-6b14df13cc1b453d0cc277d0ba50cbabc2745089.zip
jansson-6b14df13cc1b453d0cc277d0ba50cbabc2745089.tar.gz
jansson-6b14df13cc1b453d0cc277d0ba50cbabc2745089.tar.bz2
Fix dumping of Unicode control codes
Inside strings, All UTF-8 characters except for \, " and Unicode control codes are dumped as-is. The control codes that have a special one-character escape use that escape, and other control codes are dumped using the \uXXXX escape.
-rw-r--r--src/dump.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/dump.c b/src/dump.c
index 02692f7..b8bd460 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -66,27 +66,47 @@ static int dump_string(const char *str, dump_func dump, void *data)
return -1;
end = str;
- while(*end)
+ while(1)
{
- while(*end && *end != '\\' && *end != '"')
+ const char *text;
+ char seq[7];
+ int length;
+
+ while(*end && *end != '\\' && *end != '"' && (*end < 0 || *end > 0x1F))
end++;
- if(end != str)
+ if(end != str) {
if(dump(str, end - str, data))
return -1;
-
- if(*end == '\\')
- {
- if(dump("\\\\", 2, data))
- return -1;
- end++;
}
- else if(*end == '"')
+
+ if(!*end)
+ break;
+
+ /* handle \, ", and control codes */
+ length = 2;
+ switch(*end)
{
- if(dump("\\\"", 2, data))
- return -1;
- end++;
+ case '\\': text = "\\\\"; break;
+ case '\"': text = "\\\""; break;
+ case '\b': text = "\\b"; break;
+ case '\f': text = "\\f"; break;
+ case '\n': text = "\\n"; break;
+ case '\r': text = "\\r"; break;
+ case '\t': text = "\\t"; break;
+ default:
+ {
+ sprintf(seq, "\\u00%02x", *end);
+ text = seq;
+ length = 6;
+ break;
+ }
}
+
+ if(dump(text, length, data))
+ return -1;
+
+ end++;
str = end;
}