libmapper: Actually examine read errors
Don't rely on undefined behavior in failed read calls where some of the
message is read. Right now the subtree remove callback parses the message
of type "as" into a 1 element array. It uses this to determine if the
array is empty or not. This depends on the underlying implementation to
populate one of the array elements in the case where it has more than
one and produces an error.
Instead, properly enter the array container and check to see if it is empty
while doing error handling for the calls.
Change-Id: I542c488524a5dce5466d6196879159d888e47346
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/libmapper/mapper.c b/libmapper/mapper.c
index 8bb42e9..c6b797d 100644
--- a/libmapper/mapper.c
+++ b/libmapper/mapper.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "config.h"
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -403,7 +404,6 @@
sd_bus_error *e)
{
int r;
- char *intf = NULL;
struct mapper_async_subtree *subtree = userdata;
uint64_t now;
@@ -449,12 +449,26 @@
goto exit;
}
- sd_bus_message_read(m, "as", 1, &intf);
if (subtree->op == MAPPER_OP_REMOVE)
{
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
+ if (r < 0)
+ {
+ async_subtree_done(r, subtree);
+ goto exit;
+ }
+
+ r = sd_bus_message_at_end(m, false);
+ if (r < 0)
+ {
+ async_subtree_done(r, subtree);
+ goto exit;
+ }
+
/* For remove, operation is complete when the interface is not present
+ * we know it is empty if the returned array is empty
*/
- if (intf == NULL)
+ if (r)
async_subtree_done(0, subtree);
}