diff --git a/400_xowa/src/gplx/langs/phps/Php_srl_parser.java b/400_xowa/src/gplx/langs/phps/Php_srl_parser.java index 3f3d79b82..c07ab5321 100644 --- a/400_xowa/src/gplx/langs/phps/Php_srl_parser.java +++ b/400_xowa/src/gplx/langs/phps/Php_srl_parser.java @@ -30,6 +30,7 @@ public class Php_srl_parser { return rv; } Keyval Xto_kv(Php_srl_itm_kv itm) { + if (itm == null) return null; Php_srl_itm itm_key = itm.Key(); Object key = itm_key == null ? null : itm_key.Val(); Php_srl_itm itm_val = itm.Val(); @@ -72,6 +73,13 @@ public class Php_srl_parser { for (int i = 0; i < subs_len; i++) { Php_srl_itm_kv kv = factory.Kv(); Php_srl_itm key_itm = Parse_itm(pos); + + // handle null kv; PAGE:en.w:Abziri DATE:2017-11-29 + if ( key_itm.Tid() == Php_srl_itm_.Tid_string + && String_.Eq(Php_srl_parser.NULL_ARRAY_ITEM, (String)key_itm.Val())) { + rv.Subs_add(null); + continue; + } kv.Key_(key_itm); Php_srl_itm val_itm = Parse_itm(pos); kv.Val_(val_itm); @@ -191,6 +199,7 @@ public class Php_srl_parser { String msg = String_.Format(fmt, args) + " " + Int_.To_str(bgn) + " " + String_.new_u8__by_len(raw, bgn, 20); return Err_.new_wo_type(msg); } + public static final String NULL_ARRAY_ITEM = "NULL_ARRAY_ITEM"; } class Php_srl_factory { public Php_srl_itm Nil() {return Php_srl_itm_nil.Nil;} diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_mock.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_mock.java index 27a93e764..4300f1e51 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_mock.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_mock.java @@ -63,6 +63,10 @@ public class Xot_invk_mock implements Xot_invk { int len = args.length; for (int i = 0; i < len; i++) { Keyval kv = args[i]; + + // handle null kv; PAGE:en.w:Abziri DATE:2017-11-29 + if (kv == null) continue; + String kv_key_str = kv.Key(); Object kv_key_obj = kv.Key_as_obj(); Arg_nde_tkn_mock nde_tkn = null; diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func_fxt.java b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func_fxt.java index 5377220ee..681e093c5 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func_fxt.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/Scrib_invoke_func_fxt.java @@ -228,8 +228,13 @@ class Scrib_lua_rsp_bldr { bfr.Add_str_a7("a:").Add_int_variable(len).Add_str_a7(":{"); for (int i = 0; i < len; i++) { Keyval kv = ary[i]; - Bld_obj(bfr, kv.Key_as_obj()); - Bld_obj(bfr, kv.Val()); + if (kv == null) { // handle null kv; PAGE:en.w:Abziri DATE:2017-11-29 + Bld_obj(bfr, gplx.langs.phps.Php_srl_parser.NULL_ARRAY_ITEM); + } + else { + Bld_obj(bfr, kv.Key_as_obj()); + Bld_obj(bfr, kv.Val()); + } } bfr.Add_byte(Byte_ascii.Curly_end); } diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java index 135cd7545..97b117640 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw.java @@ -388,6 +388,15 @@ class Scrib_lib_mw_callParserFunction_sorter implements gplx.core.lists.Comparer public int compare(Object lhsObj, Object rhsObj) { Keyval lhs = (Keyval)lhsObj; Keyval rhs = (Keyval)rhsObj; + + // handle null kv; PAGE:en.w:Abziri DATE:2017-11-29 + if (lhs == null && rhs == null) + return CompareAble_.Same; + else if (lhs == null) + return CompareAble_.More; + else if (rhs == null) + return CompareAble_.Less; + Object lhs_key = lhs.Key_as_obj(); Object rhs_key = rhs.Key_as_obj(); boolean lhs_is_int = Type_.Eq(lhs_key.getClass(), Int_.Cls_ref_type); diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw__invoke_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw__invoke_tst.java index bf18c63a8..20241ce69 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw__invoke_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_mw__invoke_tst.java @@ -87,6 +87,10 @@ public class Scrib_lib_mw__invoke_tst { fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "DISPLAYTITLE", "''a''"), ""); Tfds.Eq("a", String_.new_a7(fxt.Parser_fxt().Ctx().Page().Html_data().Display_ttl())); } + @Test public void CallParserFunction__null() { // PURPOSE.fix: null arg should not fail; PAGE:en.w:Abziri DATE:2017-11-29 + fxt.Init_page("{{#invoke:Mod_0|Prc_0}}"); + fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.flat_many_(1, "current", 2, "#coordinates", 3, Keyval_.Ary(Keyval_.int_(1, "a"), Keyval_.int_(3, "b"), null)), "");// failed with NullPointerException + } @Test public void ExpandTemplate_tmpl() { fxt.Init_page("{{#invoke:Mod_0|Prc_0}}"); fxt.Parser_fxt().Data_create("Template:A", "b{{{key1}}}c");