Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/scratch_impl.h
Show All 9 Lines | |||||
#include "scratch.h" | #include "scratch.h" | ||||
/* Using 16 bytes alignment because common architectures never have alignment | /* Using 16 bytes alignment because common architectures never have alignment | ||||
* requirements above 8 for any of the types we care about. In addition we | * requirements above 8 for any of the types we care about. In addition we | ||||
* leave some room because currently we don't care about a few bytes. | * leave some room because currently we don't care about a few bytes. | ||||
* TODO: Determine this at configure time. */ | * TODO: Determine this at configure time. */ | ||||
#define ALIGNMENT 16 | #define ALIGNMENT 16 | ||||
static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t init_size, size_t max_size) { | static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size) { | ||||
secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); | secp256k1_scratch* ret = (secp256k1_scratch*)checked_malloc(error_callback, sizeof(*ret)); | ||||
if (ret != NULL) { | if (ret != NULL) { | ||||
ret->data = checked_malloc(error_callback, init_size); | memset(ret, 0, sizeof(*ret)); | ||||
if (ret->data == NULL) { | |||||
free (ret); | |||||
return NULL; | |||||
} | |||||
ret->offset = 0; | |||||
ret->init_size = init_size; | |||||
ret->max_size = max_size; | ret->max_size = max_size; | ||||
ret->error_callback = error_callback; | ret->error_callback = error_callback; | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { | static void secp256k1_scratch_destroy(secp256k1_scratch* scratch) { | ||||
if (scratch != NULL) { | if (scratch != NULL) { | ||||
free(scratch->data); | VERIFY_CHECK(scratch->frame == 0); | ||||
free(scratch); | free(scratch); | ||||
} | } | ||||
} | } | ||||
static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { | static size_t secp256k1_scratch_max_allocation(const secp256k1_scratch* scratch, size_t objects) { | ||||
if (scratch->max_size <= objects * ALIGNMENT) { | size_t i = 0; | ||||
size_t allocated = 0; | |||||
for (i = 0; i < scratch->frame; i++) { | |||||
allocated += scratch->frame_size[i]; | |||||
} | |||||
if (scratch->max_size - allocated <= objects * ALIGNMENT) { | |||||
return 0; | return 0; | ||||
} | } | ||||
return scratch->max_size - objects * ALIGNMENT; | return scratch->max_size - allocated - objects * ALIGNMENT; | ||||
} | } | ||||
static int secp256k1_scratch_resize(secp256k1_scratch* scratch, size_t n, size_t objects) { | static int secp256k1_scratch_allocate_frame(secp256k1_scratch* scratch, size_t n, size_t objects) { | ||||
VERIFY_CHECK(scratch->frame < SECP256K1_SCRATCH_MAX_FRAMES); | |||||
Fabien: Should be `<=` since `scratch->frame` is a counter and not an index ? | |||||
deadalnixAuthorUnsubmitted Done Inline ActionsThis is as per the source material. This is correct if the frames are counted from 0; which they most likely are. deadalnix: This is as per the source material. This is correct if the frames are counted from 0; which… | |||||
FabienUnsubmitted Not Done Inline ActionsThis would be inconsistent with, for example, then assertion in secp256k1_scratch_destroy above: VERIFY_CHECK(scratch->frame == 0);. If the frames are counted from 0, then there might still be an allocated frame when the scratch is destroyed, causing a memory leak. Fabien: This would be inconsistent with, for example, then assertion in `secp256k1_scratch_destroy`… | |||||
deadalnixAuthorUnsubmitted Done Inline ActionsYou are correct. This is counting, but the code is correct anyways, because if we are going to allocate a new frame, then we want the frame count to be bellow the max, that that at the end of the process we reach at most the max number of frames. deadalnix: You are correct. This is counting, but the code is correct anyways, because if we are going to… | |||||
if (n <= secp256k1_scratch_max_allocation(scratch, objects)) { | |||||
n += objects * ALIGNMENT; | n += objects * ALIGNMENT; | ||||
if (n > scratch->init_size && n <= scratch->max_size) { | scratch->data[scratch->frame] = checked_malloc(scratch->error_callback, n); | ||||
void *tmp = checked_realloc(scratch->error_callback, scratch->data, n); | if (scratch->data[scratch->frame] == NULL) { | ||||
if (tmp == NULL) { | |||||
return 0; | return 0; | ||||
} | } | ||||
scratch->init_size = n; | scratch->frame_size[scratch->frame] = n; | ||||
scratch->data = tmp; | scratch->offset[scratch->frame] = 0; | ||||
scratch->frame++; | |||||
return 1; | |||||
} else { | |||||
return 0; | |||||
} | } | ||||
return n <= scratch->max_size; | } | ||||
static void secp256k1_scratch_deallocate_frame(secp256k1_scratch* scratch) { | |||||
VERIFY_CHECK(scratch->frame > 0); | |||||
scratch->frame -= 1; | |||||
free(scratch->data[scratch->frame]); | |||||
} | } | ||||
static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { | static void *secp256k1_scratch_alloc(secp256k1_scratch* scratch, size_t size) { | ||||
void *ret; | void *ret; | ||||
size_t frame = scratch->frame - 1; | |||||
size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; | size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; | ||||
if (size + scratch->offset > scratch->init_size) { | |||||
if (scratch->frame == 0 || size + scratch->offset[frame] > scratch->frame_size[frame]) { | |||||
return NULL; | return NULL; | ||||
} | } | ||||
ret = (void *) ((unsigned char *) scratch->data + scratch->offset); | ret = (void *) ((unsigned char *) scratch->data[frame] + scratch->offset[frame]); | ||||
memset(ret, 0, size); | memset(ret, 0, size); | ||||
scratch->offset += size; | scratch->offset[frame] += size; | ||||
return ret; | |||||
} | |||||
static void secp256k1_scratch_reset(secp256k1_scratch* scratch) { | return ret; | ||||
scratch->offset = 0; | |||||
} | } | ||||
#endif | #endif |
Should be <= since scratch->frame is a counter and not an index ?