change resize functions to handle overflow gravefully, added backport header for C89 types and macros, moved some functions to extensions.c/.h

AuthorKonata <konata@posteo.jp>
Date
Commit3144ea2ef24360e7d77e6caf120c74ca0cd9b9fb
Parenta12f15d
12 files changed, 218 insertions(+), 75 deletions(-)
▾Ainclude/cutils/backport.h
@@ -0,0 +1,119 @@
#ifndef BACKPORT_H
#define BACKPORT_H
#include <limits.h>
#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
#include <stdbool.h>
#else
#ifndef SIZE_MAX
#define SIZE_MAX (size_t)-1
#endif /* SIZE_MAX */
#ifndef CUTILS_NO_BOOL
typedef enum {false = 0, true = !false} bool;
#endif /* CUTILS_NO_BOOL */
#ifndef CUTILS_NO_MAX
#ifdef ULLONG_MAX
#define UINTMAX_MAX ULLONG_MAX
typedef unsigned long long uintmax_t;
#else
#define UINTMAX_MAX ULONG_MAX
typedef unsigned long uintmax_t;
#endif
#ifdef LLONG_MAX
#define INTMAX_MAX LLONG_MAX
#define INTMAX_MIN LLONG_MIN
typedef unsigned long long intmax_t;
#else
#define INTMAX_MAX LONG_MAX
#define INTMAX_MIN LONG_MIN
typedef unsigned long intmax_t;
#endif
#endif /* CUTILS_NO_MAX */
#ifndef CUTILS_NO_LEAST
#define UINTLEAST8_MAX UCHAR_MAX
typedef unsigned char uint_least8_t;
#define UINT8_C(x) ((uint_least8_t)x)
#define UINTLEAST16_MAX USHRT_MAX
typedef unsigned short uint_least16_t;
#define UINT16_C(x) ((uint_least16_t)x)
#define UINTLEAST32_MAX ULONG_MAX
typedef unsigned long uint_least32_t;
#define UINT32_C(x) ((uint_least32_t)x)
#ifdef ULLONG_MAX
#define UINTLEAST64_MAX ULLONG_MAX
typedef unsigned long long uint_least64_t;
#define UINT64_C(x) ((uint_least64_t)x)
#endif /* ULLONG_MAX */
#define INTLEAST8_MAX SCHAR_MAX
#define INTLEAST8_MIN SCHAR_MIN
typedef signed char int_least8_t;
#define INT8_C(x) ((int_least8_t)x)
#define INTLEAST16_MAX SHRT_MAX
#define INTLEAST16_MIN SHRT_MIN
typedef short int_least16_t;
#define INT16_C(x) ((int_least16_t)x)
#define INTLEAST32_MAX LONG_MAX
#define INTLEAST32_MIN LONG_MIN
typedef long int_least32_t;
#define INT32_C(x) ((int_least32_t)x)
#ifdef LLONG_MAX
#define INTLEAST64_MAX LLONG_MAX
#define INTLEAST64_MIN LLONG_MIN
typedef long long int_least64_t;
#define INT64_C(x) ((int_least64_t)x)
#endif /* LLONG_MAX */
#endif /* CUTILS_NO_LEAST */
/* for now just copy least types */
#ifndef CUTILS_NO_FAST
#define UINTFAST8_MAX UCHAR_MAX
typedef unsigned char uint_fast8_t;
#define UINTFAST16_MAX USHRT_MAX
typedef unsigned short uint_fast16_t;
#define UINTFAST32_MAX ULONG_MAX
typedef unsigned long uint_fast32_t;
#ifdef ULLONG_MAX
#define UINTFAST64_MAX ULLONG_MAX
typedef unsigned long long uint_fast64_t;
#endif /* ULLONG_MAX */
#define INTFAST8_MAX SCHAR_MAX
#define INTFAST8_MIN SCHAR_MIN
typedef signed char int_fast8_t;
#define INTFAST16_MAX SHRT_MAX
#define INTFAST16_MIN SHRT_MIN
typedef short int_fast16_t;
#define INTFAST32_MAX LONG_MAX
#define INTFAST32_MIN LONG_MIN
typedef long int_fast32_t;
#ifdef LLONG_MAX
#define INTFAST64_MAX LLONG_MAX
#define INTFAST64_MIN LLONG_MIN
typedef long long int_fast64_t;
#endif /* LLONG_MAX */
#endif /* CUTILS_NO_FAST */
#endif
#endif /* BACKPORT_H */
▾Minclude/cutils/common.h
@@ -1,19 +1,8 @@
#ifndef CUTILS_COMMON_H
#define CUTILS_COMMON_H
#include <stddef.h>
#include <cutils/backport.h>
#include <cutils/hedley.h>
#ifndef SIZE_MAX
#define SIZE_MAX (size_t)-1;
#endif
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
#ifndef CUTILS_NO_BOOL
typedef enum {false = 0, true = 1} bool;
#endif
#endif
#include <cutils/extensions.h>
#endif /* CUTILS_COMMON_H */
▾Minclude/cutils/cutils.h
@@ -6,5 +6,7 @@
#include <cutils/misc.h>
#include <cutils/byte_array.h>
#include <cutils/linked-list.h>
#include <cutils/extensions.h>
#include <cutils/backport.h>
#endif /* CUTILS_H */
▾Ainclude/cutils/extensions.h
@@ -0,0 +1,42 @@
#ifndef EXTENSIONS_H
#define EXTENSIONS_H
#include <cutils/hedley.h>
#include <errno.h>
#include <stdlib.h>
#include <cutils/backport.h>
#include <string.h>
#include <ctype.h>
int strcmp_nocase(const char* s1, const char* s2);
int strncmp_nocase(const char* s1, const char* s2, size_t n);
HEDLEY_INLINE
static void* reallocsafe(void *ptr, size_t nmemb, size_t size)
{
size_t new_size = nmemb * size;
if(nmemb != 0 && new_size / nmemb != size)
{
errno = ENOMEM;
return NULL;
} else {
return realloc(ptr, new_size);
}
}
HEDLEY_INLINE
static void* reallocsafe_inc(void *ptr, size_t nmemb, size_t size, size_t add)
{
if(SIZE_MAX - add < size)
{
errno = ENOMEM;
return NULL;
} else {
return reallocsafe(ptr, nmemb, size+add);
}
}
#endif /* EXTENSIONS_H */
▾Minclude/cutils/misc.h
@@ -20,8 +20,6 @@
#include <ctype.h>
#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
typedef uintmax_t max_uint_t;
#ifdef UINT32_MAX
uint32_t ntoh32(uint32_t const net);
#endif
@@ -34,8 +32,6 @@
memcpy(item2, tmp, length);
free(tmp);
}
#else
typedef unsigned long max_uint_t;
#endif
HEDLEY_INLINE
@@ -68,13 +64,11 @@ static void memqswap(void* item1, void* item2, void* tmp, size_t length)
#endif
void sleep_ms(unsigned int milliseconds);
int strcmp_nocase(const char* s1, const char* s2);
int strncmp_nocase(const char* s1, const char* s2, size_t n);
#if __STDC_VERSION__ >= 201112L
struct timespec timespec_diff(const struct timespec* old_ts, const struct timespec* new_ts);
struct timespec timespec_add(const struct timespec* ts_1, const struct timespec* ts_2);
max_uint_t timespec_ms(const struct timespec* ts);
uintmax_t timespec_ms(const struct timespec* ts);
#endif
#endif /* MISC_H */
▾Mmeson.build
@@ -1,7 +1,7 @@
project('cutils', 'c')
WARNINGS = ['-Wall', '-Wpedantic', '-Wextra', '-Wnull-dereference', '-Wshadow', '-Wconversion', '-Wstrict-prototypes', '-Wmissing-prototypes', '-Wcast-qual', '-Wstrict-overflow=5', '-Wunreachable-code', '-Wno-unused-parameter', '-Wno-unused-function']
CFLAGS = ['-std=c89', '-fstrict-aliasing', '-fPIC'] + WARNINGS
CFLAGS = ['-std=c89', '-fstrict-aliasing', '-fPIC', '-Wno-long-long'] + WARNINGS
subdir('include')
subdir('src')
▾Msrc/byte_array.c
@@ -68,7 +68,7 @@ bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item)
size_t length = bytearray->length;
size_t size = bytearray->element_size;
if(index > length || !bytearray_adjust_size(bytearray, length+1))
if(index > length || length == SIZE_MAX || !bytearray_adjust_size(bytearray, length+1))
return false;
memmove(bytearray->items+index*size+1*size, bytearray->items+index*size, (length*size-index*size)*sizeof(*bytearray->items));
@@ -86,7 +86,7 @@ void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*))
if(rmv)
rmv(&bytearray->items[index*elsize]);
memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, (length*elsize-index*elsize-1*elsize)*sizeof(*bytearray->items));
memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, length*elsize-index*elsize-1*elsize);
bytearray->length--;
}
}
@@ -95,10 +95,8 @@ bool bytearray_adjust_size(Bytearray* bytearray, size_t size)
{
while(bytearray->capacity < size)
{
size_t capacity = bytearray->capacity;
size_t elsize = bytearray->element_size;
char* tmp = bytearray->items;
bytearray->items = realloc(bytearray->items, capacity*elsize*2*sizeof(*bytearray->items));
bytearray->items = reallocsafe_inc(bytearray->items, sizeof(*bytearray->items), bytearray->capacity, bytearray->capacity);
if(!bytearray->items)
{
bytearray->items = tmp;
@@ -113,10 +111,8 @@ bool bytearray_shrink(Bytearray* bytearray)
{
while(bytearray->capacity > bytearray->length*2)
{
size_t capacity = bytearray->capacity;
size_t size = bytearray->element_size;
char* tmp = bytearray->items;
bytearray->items = realloc(bytearray->items, (capacity*size)/(2*sizeof(*bytearray->items)));
bytearray->items = realloc(bytearray->items, (bytearray->capacity*bytearray->element_size)/2);
if(!bytearray->items)
{
bytearray->items = tmp;
▾Msrc/dyn_string.c
@@ -37,7 +37,7 @@ void string_remove_range(String* string, size_t index, size_t length)
bool string_insert(String* string, size_t index, char character)
{
if(index > string->length || !string_adjust_size(string, string->length))
if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length))
return false;
memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars));
@@ -117,7 +117,7 @@ bool string_adjust_size(String* string, size_t size)
while(string->capacity < size)
{
char* tmp = string->chars;
string->chars = realloc(string->chars, string->capacity*2*(sizeof(*string->chars)));
string->chars = reallocsafe_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
if(!string->chars)
{
string->chars = tmp;
▾Asrc/extensions.c
@@ -0,0 +1,40 @@
#include <cutils/extensions.h>
int strcmp_nocase(const char* s1, const char* s2)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
unsigned char c1, c2;
do
{
c1 = (unsigned char)tolower(*p1++);
c2 = (unsigned char)tolower(*p2++);
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
int strncmp_nocase(const char* s1, const char* s2, size_t n)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
unsigned char c1, c2;
if(n == 0)
return 0;
do
{
c1 = (unsigned char)tolower(*p1++);
c2 = (unsigned char)tolower(*p2++);
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2 && --n);
return c1 - c2;
}
▾Msrc/meson.build
@@ -1,4 +1,4 @@
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c']
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c', 'extensions.c']
srctest = src + ['test.c']
cutils_lib = library('cutils', src, include_directories : inc, install: true)
▾Msrc/misc.c
@@ -10,45 +10,6 @@ void sleep_ms(unsigned int milliseconds)
#endif
}
int strcmp_nocase(const char* s1, const char* s2)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
unsigned char c1, c2;
do
{
c1 = (unsigned char)tolower(*p1++);
c2 = (unsigned char)tolower(*p2++);
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
int strncmp_nocase(const char* s1, const char* s2, size_t n)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
unsigned char c1, c2;
if(n == 0)
return 0;
do
{
c1 = (unsigned char)tolower(*p1++);
c2 = (unsigned char)tolower(*p2++);
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2 && --n);
return c1 - c2;
}
#if __STDC_VERSION__ >= 199901L
#ifdef UINT32_MAX
uint32_t ntoh32(uint32_t const net)
@@ -98,8 +59,8 @@ struct timespec timespec_add(const struct timespec* ts_1, const struct timespec*
}
max_uint_t timespec_ms(const struct timespec* ts)
uintmax_t timespec_ms(const struct timespec* ts)
{
return (max_uint_t)ts->tv_sec * 1000 + (max_uint_t)ts->tv_nsec/1000000;
return (uintmax_t)ts->tv_sec * 1000 + (uintmax_t)ts->tv_nsec/1000000;
}
#endif
▾Msrc/vector.c
@@ -76,7 +76,7 @@ size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const
bool vector_insert(Vector* vector, size_t index, void* item)
{
if(index > vector->length || !vector_adjust_size(vector, vector->length+1))
if(index > vector->length || vector->length == SIZE_MAX || !vector_adjust_size(vector, vector->length+1))
return false;
memmove(vector->items+index+1, vector->items+index, (vector->length-index)*sizeof(*vector->items));
@@ -90,7 +90,7 @@ bool vector_adjust_size(Vector* vector, size_t size)
while(vector->capacity < size)
{
void** tmp = vector->items;
vector->items = realloc(vector->items, vector->capacity*2*sizeof(*vector->items));
vector->items = reallocsafe_inc(vector->items, sizeof(*vector->items), vector->capacity, vector->capacity);
if(!vector->items)
{
vector->items = tmp;