diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/defs.js | 20 | ||||
-rw-r--r-- | src/lauxlib.js | 3 | ||||
-rw-r--r-- | src/loadlib.js | 6 | ||||
-rw-r--r-- | src/lua.js | 1 |
5 files changed, 25 insertions, 7 deletions
@@ -45,7 +45,7 @@ Fengari implements Lua 5.3 semantics and will hopefully follow future Lua releas Lua strings are 8-bits clean and can embed `\0`. Which means that invalid UTF-8/16 strings are valid Lua strings. Lua functions like `string.dump` even use strings as a way of storing binary data. -To address that issue, Lua strings are represented by an array of bytes in Fengari. To push a JS string on the stack you can use `lua_pushliteral` which will convert it to an array of bytes before pushing it. To get a Lua string on the stack as a JS string you can use `lua_tojsstring` which will attempt to convert it to a UTF-16 JS string. The latter won't give you what you expect if the Lua string is not a valid UTF-16 sequence. You can also convert strings with `lua.to_luastring` and `lua.to_jsstring`. +To address that issue, Lua strings are represented by an array of bytes in Fengari. To push a JS string on the stack you can use `lua_pushliteral` which will convert it to an array of bytes before pushing it. To get a Lua string on the stack as a JS string you can use `lua_tojsstring` which will attempt to convert it to a UTF-16 JS string. The latter won't give you what you expect if the Lua string is not a valid UTF-16 sequence. You can also convert strings with `lua.to_luastring`, `lua.to_jsstring` and `lua.to_uristring`. ### Integers diff --git a/src/defs.js b/src/defs.js index 315364a..3ebb747 100644 --- a/src/defs.js +++ b/src/defs.js @@ -188,6 +188,25 @@ const to_jsstring = function(value, from, to) { return str; }; +const uri_allowed = {}; /* bytes allowed unescaped in a uri */ +for (let c of ";,/?:@&=+$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,-_.!~*'()#") { + uri_allowed[c.charCodeAt(0)] = true; +} + +/* utility function to convert a lua string to a js string with uri escaping */ +const to_uristring = function(a) { + let s = ""; + for (let i=0; i<a.length; i++) { + let v = a[i]; + if (uri_allowed[v]) { + s += String.fromCharCode(v); + } else { + s += "%" + (v<0x10?"0":"") + v.toString(16); + } + } + return s; +}; + const to_luastring_cache = {}; const to_luastring = function(str, cache) { @@ -405,3 +424,4 @@ module.exports.is_luastring = is_luastring; module.exports.luastring_cmp = luastring_cmp; module.exports.to_jsstring = to_jsstring; module.exports.to_luastring = to_luastring; +module.exports.to_uristring = to_uristring; diff --git a/src/lauxlib.js b/src/lauxlib.js index 8d110ea..62fc6f3 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -740,8 +740,7 @@ if (WEB) { } else { lua.lua_pushfstring(L, lua.to_luastring("@%s"), filename); - let path = lua.to_jsstring(filename); - path = encodeURI(path); + let path = lua.to_uristring(filename); let xhr = new XMLHttpRequest(); xhr.open("GET", path, false); // TODO: find a way to load bytes instead of js string diff --git a/src/loadlib.js b/src/loadlib.js index 8ae758b..49f2715 100644 --- a/src/loadlib.js +++ b/src/loadlib.js @@ -38,8 +38,7 @@ const AUXMARK = [1]; let lsys_load; if (WEB) { lsys_load = function(L, path, seeglb) { - path = lua.to_jsstring(path); - path = encodeURI(path); + path = lua.to_uristring(path); let xhr = new XMLHttpRequest(); xhr.open("GET", path, false); xhr.send(); @@ -129,8 +128,7 @@ if (!WEB) { } else { /* TODO: use async/await ? */ readable = function(path) { - path = lua.to_jsstring(path); - path = encodeURI(path); + path = lua.to_uristring(path); let xhr = new XMLHttpRequest(); /* Following GET request done by searcher_Web will be cached */ xhr.open("GET", path, false); @@ -80,6 +80,7 @@ module.exports.lua_Debug = defs.lua_Debug; module.exports.lua_upvalueindex = defs.lua_upvalueindex; module.exports.to_jsstring = defs.to_jsstring; module.exports.to_luastring = defs.to_luastring; +module.exports.to_uristring = defs.to_uristring; module.exports.LUA_CDIR = defs.LUA_CDIR; module.exports.LUA_CPATH_DEFAULT = defs.LUA_CPATH_DEFAULT; module.exports.LUA_EXEC_DIR = defs.LUA_EXEC_DIR; |