From 870d9c2e141d9fd494657f36c8c8e162eb446dff Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 21 Feb 2014 08:59:03 +0200 Subject: web client: fix path escaping problems --- web/client.js | 16 ++++++++-------- web/dom.js | 6 ++---- web/navigation.js | 11 +++++++++++ web/path.js | 32 +++++++++++++++++++++++++++----- web/transaction.js | 2 +- 5 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 web/navigation.js diff --git a/web/client.js b/web/client.js index d62a678..9bbe75c 100644 --- a/web/client.js +++ b/web/client.js @@ -22,6 +22,7 @@ require( [ "acf2/dom", "acf2/error", + "acf2/navigation", "acf2/path", "acf2/statusbar", "acf2/transaction", @@ -31,10 +32,11 @@ require( "underscore", "acf2/layout/stacked", "acf2/layout/tabular", - "jquery-bbq", "jquery-blockui" ], - function(dom, formatError, pth, statusBar, txnMgr, type, Inline, $, _) { + function( + dom, formatError, navi, pth, statusBar, txnMgr, type, Inline, $, _ + ) { $("#login").submit(function() { $.ajax("/login", { @@ -51,10 +53,8 @@ require( ); - function redirect(path) { $.bbq.pushState("#" + path); } - function renderObject(path, data) { - path = path || $.param.fragment(); + path = path || navi.getPath(); return ( data ? $.Deferred().resolve(data) : txnMgr.query(path) @@ -87,7 +87,7 @@ require( var comps = pth.split(path); comps.pop(); comps.unshift("/"); - redirect(pth.join.apply(undefined, comps)); + navi.setPath(pth.join.apply(undefined, comps)); }); }; @@ -99,7 +99,7 @@ require( function render() { - var path = $.param.fragment(); + var path = navi.getPath(); function renderMenu(target, path, current, selectFirst) { var def = $.Deferred(); @@ -222,7 +222,7 @@ require( $("#content").empty(); $(window).bind("hashchange", render); - redirect("/"); + navi.setPath("/"); }).fail(function() { statusBar.setError("Login failed", "login"); diff --git a/web/dom.js b/web/dom.js index 44f8491..ba11827 100644 --- a/web/dom.js +++ b/web/dom.js @@ -3,7 +3,7 @@ * See LICENSE file for license details */ -define(["jquery", "jquery-bbq"], function($) { +define(["acf2/navigation", "jquery"], function(navi, $) { function href() { return $("").attr({href: "javascript:void(0);"}); } @@ -14,9 +14,7 @@ define(["jquery", "jquery-bbq"], function($) { objectRef: function(value, el) { el = el || href(); if (value) { - el.click(function() { - $.bbq.pushState("#" + value); - }).text("Show"); + el.click(function() { navi.setPath(value); }).text("Show"); } return el; }, diff --git a/web/navigation.js b/web/navigation.js new file mode 100644 index 0000000..c7830a8 --- /dev/null +++ b/web/navigation.js @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2012-2014 Kaarle Ritvanen + * See LICENSE file for license details + */ + +define(["jquery", "jquery-bbq"], function($) { + return { + getPath: function() { return decodeURI($.param.fragment()); }, + setPath: function(path) { $.bbq.pushState("#" + encodeURI(path)); } + }; +}); diff --git a/web/path.js b/web/path.js index bb60c76..2373867 100644 --- a/web/path.js +++ b/web/path.js @@ -6,12 +6,34 @@ define(["underscore"], function(_) { function split(path) { var res = []; - while (path && path != "/") { - var comp = path.match(/^\/([^\\\/]|\\.)+/)[0]; - res.push(comp.substring(1)); - path = path.substring(comp.length); + var comp = ""; + var escaped; + + function merge(s) { + var n = Number(s); + if (s > "") res.push((escaped || isNaN) ? s : n); + } + + while (true) { + var m = path.match(/^([^\\\/]*)([\\\/])(.*)/); + if (!m) { + merge(comp + path); + return res; + } + + comp += m[1]; + if (m[2] == "\\") { + comp += m[3].substring(0, 1); + escaped = true; + path = m[3].substring(1); + } + else { + merge(comp); + comp = ""; + escaped = false; + path = m[3]; + } } - return res; } function escape(name) { diff --git a/web/transaction.js b/web/transaction.js index a85b7f5..a850488 100644 --- a/web/transaction.js +++ b/web/transaction.js @@ -26,7 +26,7 @@ define( if (txn) options.headers["X-ACF-Transaction-ID"] = txn; if (options.data != undefined) options.data = JSON.stringify(options.data); - return $.ajax(url, options); + return $.ajax(encodeURI(url), options); } txnMgr.abort = function() { -- cgit v1.2.3