Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions libpromises/evalfunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -10409,8 +10409,9 @@ void ModuleProtocol(EvalContext *ctx, const char *command, const char *line, int

if (CheckID(name))
{
Rlist *list = RlistParseString(content);
if (!list)
/* An empty list is NULL too, so check the return value */
Rlist *list = NULL;
if (!RlistParseString(content, &list))
{
Log(LOG_LEVEL_ERR, "Module protocol could not parse variable %s's data content %s", name, content);
}
Expand Down
27 changes: 20 additions & 7 deletions libpromises/rlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,12 @@ static int LaunchParsingMachine(const char *str, Rlist **newlist)
BufferClear(buf);
current_state = ST_ELM2;
}
else if (CLASS_BRA2(*s))
{
/* "{}" -- a closing brace before any element. Has to come
* before the catch-all below. */
current_state = ST_PRECLOSED;
}
else if (CLASS_ANY1(*s))
{
current_state = ST_ERROR;
Expand Down Expand Up @@ -955,19 +961,26 @@ static int LaunchParsingMachine(const char *str, Rlist **newlist)
clean:
BufferDestroy(buf);
RlistDestroy(*newlist);
*newlist = NULL;
assert(ret != 0);
return ret;
}

Rlist *RlistParseString(const char *string)
/**
* @brief Parse a list in the format used by the module protocol, e.g. { "a", "b" }
* @param string String to parse
* @param[out] newlist The parsed list, NULL for the empty list "{}"
* @return Whether the string was parsed successfully
*
* An empty list parses fine and gives NULL, so check the return value.
*/
bool RlistParseString(const char *string, Rlist **newlist)
{
Rlist *newlist = NULL;
if (LaunchParsingMachine(string, &newlist))
{
return NULL;
}
assert(newlist != NULL);

return newlist;
*newlist = NULL;

return (LaunchParsingMachine(string, newlist) == 0);
}

/*******************************************************************/
Expand Down
2 changes: 1 addition & 1 deletion libpromises/rlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ char *RlistScalarValueSafe(const Rlist *rlist);
FnCall *RlistFnCallValue(const Rlist *rlist);
Rlist *RlistRlistValue(const Rlist *rlist);
Rlist *RlistParseShown(const char *string);
Rlist *RlistParseString(const char *string);
bool RlistParseString(const char *string, Rlist **newlist);
Rlist *RlistKeyIn(Rlist *list, const char *key);
Rlist *RlistKeyIn_IgnoreCase(Rlist *list, const char *key);
int RlistLen(const Rlist *start);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ body common control
bundle agent test
{
meta:
"description" -> { "CFE-2139", "redmine7577" }
string => "Test that modules are allowed to emit empty lists";

"test_soft_fail"
string => "any",
meta => { "redmine7577" };
string => "windows",
meta => { "ENT-10257" };

commands:
"$(G.cat)"
Expand Down
9 changes: 7 additions & 2 deletions tests/unit/rlist_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ static struct ParseRoulette
char *str;
} PR[] =
{
/*Empty list */
{
0, "{}"},
{
0, "{ }"},
/*Simple */
{
1, "{\"a\"}"},
Expand Down Expand Up @@ -567,7 +572,7 @@ static void test_new_parser_success()
int i = 0;
while (PR[i].nfields != -1)
{
list = RlistParseString(PR[i].str);
assert_true(RlistParseString(PR[i].str, &list));
assert_int_equal(PR[i].nfields, RlistLen(list));
if (list != NULL)
{
Expand All @@ -583,7 +588,7 @@ static void test_new_parser_failure()
Rlist *list = NULL;
while (PFR[i] != NULL)
{
list = RlistParseString(PFR[i]);
assert_false(RlistParseString(PFR[i], &list));
assert_true(RlistLast(list) == NULL);
if(list) RlistDestroy(list);
i++;
Expand Down
Loading