diff --git a/doc/news/_preparation_next_release.md b/doc/news/_preparation_next_release.md index ea7fded124d..022287e8196 100644 --- a/doc/news/_preparation_next_release.md +++ b/doc/news/_preparation_next_release.md @@ -81,6 +81,14 @@ Take a look at the [new docs](../dev/mountpoints.md), if you need to know detail The following text lists news about the [plugins](https://www.libelektra.org/plugins/readme) we updated in this release. +### yajl + +- <> +- <> +- Fix an issue where trying to set invalid meta-keys won't show an error _(Juri Schreib @Bujuhu)_ +- <> +- <> + ### list - Removed the `list` plugin. _(Maximilian Irlinger @atmaxinger)_ diff --git a/src/plugins/yajl/testmod_yajl.c b/src/plugins/yajl/testmod_yajl.c index 93a2fc7dd13..2299ce72367 100644 --- a/src/plugins/yajl/testmod_yajl.c +++ b/src/plugins/yajl/testmod_yajl.c @@ -488,6 +488,27 @@ void test_readWrite (const char * fileName, KeySet * conf) elektraPluginClose (plugin, 0); } +void test_writeMetaMustFail (const char * fileName, KeySet * conf) +{ + printf ("Test write unknown meta keys must fail with %s\n", srcdir_file (fileName)); + + Plugin * plugin = elektraPluginOpen ("yajl", modules, conf, 0); + exit_if_fail (plugin != 0, "could not open plugin"); + // printf ("Test with %s\n", srcdir_file(fileName)); + + Key * parentKey = keyNew ("user:/tests/yajl", KEY_VALUE, "asdf", KEY_META, "asdf", "asdf", KEY_END); + KeySet * keys = ksNew (1, keyNew ("user:/tests/yajl/asdf", KEY_VALUE, "asdf", KEY_META, "asdf", "asdf", KEY_END), KS_END); + succeed_if (plugin->kdbSet (plugin, keys, parentKey) == ELEKTRA_PLUGIN_STATUS_ERROR, + "kdbSet did not error on bogus meta key insertion"); + + elektraUnlink (keyString (parentKey)); + + keyDel (parentKey); + ksDel (keys); + + elektraPluginClose (plugin, 0); +} + // TODO: make nicer and put to test framework #define succeed_if_equal(x, y) succeed_if (!strcmp (x, y), x) @@ -731,6 +752,8 @@ int main (int argc, char ** argv) test_readWrite ("yajl/testdata_empty_in_map2.json", ksNew (0, KS_END)); test_readWrite ("yajl/testdata_empty_in_map1.json", ksNew (0, KS_END)); + test_writeMetaMustFail ("yajl/testdata_write_meta.json", ksNew (0, KS_END)); + elektraModulesClose (modules, 0); ksDel (modules); diff --git a/src/plugins/yajl/yajl_gen.c b/src/plugins/yajl/yajl_gen.c index 7ec6aeb3480..3c98962b000 100644 --- a/src/plugins/yajl/yajl_gen.c +++ b/src/plugins/yajl/yajl_gen.c @@ -127,12 +127,12 @@ static int elektraGenOpenValue (yajl_gen g, const Key * next) * @param parentKey needed for adding warnings/errors * @param cur the key to generate the value from */ -static void elektraGenValue (yajl_gen g, Key * parentKey, const Key * cur) +static bool elektraGenValue (yajl_gen g, Key * parentKey, Key * cur) { if (strcmp (keyName (parentKey), keyName (cur)) && !elektraGenOpenValue (g, cur)) { ELEKTRA_LOG_DEBUG ("Do not yield value"); - return; + return true; } ELEKTRA_LOG_DEBUG ("GEN value %s for %s", keyString (cur), keyName (cur)); @@ -172,6 +172,7 @@ static void elektraGenValue (yajl_gen g, Key * parentKey, const Key * cur) ELEKTRA_ADD_VALIDATION_SEMANTIC_WARNINGF (parentKey, "The key %s has unknown type: %s", keyName (cur), keyString (type)); yajl_gen_string (g, (const unsigned char *) keyString (cur), keyGetValueSize (cur) - 1); } + return true; } int elektraGenEmpty (yajl_gen g, KeySet * returned, Key * parentKey) @@ -267,6 +268,28 @@ static void elektraCheckForEmptyArray (KeySet * ks) } } +static bool elektraCheckForInvalidMetaKey (Key * parentKey, KeySet * ks) +{ + Key * cur = 0; + for (elektraCursor it = 0; it < ksGetSize (ks); ++it) + { + cur = ksAtCursor (ks, it); + const KeySet * metaKeys = keyMeta (cur); + for (elektraCursor jt = 0; jt < ksGetSize (metaKeys); ++jt) + { + const Key * meta = ksAtCursor (metaKeys, jt); + const char * pos = (const char *) keyName (meta); + if (elektraStrCmp (pos, "meta:/type") != 0 && elektraStrCmp (pos, "meta:/array") != 0 && + elektraStrCmp (pos, "meta:/binary") != 0) + { + ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "The Metakey %s is not supported by yajl", keyName (meta)); + return false; + } + } + } + return true; +} + int elektraYajlSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey) { #if YAJL_MAJOR == 1 @@ -277,12 +300,21 @@ int elektraYajlSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * par yajl_gen_config (g, yajl_gen_beautify, 1); #endif + if (!elektraCheckForInvalidMetaKey (parentKey, returned)) + { + yajl_gen_free (g); + return ELEKTRA_PLUGIN_STATUS_ERROR; + } + elektraCheckForEmptyArray (returned); if (ksGetSize (returned) == 1 && !strcmp (keyName (parentKey), keyName (ksAtCursor (returned, 0))) && keyGetValueSize (ksAtCursor (returned, 0)) > 1) { - elektraGenValue (g, parentKey, ksAtCursor (returned, 0)); + if (!elektraGenValue (g, parentKey, ksAtCursor (returned, 0))) + { + return -1; + } int ret = elektraGenWriteFile (g, parentKey); yajl_gen_free (g); return ret;