From 53c34003661909bf2eb3384cc2a312011deb6173 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sat, 22 Apr 2017 08:35:53 -0400 Subject: [PATCH] Scribunto.Regex: If gsub_replace lua proc returns nothing, do not replace with empty string --- .../xowa/xtns/scribunto/libs/Scrib_lib_ustring.java | 10 +++++++--- .../scribunto/libs/Scrib_lib_ustring__gsub__tst.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java index ee64c45cf..254be2cc0 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring.java @@ -252,7 +252,8 @@ class Scrib_lib_ustring_gsub_mgr { if (limit > -1 && repl_count == limit) break; Regx_match rslt = rslts[i]; tmp_bfr.Add_str_u8(String_.Mid(text, pos, rslt.Find_bgn())); // NOTE: regx returns char pos (not bry); must add as String, not bry; DATE:2013-07-17 - Exec_repl_itm(tmp_bfr, repl_tid, repl_bry, text, rslt); + if (!Exec_repl_itm(tmp_bfr, repl_tid, repl_bry, text, rslt)) // will be false when gsub_proc returns nothing; PAGE:en.d:tracer DATE:2017-04-22 + break; pos = rslt.Find_end(); ++repl_count; } @@ -261,7 +262,7 @@ class Scrib_lib_ustring_gsub_mgr { tmp_bfr.Add_str_u8(String_.Mid(text, pos, text_len)); // NOTE: regx returns char pos (not bry); must add as String, not bry; DATE:2013-07-17 return tmp_bfr.To_str_and_clear(); } - private void Exec_repl_itm(Bry_bfr tmp_bfr, byte repl_tid, byte[] repl_bry, String text, Regx_match match) { + private boolean Exec_repl_itm(Bry_bfr tmp_bfr, byte repl_tid, byte[] repl_bry, String text, Regx_match match) { switch (repl_tid) { case Repl_tid_string: int len = repl_bry.length; @@ -346,7 +347,9 @@ class Scrib_lib_ustring_gsub_mgr { } } Keyval[] rslts = core.Interpreter().CallFunction(repl_func.Id(), luacbk_args); - if (rslts.length > 0) { // ArrayIndex check + if (rslts.length == 0) + return false; + else { // ArrayIndex check Object rslt_obj = rslts[0].Val(); // 0th idx has result tmp_bfr.Add_str_u8(Object_.Xto_str_strict_or_empty(rslt_obj)); // NOTE: always convert to String; rslt_obj can be int; PAGE:en.d:seven DATE:2016-04-27 } @@ -354,6 +357,7 @@ class Scrib_lib_ustring_gsub_mgr { } default: throw Err_.new_unhandled(repl_tid); } + return true; } private static final byte Repl_tid_null = 0, Repl_tid_string = 1, Repl_tid_table = 2, Repl_tid_luacbk = 3; public static final Scrib_lib_ustring_gsub_mgr[] Ary_empty = new Scrib_lib_ustring_gsub_mgr[0]; diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring__gsub__tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring__gsub__tst.java index 5e854926d..c84b8a0d1 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring__gsub__tst.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_ustring__gsub__tst.java @@ -59,6 +59,11 @@ public class Scrib_lib_ustring__gsub__tst { fxt.Init__cbk(proc); Exec_gsub("ab", ".", -1, proc.To_scrib_lua_proc(), "12;2"); // fails if "ab;4" } + @Test public void Replace__proc__empty() { // PURPOSE:if a proc returns null, do not replace anything; PAGE:en.d:tracer; DATE:2017-04-22 + Mock_proc__empty proc = new Mock_proc__empty(0); + fxt.Init__cbk(proc); + Exec_gsub("ab", ".", -1, proc.To_scrib_lua_proc(), "ab;0"); // fails if ";2" whic means each letter (".") replaced with null + } @Test public void Regx__int() { // PURPOSE: do not fail if integer is passed in for @regx; PAGE:en.d:λύω DATE:2014-09-02 Exec_gsub("abcd", 1 , -1, "A" , "abcd;0"); } @@ -112,3 +117,8 @@ class Mock_proc__number extends Mock_proc_fxt { private int counter = 0; return args; } } +class Mock_proc__empty extends Mock_proc_fxt { public Mock_proc__empty(int id) {super(id, "number");} + @Override public Keyval[] Exec_by_scrib(Keyval[] args) { + return Keyval_.Ary_empty; + } +}