From c67970b5b921d44785776d3e90618f6d6f1831b6 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sun, 13 Oct 2019 11:30:40 -0400 Subject: [PATCH] Parser: Do not assume that Name_ui_w_colon matches Name [#594] --- .../gplx/xowa/parsers/tmpls/Xot_invk_tkn.java | 6 ++--- .../xowa/wikis/data/tbls/Xowd_page_itm.java | 9 ++++--- .../wikis/data/tbls/Xowd_page_itm_tst.java | 3 ++- .../src/gplx/xowa/wikis/nss/Xow_ns_mgr.java | 19 +++++--------- .../xowa/wikis/nss/Xow_ns_mgr_name_itm.java | 26 +++++++++++++++++++ 5 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr_name_itm.java diff --git a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java index 2a629ec84..88892daa4 100644 --- a/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java +++ b/400_xowa/src/gplx/xowa/parsers/tmpls/Xot_invk_tkn.java @@ -108,7 +108,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk { name_bgn = 0; } - Object ns_eval = wiki.Ns_mgr().Names_get_w_colon(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia + Xow_ns_mgr_name_itm ns_eval = wiki.Ns_mgr().Names_get_w_colon_or_null(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia if (ns_eval != null && !template_prefix_found) // do not transclude ns if Template prefix seen earlier; EX: {{Template:Wikipedia:A}} should not transclude "Wikipedia:A"; DATE:2013-04-03 return SubEval(ctx, wiki, bfr, name_ary, caller, src); @@ -156,9 +156,9 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk { else { // colon present; name_ary = Bry_.Mid(name_ary, finder_subst_end + 1, name_ary_len); // chop off "raw"; +1 is for ":"; note that +1 is in bounds b/c raw_colon was found name_ary_len = name_ary.length; - Object ns_eval2 = wiki.Ns_mgr().Names_get_w_colon(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia + Xow_ns_mgr_name_itm ns_eval2 = wiki.Ns_mgr().Names_get_w_colon_or_null(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia if (ns_eval2 != null) { - Xow_ns ns_eval_itm = (Xow_ns)ns_eval2; + Xow_ns ns_eval_itm = ns_eval2.Ns(); int pre_len = ns_eval_itm.Name_enc().length; if (pre_len < name_ary_len && name_ary[pre_len] == Byte_ascii.Colon) return SubEval(ctx, wiki, bfr, name_ary, caller, src); diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm.java index 6bb5f466f..37d82417c 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm.java @@ -102,14 +102,15 @@ public class Xowd_page_itm { } public Xowd_page_itm Ttl_(byte[] v, Xow_ns_mgr ns_mgr) { ttl_full_db = v; - Object o = ns_mgr.Names_get_w_colon(v, 0, v.length); - if (o == null) { + Xow_ns_mgr_name_itm name_itm = ns_mgr.Names_get_w_colon_or_null(v, 0, v.length); + if (name_itm == null) { ns = ns_mgr.Ns_main(); ttl_page_db = v; } else { - ns = (Xow_ns)o; - ttl_page_db = Bry_.Mid(v, ns.Name_ui_w_colon().length, v.length); // EX: "Template:A" -> "Template:" + "A" + ns = name_itm.Ns(); + byte[] ns_name_bry = name_itm.Name(); + ttl_page_db = Bry_.Mid(v, ns_name_bry.length + 1, v.length); // EX: "Template:A" -> "Template:" + "A" } ns_id = ns.Id(); return this; diff --git a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm_tst.java b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm_tst.java index d51907c24..faa27abc1 100644 --- a/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm_tst.java +++ b/400_xowa/src/gplx/xowa/wikis/data/tbls/Xowd_page_itm_tst.java @@ -23,6 +23,7 @@ public class Xowd_page_itm_tst { } } class Xowd_page_itm_fxt { + private Xow_ns_mgr ns_mgr; Xowd_page_itm tmp_page; public void Init() { if (ns_mgr == null) { ns_mgr = new Xow_ns_mgr(gplx.xowa.langs.cases.Xol_case_mgr_.A7()); @@ -31,7 +32,7 @@ class Xowd_page_itm_fxt { ns_mgr.Init_w_defaults(); tmp_page = new Xowd_page_itm(); } - } private Xow_ns_mgr ns_mgr; Xowd_page_itm tmp_page; + } public void Test_ttl_(String ttl, int expd_ns, String expd_ttl) { tmp_page.Ttl_(Bry_.new_a7(ttl), ns_mgr); Tfds.Eq(expd_ns, tmp_page.Ns_id()); diff --git a/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr.java b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr.java index 92f88f986..5a9315c5f 100644 --- a/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr.java @@ -68,11 +68,12 @@ public class Xow_ns_mgr implements Gfo_invk, gplx.core.lists.ComparerAble { Xow_ns rv = this.Names_get_or_null(name_bry, 0, name_bry.length); return rv == null ? this.Ns_main() : rv; } - public Object Names_get_w_colon(byte[] src, int bgn, int end) { // NOTE: get ns for a name with a ":"; EX: "Template:A" should return "Template" ns + public Xow_ns_mgr_name_itm Names_get_w_colon_or_null(byte[] src, int bgn, int end) { // NOTE: get ns for a name with a ":"; EX: "Template:A" should return "Template" ns int colon_pos = Bry_find_.Find_fwd(src, Byte_ascii.Colon, bgn, end); - if (colon_pos == Bry_find_.Not_found) return null; // name does not have ":"; return; - Object rv = name_hash.Get_by_mid(src, bgn, colon_pos); - return rv == null ? null : ((Xow_ns_mgr_name_itm)rv).Ns(); + return (colon_pos == Bry_find_.Not_found) + ? (Xow_ns_mgr_name_itm)null // name does not have ":"; return null; + : (Xow_ns_mgr_name_itm)name_hash.Get_by_mid(src, bgn, colon_pos) // NOTE: can return NULL + ; } public int Tmpls_get_w_colon(byte[] src, int bgn, int end) { // NOTE: get length of template name with a ":"; EX: "Template:A" returns 10; PERF int colon_pos = Bry_find_.Find_fwd(src, Byte_ascii.Colon, bgn, end); @@ -128,7 +129,7 @@ public class Xow_ns_mgr implements Gfo_invk, gplx.core.lists.ComparerAble { ns.Name_bry_(Bry_.Replace(ns_name, Project_talk_fmt_arg, project_ns.Name_db())); } private static final byte[] Project_talk_fmt_arg = Bry_.new_a7("$1"); private void Rebuild_hashes__add(Hash_adp_bry hash, Xow_ns ns, byte[] key) { - Xow_ns_mgr_name_itm ns_itm = new Xow_ns_mgr_name_itm(key, ns); + Xow_ns_mgr_name_itm ns_itm = new Xow_ns_mgr_name_itm(ns, key); hash.Add_if_dupe_use_nth(key, ns_itm); if (Bry_find_.Find_fwd(key, Byte_ascii.Underline) != Bry_find_.Not_found) // ns has _; add another entry for space; EX: Help_talk -> Help talk hash.Add_if_dupe_use_nth(Bry_.Replace(key, Byte_ascii.Underline, Byte_ascii.Space), ns_itm); @@ -164,7 +165,7 @@ public class Xow_ns_mgr implements Gfo_invk, gplx.core.lists.ComparerAble { if (!id_hash.Has(id_hash_ref.Val_(ns_id))) // NOTE: do not add if already exists; avoids alias id_hash.Add(Int_obj_ref.New(ns.Id()), ns); } - name_hash.Add_if_dupe_use_nth(ns.Name_db(), new Xow_ns_mgr_name_itm(ns.Name_db(), ns)); + name_hash.Add_if_dupe_use_nth(ns.Name_db(), new Xow_ns_mgr_name_itm(ns, ns.Name_db())); return this; } public int compare(Object lhsObj, Object rhsObj) { @@ -235,12 +236,6 @@ public class Xow_ns_mgr implements Gfo_invk, gplx.core.lists.ComparerAble { bfr.Add(ttl); return bfr.To_bry_and_clear(); } - class Xow_ns_mgr_name_itm { - public Xow_ns_mgr_name_itm(byte[] name, Xow_ns ns) {this.name = name; this.name_len = name.length; this.ns = ns;} - public byte[] Name() {return name;} private byte[] name; - public int Name_len() {return name_len;} private int name_len; - public Xow_ns Ns() {return ns;} private Xow_ns ns; - } public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_clear)) this.Clear(); // NOTE: called by /xowa/bin/any/xowa/cfg/wiki/core/*.gfs for (a) aliases; (b) Subpages_enabled diff --git a/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr_name_itm.java b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr_name_itm.java new file mode 100644 index 000000000..0ad5d522e --- /dev/null +++ b/400_xowa/src/gplx/xowa/wikis/nss/Xow_ns_mgr_name_itm.java @@ -0,0 +1,26 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +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.xowa.wikis.nss; import gplx.*; import gplx.xowa.*; import gplx.xowa.wikis.*; +public class Xow_ns_mgr_name_itm { + public Xow_ns_mgr_name_itm(Xow_ns ns, byte[] name) { + this.ns = ns; + this.name = name; + this.name_len = name.length; + } + public Xow_ns Ns() {return ns;} private final Xow_ns ns; + public byte[] Name() {return name;} private final byte[] name; + public int Name_len() {return name_len;} private final int name_len; +}