Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Always return a non-NULL pointer for malloc(0).
Some C runtimes, like musl, will return NULL in this case. It's more
convenient to not get a NULL (which is meant to be interpreted as a failure),
but instead get a non-NULL pointer that can't be dereferenced (because
it's a pointer to zero bytes of memory).
  • Loading branch information
icculus committed May 4, 2018
1 parent 2cf3ac4 commit dfa17bf
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 10 deletions.
6 changes: 4 additions & 2 deletions mojoshader.c
Expand Up @@ -307,9 +307,10 @@ static inline void out_of_memory(Context *ctx)
ctx->isfail = ctx->out_of_memory = 1;
} // out_of_memory

static char zeromalloc = 0;
static inline void *Malloc(Context *ctx, const size_t len)
{
void *retval = ctx->malloc((int) len, ctx->malloc_data);
void *retval = (len == 0) ? &zeromalloc : ctx->malloc((int) len, ctx->malloc_data);
if (retval == NULL)
out_of_memory(ctx);
return retval;
Expand All @@ -325,7 +326,8 @@ static inline char *StrDup(Context *ctx, const char *str)

static inline void Free(Context *ctx, void *ptr)
{
ctx->free(ptr, ctx->malloc_data);
if ((ptr != &zeromalloc) && (ptr != NULL))
ctx->free(ptr, ctx->malloc_data);
} // Free

static void * MOJOSHADERCALL MallocBridge(int bytes, void *data)
Expand Down
6 changes: 4 additions & 2 deletions mojoshader_assembler.c
Expand Up @@ -72,9 +72,10 @@ static inline void out_of_memory(Context *ctx)
ctx->isfail = ctx->out_of_memory = 1;
} // out_of_memory

static char zeromalloc = 0;
static inline void *Malloc(Context *ctx, const size_t len)
{
void *retval = ctx->malloc((int) len, ctx->malloc_data);
void *retval = (len == 0) ? &zeromalloc : ctx->malloc((int) len, ctx->malloc_data);
if (retval == NULL)
out_of_memory(ctx);
return retval;
Expand All @@ -90,7 +91,8 @@ static inline char *StrDup(Context *ctx, const char *str)

static inline void Free(Context *ctx, void *ptr)
{
ctx->free(ptr, ctx->malloc_data);
if ((ptr != &zeromalloc) && (ptr != NULL))
ctx->free(ptr, ctx->malloc_data);
} // Free

static void *MallocBridge(int bytes, void *data)
Expand Down
6 changes: 4 additions & 2 deletions mojoshader_compiler.c
Expand Up @@ -160,9 +160,10 @@ static inline void out_of_memory(Context *ctx)
ctx->isfail = ctx->out_of_memory = 1;
} // out_of_memory

static char zeromalloc = 0;
static inline void *Malloc(Context *ctx, const size_t len)
{
void *retval = ctx->malloc((int) len, ctx->malloc_data);
void *retval = (len == 0) ? &zeromalloc : ctx->malloc((int) len, ctx->malloc_data);
if (retval == NULL)
out_of_memory(ctx);
return retval;
Expand All @@ -178,7 +179,8 @@ static inline char *StrDup(Context *ctx, const char *str)

static inline void Free(Context *ctx, void *ptr)
{
ctx->free(ptr, ctx->malloc_data);
if ((ptr != &zeromalloc) && (ptr != NULL))
ctx->free(ptr, ctx->malloc_data);
} // Free

static void *MallocBridge(int bytes, void *data)
Expand Down
5 changes: 3 additions & 2 deletions mojoshader_opengl.c
Expand Up @@ -347,17 +347,18 @@ static inline void out_of_memory(void)
set_error("out of memory");
} // out_of_memory

static char zeromalloc = 0;
static inline void *Malloc(const size_t len)
{
void *retval = ctx->malloc_fn((int) len, ctx->malloc_data);
void *retval = (len == 0) ? &zeromalloc : ctx->malloc_fn((int) len, ctx->malloc_data);
if (retval == NULL)
out_of_memory();
return retval;
} // Malloc

static inline void Free(void *ptr)
{
if (ptr != NULL)
if ((ptr != &zeromalloc) && (ptr != NULL))
ctx->free_fn(ptr, ctx->malloc_data);
} // Free

Expand Down
6 changes: 4 additions & 2 deletions mojoshader_preprocessor.c
Expand Up @@ -68,17 +68,19 @@ static inline void out_of_memory(Context *ctx)
ctx->out_of_memory = 1;
} // out_of_memory

static char zeromalloc = 0;
static inline void *Malloc(Context *ctx, const size_t len)
{
void *retval = ctx->malloc((int) len, ctx->malloc_data);
void *retval = (len == 0) ? &zeromalloc : ctx->malloc((int) len, ctx->malloc_data);
if (retval == NULL)
out_of_memory(ctx);
return retval;
} // Malloc

static inline void Free(Context *ctx, void *ptr)
{
ctx->free(ptr, ctx->malloc_data);
if ((ptr != &zeromalloc) && (ptr != NULL))
ctx->free(ptr, ctx->malloc_data);
} // Free

static void *MallocBridge(int bytes, void *data)
Expand Down

0 comments on commit dfa17bf

Please sign in to comment.