diff --git a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr.java b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr.java index 9d568426b..640c1c5cf 100644 --- a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr.java +++ b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr.java @@ -144,7 +144,6 @@ public class Http_server_wkr implements Gfo_invk { page_html = String_.Replace(page_html, "/site" , ""); return page_html; } - public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Invk_run)) {this.Run();} else return Gfo_invk_.Rv_unhandled; diff --git a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack_.java b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack_.java new file mode 100644 index 000000000..c6706f0d0 --- /dev/null +++ b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack_.java @@ -0,0 +1,141 @@ +/* +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.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*; +import gplx.core.btries.*; +class Http_server_wkr_fsys_hack_ { + private static final byte[] + Bry__file_lhs = Bry_.new_a7("file:///") + , Bry__file_fsys = Bry_.new_a7("/fsys") + ; + private static final Btrie_slim_mgr xowa_path_segment_trie = Btrie_slim_mgr.ci_a7() + .Add_many_str + ( "/file/" // most files EX: file:////home/lnxusr/xowa/file/en.wikipedia.org/7/0/A.png + , "/user/anonymous/" // wiki css; EX: url(file:///c:/xowa/user/anonymous/wiki/www.wikidata.org/html/logo.png) + , "/bin/any/" // app resources; EX: file:///c:/xowa/bin/any/xowa/file/app.window/app_icon.png + ) + ; + public static byte[] Replace(byte[] html_bry) { + // init + Bry_bfr bfr = Bry_bfr_.New(); + int len = html_bry.length; + int pos = 0; + + // loop while finding root_dir_http + while (true) { + // find "file:///" + int file_bgn = Bry_find_.Find_fwd(html_bry, Bry__file_lhs, pos); + + // exit if nothing found + if (file_bgn == Bry_find_.Not_found) + break; + + // set file_end (after "file:///") + int file_end = file_bgn + Bry__file_lhs.length; + + // skip if page literally starts with "file:" + if (file_bgn == 0) { + bfr.Add_mid(html_bry, pos, file_end); + pos = file_end; + continue; + } + + // get quote_bgn char before "file:///" + int quote_bgn = file_bgn - 1; + byte quote_bgn_char = html_bry[quote_bgn]; + byte quote_end_char = Byte_ascii.Null; + boolean quote_is_ws = false; + + // get quote_end char + switch (quote_bgn_char) { + case Byte_ascii.Apos: // EX: 'file:///...' + case Byte_ascii.Quote: // EX: "file:///..." + quote_end_char = quote_bgn_char; + break; + case Byte_ascii.Paren_bgn: // EX: url(file:///...) + quote_end_char = Byte_ascii.Paren_end; + break; + case Byte_ascii.Space: // EX: '\sfile:///...\n'; NOTE: don't know if this is needed, but just in case it's in TemplateStyles.css + case Byte_ascii.Tab: + case Byte_ascii.Nl: + case Byte_ascii.Cr: + quote_is_ws = true; + quote_end_char = quote_bgn_char; + break; + default: + break; + } + + // preceding char is not supported; exit; EX: '!file:///' + if (quote_end_char == Byte_ascii.Null) { + bfr.Add_mid(html_bry, pos, file_end); + pos = file_end; + continue; + } + + // find quote_end + int quote_end = + quote_is_ws + ? Bry_find_.Find_fwd_until_ws(html_bry, file_end, len) + : Bry_find_.Find_fwd (html_bry, quote_end_char, file_end); + + // exit if no quote_end + if (quote_end == Bry_find_.Not_found) + break; + + // skip if "'file: ... '" is too long. should be no more than 300 + if (quote_end - file_end > 300) { + bfr.Add_mid(html_bry, pos, quote_end); + pos = quote_end; + continue; + } + + // loop chars between quote_bgn and quote_end and must have one of segments defined above; "/file/", "/bin/any/", "/user/anonymous/" + int mid_bgn = Bry_find_.Not_found; + Btrie_rv trv = new Btrie_rv(); + for (int i = quote_bgn; i < quote_end; i++) { + byte b = html_bry[i]; + Object o = xowa_path_segment_trie.Match_at_w_b0(trv, b, html_bry, i, quote_end); + if (o != null) { + mid_bgn = i; + break; + } + } + + // skip if no xowa_path_segment found + if (mid_bgn == -1) { + bfr.Add_mid(html_bry, pos, quote_end); + pos = quote_end; + continue; + } + + // add everything up to xowa_path_segment + bfr.Add_mid(html_bry, pos, file_bgn); + + // add "/fsys/" + bfr.Add(Bry__file_fsys); + + // add everything up to quote_end + bfr.Add_mid(html_bry, mid_bgn, quote_end); + + // move pos forward + pos = quote_end; + } + + // add rest + bfr.Add_mid(html_bry, pos, len); + return bfr.To_bry_and_clear(); + } +} diff --git a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack__tst.java b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack__tst.java new file mode 100644 index 000000000..07e9a591f --- /dev/null +++ b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_fsys_hack__tst.java @@ -0,0 +1,63 @@ +/* +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.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*; +import org.junit.*; import gplx.core.tests.*; +public class Http_server_wkr_fsys_hack__tst { + private final Http_server_wkr_fsys_hack__fxt fxt = new Http_server_wkr_fsys_hack__fxt(); + @Test public void File_bgn_missing() { // "file:" missing + fxt.Test__Replace_fsys_hack("src='file////home/lnxusr/xowa/file/'"); + } + @Test public void File_bgn_at_bos() { // "file:" at start of page + fxt.Test__Replace_fsys_hack("file:////home/lnxusr/xowa/file/"); + } + @Test public void Quote_bgn_missing() { + fxt.Test__Replace_fsys_hack(""); + } + @Test public void Quote_end_missing() { + fxt.Test__Replace_fsys_hack("a'file:////home/lnxusr/xowa/file/"); + } + @Test public void Too_long() { // skip if too long + fxt.Test__Replace_fsys_hack("'file:" + String_.Repeat("a", 301) + "'"); + } + @Test public void File_mid_missing() { // skip if no /file/ + fxt.Test__Replace_fsys_hack("'file:////home/lnxusr/xowa/file_missing/'"); + } + @Test public void File__one() { + fxt.Test__Replace_fsys_hack("'file:////home/lnxusr/xowa/file/A.png'", "'/fsys/file/A.png'"); + } + @Test public void File__many() { + fxt.Test__Replace_fsys_hack("a 'file:////home/lnxusr/xowa/file/A.png' b 'file:////home/lnxusr/xowa/file/B.png' c", "a '/fsys/file/A.png' b '/fsys/file/B.png' c"); + } + @Test public void Quote() { + fxt.Test__Replace_fsys_hack("a \"file:////home/lnxusr/xowa/file/A.png\" b", "a \"/fsys/file/A.png\" b"); + } + @Test public void Ws() { + fxt.Test__Replace_fsys_hack("a file:////home/lnxusr/xowa/file/A.png\nb", "a /fsys/file/A.png\nb"); + } + @Test public void Bin_any() { + fxt.Test__Replace_fsys_hack("a 'file:///C:/xowa/bin/any/xowa/file/app.window/app_icon.png' b", "a '/fsys/bin/any/xowa/file/app.window/app_icon.png' b"); + } + @Test public void Url() { + fxt.Test__Replace_fsys_hack("url(file:///C:/xowa/user/anonymous/wiki/en.wikipedia.org/html/logo.png)", "url(/fsys/user/anonymous/wiki/en.wikipedia.org/html/logo.png)"); + } +} +class Http_server_wkr_fsys_hack__fxt { + public void Test__Replace_fsys_hack(String html) {Test__Replace_fsys_hack(html, html);} + public void Test__Replace_fsys_hack(String html, String expd) { + byte[] actl = Http_server_wkr_fsys_hack_.Replace(Bry_.new_u8(html)); + Gftest.Eq__ary__lines(expd, actl); + } +} diff --git a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_tst.java b/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_tst.java deleted file mode 100644 index 04e840cda..000000000 --- a/400_xowa/src/gplx/xowa/apps/servers/http/Http_server_wkr_tst.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -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.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*; -import org.junit.*; import gplx.core.tests.*; -public class Http_server_wkr_tst { - private final Http_server_wkr_fxt fxt = new Http_server_wkr_fxt(); - @Test public void File_bgn_missing() { // "file:" missing - fxt.Test__Replace_fsys_hack("src='file////home/lnxusr/xowa/file/'"); - } - @Test public void One() { - fxt.Test__Replace_fsys_hack("'file:////home/lnxusr/xowa/file/A.png'", "'/fsys/file/A.png'"); - } - @Test public void Many() { - fxt.Test__Replace_fsys_hack("a 'file:////home/lnxusr/xowa/file/A.png' b \"file:////home/lnxusr/xowa/file/B.png\" c", "a '/fsys/file/A.png' b \"/fsys/file/B.png\" c"); - } - @Test public void Non_file() { - fxt.Test__Replace_fsys_hack("a file:////home/lnxusr/xowa/bin/any/xowa/file/app.window/app_icon.png b", "a /fsys/bin/any/xowa/file/app.window/app_icon.png b"); - } - @Test public void Url() { - fxt.Test__Replace_fsys_hack("url(file:////home/lnxusr/xowa/anonymous/wiki/www.wikidata.org/html/logo.png)", "url(/fsys/anonymous/wiki/www.wikidata.org/html/logo.png)"); - } -} -class Http_server_wkr_fxt { - private static final byte[] root_dir_http = Bry_.new_a7("file:////home/lnxusr/xowa/"); - public void Test__Replace_fsys_hack(String html) {Test__Replace_fsys_hack(html, html);} - public void Test__Replace_fsys_hack(String html, String expd) { - byte[] actl = Bry_.Replace_many(Bry_.new_u8(html), root_dir_http, Http_server_wkr.Url__fsys); - Gftest.Eq__ary__lines(expd, actl); - } -}