Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fe18615 authored by Elliott Hughes's avatar Elliott Hughes Committed by Android Git Automerger
Browse files

am 56d57e88: am 5f130216: Merge "Handle errno properly to avoid corrupt str_parms"

* commit '56d57e88':
  Handle errno properly to avoid corrupt str_parms
parents f84b61b3 56d57e88
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -91,6 +91,16 @@ LOCAL_STATIC_LIBRARIES := lib64log
LOCAL_CFLAGS += $(hostSmpFlag) -m64
include $(BUILD_HOST_STATIC_LIBRARY)

# Tests for host
# ========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := tst_str_parms
LOCAL_CFLAGS += -DTEST_STR_PARMS
LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c
LOCAL_STATIC_LIBRARIES := liblog
LOCAL_MODULE_TAGS := optional
include $(BUILD_HOST_EXECUTABLE)


# Shared and static library for target
# ========================================================
+44 −13
Original line number Diff line number Diff line
@@ -194,23 +194,46 @@ err_create_str_parms:
int str_parms_add_str(struct str_parms *str_parms, const char *key,
                      const char *value)
{
    void *old_val;
    void *tmp_key;
    void *tmp_val;
    void *tmp_key = NULL;
    void *tmp_val = NULL;
    void *old_val = NULL;

    // strdup and hashmapPut both set errno on failure.
    // Set errno to 0 so we can recognize whether anything went wrong.
    int saved_errno = errno;
    errno = 0;

    tmp_key = strdup(key);
    if (tmp_key == NULL) {
        goto clean_up;
    }

    tmp_val = strdup(value);
    if (tmp_val == NULL) {
        goto clean_up;
    }

    old_val = hashmapPut(str_parms->map, tmp_key, tmp_val);
    if (old_val == NULL) {
        // Did hashmapPut fail?
        if (errno == ENOMEM) {
            goto clean_up;
        }
        // For new keys, hashmap takes ownership of tmp_key and tmp_val.
        tmp_key = tmp_val = NULL;
    } else {
        // For existing keys, hashmap takes ownership of tmp_val.
        // (It also gives up ownership of old_val.)
        tmp_val = NULL;
    }

    if (old_val) {
        free(old_val);
        free(tmp_key);
    } else if (errno == ENOMEM) {
clean_up:
    free(tmp_key);
    free(tmp_val);
        return -ENOMEM;
    }
    return 0;
    free(old_val);
    int result = -errno;
    errno = saved_errno;
    return result;
}

int str_parms_add_int(struct str_parms *str_parms, const char *key, int value)
@@ -337,7 +360,6 @@ static void test_str_parms_str(const char *str)
{
    struct str_parms *str_parms;
    char *out_str;
    int ret;

    str_parms = str_parms_create_str(str);
    str_parms_add_str(str_parms, "dude", "woah");
@@ -370,6 +392,15 @@ int main(void)
    test_str_parms_str("foo=bar;baz=bat;");
    test_str_parms_str("foo=bar;baz=bat;foo=bar");

    // hashmapPut reports errors by setting errno to ENOMEM.
    // Test that we're not confused by running in an environment where this is already true.
    errno = ENOMEM;
    test_str_parms_str("foo=bar;baz=");
    if (errno != ENOMEM) {
        abort();
    }
    test_str_parms_str("foo=bar;baz=");

    return 0;
}
#endif