Skip to content

[CRITICAL BUG] dynarray_set() uses wrong casting instead of memcpy #1

Description

@seesee010

Bug Description

The dynarray_set() function has a critical casting bug that makes it only work for DynArray pointer types, breaking generic functionality.

Location

src/access.c line 34

Current Code

bool dynarray_set(DynArray *array, size_t index, void *value) {
    if (array == NULL) {
        return false;
    }

    if (index >= array->capacity) {
        array->length++;
        return false;
    }

    // i hate myself
    ((DynArray **)array->data)[index] = (DynArray*)value;  // ← WRONG!

    return true;
}

Problem

  1. Casts generic void* to DynArray**
  2. Only works if storing DynArray pointers
  3. For ANY other type (int, float, struct), this causes undefined behavior
  4. Should use memcpy() to copy element_size bytes

Expected Behavior

Should copy the actual data bytes, not cast pointers.

Proposed Fix

bool dynarray_set(DynArray *array, size_t index, void *value) {
    if (array == NULL || value == NULL) {
        return false;
    }

    if (index >= array->capacity) {
        return false;
    }

    // Proper generic set using memcpy
    void *dest = (char*)array->data + index * array->element_size;
    memcpy(dest, value, array->element_size);
    
    // Update length if setting beyond current length
    if (index >= array->length) {
        array->length = index + 1;
    }

    return true;
}

Impact

  • Severity: Critical
  • Any code using set() with non-pointer types will corrupt memory
  • Makes the library unusable for its intended generic purpose

Test Case

DynArray *arr = dynarray_create(sizeof(int), 10);
int value = 42;
dynarray_set(arr, 0, &value);  // Currently broken for int types

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions