diff options
author | Edwin Mons <edwin.mons@isode.com> | 2016-09-22 10:09:49 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2016-10-19 19:11:45 (GMT) |
commit | 08a340dbfc9208d1c0e6d574fed244a98e104f01 (patch) | |
tree | 936263f06740ee377928c18abdc4ee0a156bcf44 | |
parent | bcd3660a3527327117b46e104d16204a64fe0b9f (diff) | |
download | swift-08a340dbfc9208d1c0e6d574fed244a98e104f01.zip swift-08a340dbfc9208d1c0e6d574fed244a98e104f01.tar.bz2 |
Always add a fields table member in FormConvertor
The fields member of the forms generated by FormConvertor is used for
lookups in the __index metafunction. If a form is parsed with no
fields (and possibly no items), there wouldn't be a member 'fields',
causing another __index lookup, triggering infinite recursion.
There will now always be a fields array, which may be empty.
Sluift/Tests/FormTest.lua has been updated to test against an empty
form.
Test-Information:
Updated FormTest.lua works without issues.
Change-Id: Idee98f23bf42e1213ca3d03707f908ed5317dad6
-rw-r--r-- | Sluift/ElementConvertors/FormConvertor.cpp | 4 | ||||
-rw-r--r-- | Sluift/Tests/FormTest.lua | 14 |
2 files changed, 14 insertions, 4 deletions
diff --git a/Sluift/ElementConvertors/FormConvertor.cpp b/Sluift/ElementConvertors/FormConvertor.cpp index a0e3dfe..85f40a1 100644 --- a/Sluift/ElementConvertors/FormConvertor.cpp +++ b/Sluift/ElementConvertors/FormConvertor.cpp @@ -260,63 +260,61 @@ namespace { lua_pop(L, 1); lua_getfield(L, -1, "items"); if (lua_istable(L, -1)) { for (lua_pushnil(L); lua_next(L, -2);) { result->addItem(convertFieldListFromLua(L)); lua_pop(L, 1); } } lua_pop(L, 1); return result; } void convertFormToLua(lua_State* L, std::shared_ptr<Form> payload) { std::string type; switch (payload->getType()) { case Form::FormType: type = "form"; break; case Form::SubmitType: type = "submit"; break; case Form::CancelType: type = "cancel"; break; case Form::ResultType: type = "result"; break; } Lua::Table result = boost::assign::map_list_of("type", Lua::valueRef(type)); if (!payload->getTitle().empty()) { result["title"] = Lua::valueRef(payload->getTitle()); } if (!payload->getInstructions().empty()) { result["instructions"] = Lua::valueRef(payload->getInstructions()); } - if (!payload->getFields().empty()) { - result["fields"] = valueRef(convertFieldListToLua(payload->getFields())); - } + result["fields"] = valueRef(convertFieldListToLua(payload->getFields())); if (!payload->getReportedFields().empty()) { result["reported_fields"] = valueRef(convertFieldListToLua(payload->getReportedFields())); } if (!payload->getItems().empty()) { Lua::Array luaItems; foreach(const Form::FormItem& item, payload->getItems()) { if (!item.empty()) { luaItems.push_back(convertFieldListToLua(item)); } } result["items"] = valueRef(luaItems); } Lua::pushValue(L, result); lua_newtable(L); lua_pushcfunction(L, formIndex); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, formNewIndex); lua_setfield(L, -2, "__newindex"); lua_setmetatable(L, -2); } int createSubmission(lua_State* L) { std::shared_ptr<Form> form = convertFormFromLua(L); // Remove all redundant elements form->setInstructions(""); form->setTitle(""); diff --git a/Sluift/Tests/FormTest.lua b/Sluift/Tests/FormTest.lua index 8065360..d584646 100644 --- a/Sluift/Tests/FormTest.lua +++ b/Sluift/Tests/FormTest.lua @@ -1,32 +1,32 @@ --[[ - Copyright (c) 2013 Isode Limited. + Copyright (c) 2013-2016 Isode Limited. All rights reserved. See the COPYING file for more information. --]] example_form = [[ <x xmlns='jabber:x:data' type='form'> <title>Bot Configuration</title> <instructions>Fill out this form to configure your new bot!</instructions> <field type='hidden' var='FORM_TYPE'> <value>jabber:bot</value> </field> <field type='fixed'><value>Section 1: Bot Info</value></field> <field type='text-single' label='The name of your bot' var='botname'/> <field type='text-multi' label='Helpful description of your bot' var='description'> <value>This is</value> <value>my bot</value> </field> <field type='boolean' label='Public bot?' var='public'> <required/> </field> <field type='text-private' label='Password for special access' var='password'/> <field type='fixed'><value>Section 2: Features</value></field> <field type='list-multi' label='What features will the bot support?' var='features'> <option label='Contests'><value>contests</value></option> <option label='News'><value>news</value></option> <option label='Polls'><value>polls</value></option> <option label='Reminders'><value>reminders</value></option> <option label='Search'><value>search</value></option> <value>news</value> <value>search</value> @@ -63,30 +63,42 @@ assert(public_field['required'] == true) features_field = form['fields'][8] assert(features_field['name'] == 'features') assert(type(features_field['value']) == 'table') assert(#features_field['value'] == 2) assert(features_field['value'][1] == 'news') assert(features_field['value'][2] == 'search') -- Test shortcut index assert(form['features']['name'] == 'features') assert(form['FORM_TYPE']['value'] == 'jabber:bot') -- Test response form submission = form:create_submission() assert(#(submission.fields) == 8) description_submit_value = submission['description']['value'] assert(type(description_submit_value) == 'table') assert(description_submit_value[1] == 'This is') assert(description_submit_value[2] == 'my bot') submission['description'] = 'my description' assert(submission['description']['value'] == 'my description') submission['type'] = 'cancel' -- Test text-multi field text_multi_field = form['fields'][4] assert(text_multi_field['name'] == 'description') assert(type(text_multi_field['value']) == 'table') --print(sluift.to_xml({type = 'form', data = form})) + +-- test parsing an empty form -- this had issues as reported in SWIFT-174 +empty_form = [[<x xmlns='jabber:x:data' type='form'/>]] +form = sluift.from_xml(empty_form) +-- and check if we can access all fields without problems +assert(type(form._type)) +assert(type(form.title)) +assert(type(form.instructions)) +assert(type(form.type)) +assert(type(form.fields)) +assert(type(form.items)) +assert(type(form.reported_items)) |