1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Language: Escape left-to-right / right-to-left marks in names.json ('\xE2\x80\x8E' to '\u200E') [#501]

This commit is contained in:
gnosygnu
2019-06-23 21:35:21 -04:00
parent d4a28d3ffe
commit 5d886501e8
12 changed files with 326 additions and 45 deletions

View File

@@ -14,9 +14,12 @@ GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.langs.jsons; import gplx.*; import gplx.langs.*;
import gplx.objects.strings.unicodes.*;
import gplx.core.encoders.*;
public class Json_doc_wtr {
private int indent = -2;
private Bry_bfr bfr = Bry_bfr_.Reset(255);
public void Opt_unicode_y_() {opt_unicode = true;} private boolean opt_unicode;
public Json_doc_wtr Indent() {return Indent(indent);}
private Json_doc_wtr Indent(int v) {if (v > 0) bfr.Add_byte_repeat(Byte_ascii.Space, v); return this;}
public Json_doc_wtr Indent_add() {indent += 2; return this;}
@@ -31,11 +34,59 @@ public class Json_doc_wtr {
bfr.Add(Object_.Bry__null);
else {
bfr.Add_byte(Byte_ascii.Quote);
bfr.Add_bry_escape(Byte_ascii.Quote, Escaped__quote, v, 0, v.length);
if (opt_unicode) {
Ustring ustr = Ustring_.New_codepoints(String_.new_u8(v));
int ustr_len = ustr.Len_in_data();
for (int i = 0; i < ustr_len; i++) {
int cp = ustr.Get_data(i);
Write_str_codepoint(bfr, cp);
}
}
else {
bfr.Add_bry_escape(Byte_ascii.Quote, Escaped__quote, v, 0, v.length);
}
bfr.Add_byte(Byte_ascii.Quote);
}
return this;
}
private void Write_str_codepoint(Bry_bfr bfr, int val) {
switch (val) { // REF: https://www.json.org/
case Byte_ascii.Quote:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Quote);
break;
case Byte_ascii.Backslash:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Backslash);
break;
case Byte_ascii.Backfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_b);
break;
case Byte_ascii.Formfeed:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_f);
break;
case Byte_ascii.Nl:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_n);
break;
case Byte_ascii.Cr:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_r);
break;
case Byte_ascii.Tab:
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_t);
break;
default:
if ( val < Byte_ascii.Space // control characters
|| val == 160 // nbsp
|| val == 8206 // left to right
|| val == 8207 // right to left
) {
// convert to \u1234
bfr.Add_byte_backslash().Add_byte(Byte_ascii.Ltr_u).Add_str_a7(Hex_utl_.To_str(val, 4));
}
else {
bfr.Add_u8_int(val);
}
break;
}
}
public Json_doc_wtr Int(int v) {bfr.Add_int_variable(v); return this;}
public Json_doc_wtr Double(double v) {bfr.Add_double(v); return this;}
public Json_doc_wtr Comma() {Indent(); bfr.Add_byte(Byte_ascii.Comma).Add_byte_nl(); return this;}

View File

@@ -25,6 +25,19 @@ public class Json_doc_wtr_tst {
, " 'k1':'v\\\"1'"
, "}"));
}
@Test public void Quotes() {
fxt.Test__string__quotes("a\"z" , "a\\\"z");
fxt.Test__string__quotes("a\u0008z" , "a\\bz");
fxt.Test__string__quotes("a\fz" , "a\\fz");
fxt.Test__string__quotes("a\nz" , "a\\nz");
fxt.Test__string__quotes("a\rz" , "a\\rz");
fxt.Test__string__quotes("a\tz" , "a\\tz");
fxt.Test__string__quotes("aēz" , "aēz");
fxt.Test__string__quotes("az" , "a\\u000Fz");
fxt.Test__string__quotes("a z" , "a\\u00A0z");
fxt.Test__string__quotes("az" , "a\\u200Ez");
fxt.Test__string__quotes("az" , "a\\u200Fz");
}
}
class Json_doc_wtr_fxt {
public Json_doc_wtr Exec__Kv_simple(String key, String val) {
@@ -40,4 +53,12 @@ class Json_doc_wtr_fxt {
public String Exec__Concat_apos(String... ary) {
return Json_doc.Make_str_by_apos(ary);
}
public void Test__string__quotes(String raw, String expd) {
Json_doc_wtr doc_wtr = new Json_doc_wtr();
doc_wtr.Opt_unicode_y_();
doc_wtr.Str(Bry_.new_u8(raw));
String actl = doc_wtr.Bld_as_str();
actl = String_.Mid(actl, 1, String_.Len(actl) - 1);
Gftest.Eq__str(expd, actl);
}
}