Skip to content

Commit fdfce8d

Browse files
committed
Web.JSON: Convert UTF-16 surrogate pairs.
1 parent 4f843c5 commit fdfce8d

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

autoload/vital/__vital__/Web/JSON.vim

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ function! s:_resolve(val, prefix) abort
7878
return a:val
7979
endfunction
8080

81-
8281
function! s:_vital_created(module) abort
8382
" define constant variables
8483
if !exists('s:const')
@@ -114,6 +113,10 @@ function! s:decode(json, ...) abort
114113
let json = join(split(json, "\n"), '')
115114
let json = substitute(json, '\\u34;', '\\"', 'g')
116115
let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:string.nr2enc_char("0x".submatch(1))', 'g')
116+
" convert surrogate pair
117+
let json = substitute(json, '\([\uD800-\uDBFF]\)\([\uDC00-\uDFFF]\)',
118+
\ '\=nr2char(0x10000+and(0x7ff,char2nr(submatch(1)))*0x400+and(0x3ff,char2nr(submatch(2))))',
119+
\ 'g')
117120
if settings.allow_nan
118121
let [NaN,Infinity] = [s:float_nan,s:float_inf]
119122
endif
@@ -122,7 +125,7 @@ function! s:decode(json, ...) abort
122125
while stridx(json, prefix) != -1
123126
let prefix .= '_'
124127
endwhile
125-
let [null,true,false] = map(['null','true','false'], 'prefix . v:val')
128+
let [null,true,false] = [prefix.'null',prefix.'true',prefix.'false']
126129
sandbox return s:_resolve(eval(json), prefix)
127130
else
128131
let [null,true,false] = [s:const.null(),s:const.true(),s:const.false()]

test/Web/JSON.vimspec

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Describe Web.JSON
3636
Assert Equals(JSON.decode('"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"'), "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f")
3737
" multibyte
3838
Assert Equals(JSON.decode('"s¢cĴgё"'), "s¢cĴgё")
39+
" UTF-16 surrogate pair
40+
Assert Equals(JSON.decode('"\ud83c\udf63"'), "\xf0\x9f\x8d\xa3")
41+
" unpaired UTF-16 surrogate
42+
Assert Equals(JSON.decode('"\ud83c\u00a0"'), "\ud83c\u00a0")
3943
End
4044

4145
It decodes strings with character encoding
@@ -132,6 +136,8 @@ Describe Web.JSON
132136
Assert Equals(JSON.encode("\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"), '"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"')
133137
" multibyte
134138
Assert Equals(JSON.encode("s¢cĴgё"), '"s¢cĴgё"')
139+
" UTF-16 surrogate pair
140+
Assert Equals(JSON.encode("\xf0\x9f\x8d\xa3"), "\"\xf0\x9f\x8d\xa3\"")
135141
End
136142

137143
It encodes strings with character encoding

0 commit comments

Comments
 (0)