From 8501ec6fd83b0f23b58903ac2ea2df558d4a5f52 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Sat, 1 Apr 2017 17:06:41 -0400 Subject: [PATCH] Parser.Time: Ignore multiple years / multiple days when parsing date for #time function --- .../times/Pft_func_time__uncommon__tst.java | 4 ++- .../xowa/xtns/pfuncs/times/Pxd_eval_seg.java | 5 ++-- .../xowa/xtns/pfuncs/times/Pxd_itm_int.java | 26 +++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time__uncommon__tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time__uncommon__tst.java index 3310a12e8..2493a5130 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time__uncommon__tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pft_func_time__uncommon__tst.java @@ -19,5 +19,7 @@ public class Pft_func_time__uncommon__tst { private final Xop_fxt fxt = new Xop_fxt(); @Before public void init() {fxt.Reset(); Datetime_now.Manual_(DateAdp_.new_(2012, 1, 2, 3, 4, 5, 6));} @After public void term() {Datetime_now.Manual_n_();} - @Test public void Year_5_digits() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|00123-4-5}}" , "{{test}}" , "2003-04-05");} // PURPOSE: emulate PHP's incorrect date parsing; EX:ca.w:Nicolau_de_Mira; DATE:2014-04-17 + @Test public void Year__5_digits() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|00123-4-5}}" , "{{test}}" , "2003-04-05");} // PURPOSE: emulate PHP's incorrect date parsing; EX:ca.w:Nicolau_de_Mira; DATE:2014-04-17 + @Test public void Year__multiple() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|12 November 2016 2008}}" , "{{test}}" , "2016-11-12");} // PURPOSE: multiple years should take 1st, not last; EX:en.w:Antipas,_Cotabato; DATE:2017-04-01 + @Test public void Day__multiple() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|2 12 November 2016}}" , "{{test}}" , "Invalid month: 12");} // PURPOSE: multiple days should generate error, not create a real date; EX:en.w:Antipas,_Cotabato; DATE:2017-04-01 } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_eval_seg.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_eval_seg.java index 6965c6763..193cd1c5f 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_eval_seg.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_eval_seg.java @@ -86,8 +86,9 @@ class Pxd_eval_seg { int val = itm.Val(); switch (itm.Digits()) { case 1: - case 2: - if (val > -1 && val < 13) { + case 2: + if ( val > -1 && val < 13 // val is between 0 and 12; possible month; + && tctx.Seg_idxs()[DateAdp_.SegIdx_month] == Pxd_itm_base.Seg_idx_null) { // month is empty; needed else multiple access-date errors in references; PAGE:en.w:Template:Date; en.w:Antipas,_Cotabato; EX:"2 12 November 2016" DATE:2017-04-01 tctx.Seg_idxs_(itm, DateAdp_.SegIdx_month); return true; } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_itm_int.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_itm_int.java index 14b27c4dd..bebd7f88f 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_itm_int.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/times/Pxd_itm_int.java @@ -83,12 +83,28 @@ class Pxd_itm_int extends Pxd_itm_base implements Pxd_itm_int_interface { val = 2000 + (val % 10); // NOTE: emulate PHP's incorrect behavior with 5 digit years; EX:ca.w:Nicolau_de_Mira; DATE:2014-04-18 tctx.Seg_idxs_(this, DateAdp_.SegIdx_year); break; - case 4: // 4 digits; assume year + case 4: + // 4 digits; assume year switch (data_idx) { - case 0: Pxd_eval_year.Eval_at_pos_0(tctx, this); break; // year at pos 0; EX: 2001-02-03 - case 1: tctx.Err_set(Pft_func_time_log.Invalid_year_mid); return false;// year at pos 1; invalid; EX: 02-2003-03 - case 2: Pxd_eval_year.Eval_at_pos_2(tctx, this); break; // year at pos 2; EX: 02-03-2001 - default: Pxd_eval_year.Eval_at_pos_n(tctx, this); break; // year at pos n; EX: 04:05 02-03-2001 + // year at pos 0; EX: 2001-02-03 + case 0: Pxd_eval_year.Eval_at_pos_0(tctx, this); break; + // year at pos 1; invalid; EX: 02-2003-03 + case 1: tctx.Err_set(Pft_func_time_log.Invalid_year_mid); return false; + // year at pos 2; EX: 02-03-2001 + case 2: Pxd_eval_year.Eval_at_pos_2(tctx, this); break; + // year at pos 3 or more + default: + // if year already exists, ignore; needed else multiple access-date errors in references; PAGE:en.w:Template:Date; en.w:Antipas,_Cotabato; EX:"12 November 2016 2008" DATE:2017-04-01 + if (tctx.Seg_idxs()[DateAdp_.SegIdx_year] != Pxd_itm_base.Seg_idx_null + ) { + this.Seg_idx_(Seg_idx_skip); + return true; + } + // try to evaluate year at pos n; EX: 04:05 02-03-2001 + else { + Pxd_eval_year.Eval_at_pos_n(tctx, this); + } + break; } tctx.Seg_idxs_(this, DateAdp_.SegIdx_year); break;