Skip to content
Snippets Groups Projects
Commit d6d7c359 authored by Alex Dowad's avatar Alex Dowad Committed by Natanael Copa
Browse files

main/lua-luaxml: Build from n1tehawk's fork of LuaXML

The original repository for LuaXML is inactive and unmaintained
(and has been since 2013). Switch to a more recently maintained fork,
which contains a number of bug fixes, performance optimizations, and
new features.

It contains a fix for the same bug which was patched in 77f0be51.
parent 4a663851
No related branches found
No related tags found
1 merge request!30331main/lua-luaxml: Build from n1tehawk's fork of LuaXML
Pipeline #112772 passed
From 0b7449ef614cd6514a7f81ebdc8f2171efee0ca9 Mon Sep 17 00:00:00 2001
From: Alex Dowad <alexinbeijing@gmail.com>
Date: Thu, 24 Feb 2022 14:58:01 +0200
Subject: [PATCH] Be strict about handling of malformed XML attributes
This code was written by Natanael Copa.
---
LuaXML_lib.c | 11 ++++++++++-
unittest.lua | 8 ++++++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/LuaXML_lib.c b/LuaXML_lib.c
index 6c074de..ae330ee 100644
--- a/LuaXML_lib.c
+++ b/LuaXML_lib.c
@@ -671,8 +671,17 @@ int Xml_eval(lua_State *L) {
// parse tag header
size_t sepPos = find(token, "=", 0);
if (token[sepPos]) { // regular attribute (key="value")
- const char *aVal = token + sepPos + 2;
+ const char *aVal = token + sepPos + 1;
lua_pushlstring(L, token, sepPos);
+ size_t lenVal = strlen(aVal);
+
+ if (lenVal < 2 || ((aVal[0] != '"' && aVal[0] != '\'') || (aVal[lenVal-1] != '"' && aVal[lenVal-1] != '\'')))
+ luaL_error(L, "Malformed XML: attribute value not quoted in '%s'", token);
+
+ // strip quote chars
+ aVal++;
+ lenVal -= 2;
+
Xml_pushDecode(L, aVal, strlen(aVal) - 1);
lua_rawset(L, -3);
}
diff --git a/unittest.lua b/unittest.lua
index e179d91..1d16d7a 100644
--- a/unittest.lua
+++ b/unittest.lua
@@ -162,5 +162,13 @@ function TestXml:test_transform()
lu.assertEquals(test, expected)
end
+function TestXml:test_malformed_attribute()
+ -- malformed XML attribute
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad=0></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad=></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad='></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, '<a bad="></a>')
+end
+
-- run test suite with verbose output
os.exit(lu.LuaUnit.run("-v"))
--
2.25.1
From 087a65cd18aa95cce07944a57874fab35302879f Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 23 Feb 2022 14:59:28 +0000
Subject: [PATCH] add unit test
based on unittest.lua https://github.com/n1tehawk/LuaXML
failing tests was removed.
int underflow test added for malformed attribute
---
unittest.lua | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 unittest.lua
diff --git a/unittest.lua b/unittest.lua
new file mode 100644
index 0000000..a791ee4
--- /dev/null
+++ b/unittest.lua
@@ -0,0 +1,96 @@
+-- unit tests for LuaXML
+
+local xml = require('LuaXml')
+local lu = require('luaunit')
+
+TestXml = {} -- the test suite
+
+function TestXml:test_basics()
+ -- encoding / decoding XML representations
+ lu.assertEquals(xml.encode("<->"), "&lt;-&gt;")
+
+ -- check metatable of newly created object
+ local foobar = xml.new()
+ lu.assertIsTable(foobar)
+ lu.assertEquals(getmetatable(foobar).__index, xml)
+
+ -- simple XML strings
+ lu.assertNil(xml.eval(""))
+ foobar = xml.eval('<foo bar="true" />')
+ lu.assertIsTable(foobar)
+ lu.assertEquals(foobar[0], "foo")
+ lu.assertEquals(foobar.bar, "true")
+
+ -- mimic the append() example from the README
+ foobar = xml.new("root")
+ foobar:append("child")[1] = 123
+ lu.assertEquals(foobar[1]:str(), "<child>123</child>\n")
+
+ -- proper handling of an empty attribute
+ local foo = '<tag attr="" />\n'
+ foobar = xml.eval(foo)
+ lu.assertEquals(foobar.attr, "")
+ lu.assertEquals(foobar:str(), foo)
+
+ -- encoding / decoding of special entities
+ foo = xml.new({"<&>"}, "foo")
+ lu.assertEquals(xml.eval("<foo>&#032;</foo>")[1], " ")
+ lu.assertEquals(xml.eval("<bar>&#32;</bar>")[1], " ")
+ lu.assertEquals(xml.eval("<foobar>&apos;&#9;&apos;</foobar>")[1], "'\t'")
+
+ -- enhanced whitespace handling
+ lu.assertEquals(xml.eval("<foo> </foo>"):str(), "<foo />\n") -- default mode
+ lu.assertEquals(xml.eval("<foo> </foo>", xml.WS_TRIM):str(), "<foo />\n")
+ lu.assertEquals(xml.eval("<foo>\n <bar/> x\t</foo>", xml.WS_TRIM),
+ {{[0]="bar"}, "x", [0]="foo"})
+
+ -- CDATA
+ lu.assertEquals(xml.eval("<fu><![CDATA[]]></fu>"), {[0] = "fu"})
+ lu.assertEquals(xml.eval("<fu>foo<![CDATA[]]>bar</fu>"),
+ {"foo", "bar", [0] = "fu"})
+ lu.assertEquals(xml.eval("<fu>foo<![CDATA[foobar]]>bar</fu>"),
+ {"foo", "foobar", "bar", [0] = "fu"})
+
+ -- check load error
+ lu.assertErrorMsgContains("file error or file not found",
+ xml.load, "invalid_filename")
+
+ -- safeguard against global namespace pollution
+ lu.assertNil(_G.xml)
+end
+
+function TestXml:test_malformed_attribute()
+ -- malformed XML attribute
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad=0></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad=></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, "<a bad='></a>")
+ lu.assertErrorMsgContains("Malformed XML", xml.eval, '<a bad="></a>')
+end
+
+function TestXml:test_parse()
+ local test = xml.load("test.xml")
+
+ local scene = test:find("scene")
+ lu.assertIsTable(scene)
+ lu.assertEquals(scene:tag(), "scene") -- XML tag
+ lu.assertEquals(scene.id, "0") -- XML property/attribute
+ lu.assertEquals(scene.script, "main")
+
+ -- first (sub)element
+ scene = scene[1]
+ lu.assertIsTable(scene)
+ lu.assertEquals(scene:tag(), "object")
+ lu.assertEquals(scene.name, "observer")
+ lu.assertEquals(scene.id, "0")
+ lu.assertEquals(scene.input, "window")
+ lu.assertEquals(scene.script, "camera.lua")
+
+ -- make sure that the CDATA element from <script> starts with '\n' and
+ -- ends with ' ' (i.e. preserved whitespace)
+ local script_str = test:find("script")[1]
+ lu.assertEquals(script_str:sub(1, 1), '\n')
+ lu.assertEquals(script_str:sub(-1), ' ')
+end
+
+-- run test suite with verbose output
+os.exit(lu.LuaUnit.run("-v"))
--
2.35.1
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=lua-luaxml
pkgver=130610
pkgver=2.0.0
_pkgver=$pkgver-1
pkgrel=9
pkgrel=0
pkgdesc="A minimal set of functions for the processing of XML data in Lua"
# url="https://github.com/LuaDist2/luaxml"
url="https://luarocks.org/modules/djerius/luaxml"
url="https://github.com/n1tehawk/LuaXML"
arch="all"
license="MIT"
replaces="lua-xml"
patch_args="-l"
source="https://distfiles.alpinelinux.org/distfiles/v3.13/$pkgname-$pkgver.tar.gz
fixes.patch
fix-int-overflow.patch
0001-add-unit-test.patch
"
builddir="$srcdir/luaxml-$_pkgver"
source="$pkgname-$pkgver.tar.gz::https://github.com/n1tehawk/LuaXML/archive/7cd4a7ab5db85222edb4c955d53e5674afd170b6.tar.gz
0001-XML-attributes.patch"
builddir="$srcdir/LuaXML-7cd4a7ab5db85222edb4c955d53e5674afd170b6"
_luaversions="5.2 5.3 5.4"
for _v in $_luaversions; do
makedepends="$makedepends lua$_v-dev"
makedepends="$makedepends lua$_v-dev lua-unit"
subpackages="$subpackages lua$_v-${pkgname#lua-}:_subpackage"
checkdepends="$checkdepends lua$_v-unit"
done
prepare() {
# Remove garbage.
rm -f ./*.dll ./*.so ./*.zip
# fix newlines
sed -i -e 's/\r//' *.c *.lua *.txt *.xml
default_prepare
local lver; for lver in $_luaversions; do
......@@ -75,7 +66,10 @@ _subpackage() {
install -m 755 -D LuaXML_lib.so \
"$subpkgdir"/usr/lib/lua/$lver/LuaXML_lib.so
install -m 755 -D LuaXml.lua \
install -m 755 -D LuaXML.lua \
"$subpkgdir"/usr/share/lua/$lver/LuaXML.lua
# For backward compatibility, provide both LuaXML.lua and LuaXml.lua
install -m 755 -D LuaXML.lua \
"$subpkgdir"/usr/share/lua/$lver/LuaXml.lua
mkdir -p "$rockdir"
......@@ -83,8 +77,6 @@ _subpackage() {
}
sha512sums="
aabac62b5e748c04cd3591e5c2e6b417909c7a9efa1ff6c3dd1f546a2387220eb7fa1ffa56d3be0718a84a6fed51f287b68c7d334661c66787f7024d76142dfc lua-luaxml-130610.tar.gz
8690a4278a4f3b2b1a397eab9f8ba218e13b65d92d8114b84e988d31a8d014639e15b402c1e0302a8afa0bc4f72dc0b89a43be3529243070d67185e59b5c3404 fixes.patch
80ab69ae0d0a2eeea0be2a7a7a40c0cb31371631e07f3b7b7dfd21af324a636c7e2aa45a1c446c372680244f358eca44eb04d195d503dfa6d39c7c1a4073d37b fix-int-overflow.patch
21f8aa39ccafe433bf129ff5a747eaabfdd28f00ebf3e375faab463f908b1fa31aa417f20c4d20e4418de32a6c757a295295a21567101bcceb94a98c07f4736c 0001-add-unit-test.patch
584f8aa2c78411bc00d6f11973929c3629a401c312cf10382eb116f18b8d1b267fe2a3f99d7db7a1c8a20f5c963203e760263cccf5e949714a8b58e9412bb661 lua-luaxml-2.0.0.tar.gz
64305a006b36aee1bb8dfcba97b7bff33aa2bcac9746ac39a0e18cbeedecfb1e6f249afd6b8c3dd28b88dd2eccee983f5c53e59db79506d1e72622fb7673d686 0001-XML-attributes.patch
"
diff --git a/LuaXML_lib.c b/LuaXML_lib.c
index 62a2dc6..70c432a 100644
--- a/LuaXML_lib.c
+++ b/LuaXML_lib.c
@@ -322,9 +322,17 @@ int Xml_eval(lua_State *L) {
while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header
size_t sepPos=find(token, "=", 0);
if(token[sepPos]) { // regular attribute
- const char* aVal =token+sepPos+2;
+ const char* aVal =token+sepPos+1;
lua_pushlstring(L, token, sepPos);
- size_t lenVal = strlen(aVal)-1;
+ size_t lenVal = strlen(aVal);
+
+ if (lenVal < 2 || ((aVal[0] != '"' && aVal[0] != '\'') || (aVal[lenVal-1] != '"' && aVal[lenVal-1] != '\'')))
+ luaL_error(L, "Malformed XML: attribute value not quoted in '%s'", token);
+
+ // strip quote chars
+ aVal++;
+ lenVal -= 2;
+
if(!lenVal) Xml_pushDecode(L, "", 0);
else Xml_pushDecode(L, aVal, lenVal);
lua_settable(L, -3);
diff --git a/LuaXML_lib.c b/LuaXML_lib.c
index 18b6960..62a2dc6 100644
--- a/LuaXML_lib.c
+++ b/LuaXML_lib.c
@@ -311,17 +311,7 @@ int Xml_eval(lua_State *L) {
else return lua_gettop(L);
}
// set metatable:
- lua_newtable(L);
- lua_pushliteral(L, "__index");
- lua_getglobal(L, "xml");
- lua_settable(L, -3);
-
- lua_pushliteral(L, "__tostring"); // set __tostring metamethod
- lua_getglobal(L, "xml");
- lua_pushliteral(L,"str");
- lua_gettable(L, -2);
- lua_remove(L, -2);
- lua_settable(L, -3);
+ luaL_getmetatable(L, "LuaXML.node");
lua_setmetatable(L, -2);
// parse tag and content:
@@ -434,6 +424,18 @@ int _EXPORT luaopen_LuaXML_lib (lua_State* L) {
{NULL, NULL}
};
luaL_newlib(L, funcs);
+ luaL_newmetatable(L, "LuaXML.node");
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -3);
+ lua_settable(L, -3);
+ lua_pop(L, 1);
+
+ // store metatable in xml.__metatable, so we can finish setting it up
+ // in LuaXml.lua
+ lua_pushliteral(L, "__metatable");
+ luaL_getmetatable(L, "LuaXML.node");
+ lua_settable(L, -3);
+
// register default codes:
if(!sv_code) {
sv_code=(char**)malloc(sv_code_capacity*sizeof(char*));
diff --git a/LuaXml.lua b/LuaXml.lua
index 7beb11a..2476b68 100644
--- a/LuaXml.lua
+++ b/LuaXml.lua
@@ -8,9 +8,9 @@ xml.TAG = 0
function xml.tag(var,tag)
if base.type(var)~="table" then return end
if base.type(tag)=="nil" then
- return var[TAG]
+ return var[xml.TAG]
end
- var[TAG] = tag
+ var[xml.TAG] = tag
end
-- creates a new LuaXML object either by setting the metatable of an existing Lua table or by setting its tag
@@ -21,7 +21,7 @@ function xml.new(arg)
end
local var={}
base.setmetatable(var,{__index=xml, __tostring=xml.str})
- if base.type(arg)=="string" then var[TAG]=arg end
+ if base.type(arg)=="string" then var[xml.TAG]=arg end
return var
end
@@ -75,6 +75,7 @@ function xml.str(var,indent,tagValue)
end
end
+xml.__metatable.__tostring = xml.str
-- saves a Lua var as xml file
function xml.save(var,filename)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment