diff --git a/configure.in b/configure.in index 6ca5531e0..be1ee33ca 100644 --- a/configure.in +++ b/configure.in @@ -158,6 +158,28 @@ AM_CONDITIONAL(NAT_PMP, test x$natpmp = xtrue) AM_CONDITIONAL(MINIUPNPC, test x$upnp = xtrue) AM_PROG_CC_C_O +ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [ +AC_C_FLEXIBLE_ARRAY_MEMBER +], [ + dnl Maybe we've got an old autoconf... + AC_CACHE_CHECK([for flexible array members], + tor_cv_c_flexarray, + [AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([ + struct abc { int a; char b[]; }; +], [ + struct abc *def = malloc(sizeof(struct abc)+sizeof(char)); + def->b[0] = 33; +]), + [tor_cv_c_flexarray=yes], + [tor_cv_c_flexarray=no])]) + if test $tor_cv_flexarray = yes ; then + AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], []) + else + AC_DEFINE([FLEXIBLE_ARRAY_MEMBER], [1]) + fi +]) + AC_PATH_PROG([SHA1SUM], [sha1sum], none) AC_PATH_PROG([OPENSSL], [openssl], none) diff --git a/src/common/mempool.c b/src/common/mempool.c index c44492318..520e470c7 100644 --- a/src/common/mempool.c +++ b/src/common/mempool.c @@ -137,7 +137,8 @@ struct mp_chunk_t { int capacity; /**< Number of items that can be fit into this chunk. */ size_t mem_size; /**< Number of usable bytes in mem. */ char *next_mem; /**< Pointer into part of mem not yet carved up. */ - char mem[1]; /**< Storage for this chunk. (Not actual size.) */ + /** Storage for this chunk */ + char mem[FLEXIBLE_ARRAY_MEMBER]; }; /** Number of extra bytes needed beyond mem_size to allocate a chunk. */ diff --git a/src/or/buffers.c b/src/or/buffers.c index 9f393b987..48acf505e 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -68,8 +68,8 @@ typedef struct chunk_t { size_t datalen; /**< The number of bytes stored in this chunk */ size_t memlen; /**< The number of usable bytes of storage in mem. */ char *data; /**< A pointer to the first byte of data stored in mem. */ - char mem[1]; /**< The actual memory used for storage in this chunk. May be - * more than one byte long. */ + char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in + * this chunk. */ } chunk_t; #define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0]) diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 6c4f7eff2..5b440bc7c 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -191,7 +191,8 @@ var_cell_pack_header(const var_cell_t *cell, char *hdr_out) var_cell_t * var_cell_new(uint16_t payload_len) { - var_cell_t *cell = tor_malloc(sizeof(var_cell_t)+payload_len-1); + size_t size = STRUCT_OFFSET(var_cell_t, payload) + payload_len; + var_cell_t *cell = tor_malloc(size); cell->payload_len = payload_len; cell->command = 0; cell->circ_id = 0; diff --git a/src/or/or.h b/src/or/or.h index 2d1fbef59..8aef2d023 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -857,8 +857,8 @@ typedef struct cell_t { typedef struct var_cell_t { uint8_t command; circid_t circ_id; - uint16_t payload_len; - uint8_t payload[1]; + uint16_t payload_len; /**< The actual length of payload. */ + uint8_t payload[FLEXIBLE_ARRAY_MEMBER]; } var_cell_t; /** A cell as packed for writing to the network. */ @@ -1660,11 +1660,11 @@ typedef struct short_policy_t { unsigned int is_accept : 1; /** The actual number of values in 'entries'. */ unsigned int n_entries : 31; - /** An array of (probably more than 1!) short_policy_entry_t values, - * each descriping a range of ports that this policy accepts or rejects - * (depending on the value of is_accept). + /** An array of 0 or more short_policy_entry_t values, each descriping a + * range of ports that this policy accepts or rejects (depending on the + * value of is_accept). */ - short_policy_entry_t entries[1]; + short_policy_entry_t entries[FLEXIBLE_ARRAY_MEMBER]; } short_policy_t; /** A microdescriptor is the smallest amount of information needed to build a diff --git a/src/or/policies.c b/src/or/policies.c index 46a431a8d..e5af7887c 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1382,8 +1382,8 @@ parse_short_policy(const char *summary) } { - size_t size = sizeof(short_policy_t) + - sizeof(short_policy_entry_t)*(n_entries-1); + size_t size = STRUCT_OFFSET(short_policy_t, entries) + + sizeof(short_policy_entry_t)*(n_entries); result = tor_malloc_zero(size); tor_assert( (char*)&result->entries[n_entries-1] < ((char*)result)+size);