| /* | |
| * Copyright 2023 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/private/base/SkAssert.h" | |
| #include "include/private/base/SkMalloc.h" | |
| #include "tests/Test.h" | |
| #include <cstddef> | |
| #include <cstdint> | |
| DEF_TEST(SkFree_SafeToPassNull, reporter) { | |
| // This test passes by not crashing | |
| sk_free(nullptr); | |
| } | |
| DEF_TEST(SkCalloc_DataIsZeroInitializedAndWriteable, reporter) { | |
| constexpr size_t alloc_count = 100; | |
| uint8_t* bytes = (uint8_t*) sk_calloc_throw(alloc_count); // provide num bytes directly | |
| SkASSERT_RELEASE(bytes != nullptr); | |
| for (size_t i = 0; i < alloc_count; i++) { | |
| REPORTER_ASSERT(reporter, bytes[i] == 0); | |
| bytes[i] = (uint8_t)i; | |
| } | |
| sk_free(bytes); | |
| int32_t* ints = (int32_t*) sk_calloc_throw(alloc_count, sizeof(int32_t)); // count + elem size | |
| SkASSERT_RELEASE(ints != nullptr); | |
| for (size_t i = 0; i < alloc_count; i++) { | |
| REPORTER_ASSERT(reporter, ints[i] == 0); | |
| ints[i] = (int32_t)i; | |
| } | |
| sk_free(ints); | |
| } | |
| DEF_TEST(SkMalloc_DataIsWriteable, reporter) { | |
| constexpr size_t alloc_count = 100; | |
| uint8_t* bytes = (uint8_t*) sk_malloc_throw(alloc_count); // provide num bytes directly | |
| SkASSERT_RELEASE(bytes != nullptr); | |
| for (size_t i = 0; i < alloc_count; i++) { | |
| bytes[i] = (uint8_t)i; | |
| } | |
| sk_free(bytes); | |
| int32_t* ints = (int32_t*) sk_malloc_throw(alloc_count, sizeof(int32_t)); // count + elem size | |
| SkASSERT_RELEASE(ints != nullptr); | |
| for (size_t i = 0; i < alloc_count; i++) { | |
| ints[i] = (int32_t)i; | |
| } | |
| sk_free(ints); | |
| } | |
| DEF_TEST(SkRealloc_DataIsWriteableAndEventuallyFreed, reporter) { | |
| // Calling sk_realloc_throw with null should be treated as if it was sk_malloc_throw | |
| uint8_t* bytes = (uint8_t*) sk_realloc_throw(nullptr, 10); | |
| SkASSERT_RELEASE(bytes != nullptr); | |
| // Make sure those 10 bytes are writeable | |
| for (size_t i = 0; i < 10; i++) { | |
| bytes[i] = (uint8_t)i; | |
| } | |
| // Make it smaller | |
| bytes = (uint8_t*) sk_realloc_throw(bytes, 5); | |
| SkASSERT_RELEASE(bytes != nullptr); | |
| // Make sure those 5 bytes are still writeable and contain the previous values | |
| for (int i = 0; i < 5; i++) { | |
| REPORTER_ASSERT(reporter, bytes[i] == i, "bytes[%d] != %d", i, i); | |
| bytes[i] = (uint8_t)i + 17; | |
| } | |
| // Make it bigger | |
| bytes = (uint8_t*) sk_realloc_throw(bytes, 20, sizeof(uint8_t)); // count + elem size | |
| SkASSERT_RELEASE(bytes != nullptr); | |
| // Make sure the first 5 bytes are still writeable and contain the previous values | |
| for (int i = 0; i < 5; i++) { | |
| REPORTER_ASSERT(reporter, bytes[i] == (i + 17), "bytes[%d] != %d", i, i+17); | |
| bytes[i] = (uint8_t)i + 43; | |
| } | |
| // The next 15 bytes are uninitialized, so just make sure we can write to them. | |
| for (int i = 5; i < 20; i++) { | |
| bytes[i] = (uint8_t)i + 43; | |
| } | |
| // This should free the memory and return nullptr. | |
| bytes = (uint8_t*) sk_realloc_throw(bytes, 0); | |
| REPORTER_ASSERT(reporter, bytes == nullptr); | |
| // We run our tests with LeakSanitizer, so if bytes is *not* freed, we should see a failure. | |
| } |