aboutsummaryrefslogtreecommitdiffhomepage
path: root/common
diff options
context:
space:
mode:
authorGravatar kwkam <mailsende@gmail.com>2016-02-06 14:57:00 +0800
committerGravatar wm4 <wm4@nowhere>2016-02-06 22:54:49 +0100
commit3314483a022faf4ea7c4b56192306da5a1ce811a (patch)
tree4e258cb90f4180b3f5e7f074dedad57b14394fc9 /common
parent563b4785dab5b4f12ffa6c29161eeb61168553e4 (diff)
common/common.c: handle utf16 in mp_parse_escape
Signed-off-by: wm4 <wm4@nowhere>
Diffstat (limited to 'common')
-rw-r--r--common/common.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/common/common.c b/common/common.c
index d77e188a24..41647b3450 100644
--- a/common/common.c
+++ b/common/common.c
@@ -187,9 +187,20 @@ static bool mp_parse_escape(void *talloc_ctx, bstr *dst, bstr *code)
}
if (code->start[0] == 'u' && code->len >= 5) {
bstr num = bstr_splice(*code, 1, 5);
- int c = bstrtoll(num, &num, 16);
+ uint32_t c = bstrtoll(num, &num, 16);
if (num.len)
return false;
+ if (c >= 0xd800 && c <= 0xdbff) {
+ if (code->len < 5 + 6 // udddd + \udddd
+ || code->start[5] != '\\' || code->start[6] != 'u')
+ return false;
+ *code = bstr_cut(*code, 5 + 1);
+ bstr num2 = bstr_splice(*code, 1, 5);
+ uint32_t c2 = bstrtoll(num2, &num2, 16);
+ if (num2.len || c2 < 0xdc00 || c2 > 0xdfff)
+ return false;
+ c = ((c - 0xd800) << 10) + 0x10000 + (c2 - 0xdc00);
+ }
mp_append_utf8_bstr(talloc_ctx, dst, c);
*code = bstr_cut(*code, 5);
return true;