Skip to content

Commit 89fb9db

Browse files
committed
AVRO-4193 support for empty bytes
When avro-c tries to encode an empty byte array it will avro_malloc(0) which on some architectures will return NULL. Make sure this is not interpreted as an error or or dereferenced causing a segfault.
1 parent 1e9a16a commit 89fb9db

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

lang/c/src/datum.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ static avro_datum_t avro_bytes_private(char *bytes, int64_t size,
156156
avro_datum_t avro_bytes(const char *bytes, int64_t size)
157157
{
158158
char *bytes_copy = (char *) avro_malloc(size);
159-
if (!bytes_copy) {
159+
if (!bytes_copy && size) {
160160
avro_set_error("Cannot copy bytes content");
161161
return NULL;
162162
}
@@ -197,7 +197,7 @@ int avro_bytes_set(avro_datum_t datum, const char *bytes, const int64_t size)
197197
{
198198
int rval;
199199
char *bytes_copy = (char *) avro_malloc(size);
200-
if (!bytes_copy) {
200+
if (!bytes_copy && size) {
201201
avro_set_error("Cannot copy bytes content");
202202
return ENOMEM;
203203
}

lang/c/src/value-json.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ encode_utf8_bytes(const void *src, size_t src_len,
6262

6363
// Allocate a new buffer for the UTF-8 string and fill it in.
6464
uint8_t *dest8 = (uint8_t *) avro_malloc(utf8_len);
65-
if (dest8 == NULL) {
65+
if (dest8 == NULL && utf8_len) {
6666
avro_set_error("Cannot allocate JSON bytes buffer");
6767
return ENOMEM;
6868
}
@@ -126,7 +126,7 @@ avro_value_to_json_t(const avro_value_t *value)
126126
return NULL;
127127
}
128128

129-
json_t *result = json_stringn_nocheck((const char *) encoded, encoded_size);
129+
json_t *result = json_stringn_nocheck((const char *) encoded ? encoded : "", encoded_size);
130130
avro_free(encoded, encoded_size);
131131
if (result == NULL) {
132132
avro_set_error("Cannot allocate JSON bytes");

lang/c/tests/test_avro_data.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,20 @@ test_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
4040
AVRO_UNUSED(osize);
4141

4242
if (nsize == 0) {
43-
size_t *size = ((size_t *) ptr) - 1;
44-
if (osize != *size) {
45-
fprintf(stderr,
46-
"Error freeing %p:\n"
47-
"Size passed to avro_free (%" PRIsz ") "
48-
"doesn't match size passed to "
49-
"avro_malloc (%" PRIsz ")\n",
50-
ptr, osize, *size);
51-
abort();
52-
//exit(EXIT_FAILURE);
43+
if (ptr) {
44+
size_t *size = ((size_t *) ptr) - 1;
45+
if (osize != *size) {
46+
fprintf(stderr,
47+
"Error freeing %p:\n"
48+
"Size passed to avro_free (%" PRIsz ") "
49+
"doesn't match size passed to "
50+
"avro_malloc (%" PRIsz ")\n",
51+
ptr, osize, *size);
52+
abort();
53+
//exit(EXIT_FAILURE);
54+
}
55+
free(size);
5356
}
54-
free(size);
5557
return NULL;
5658
} else {
5759
size_t real_size = nsize + sizeof(size_t);
@@ -214,6 +216,34 @@ static int test_bytes(void)
214216
return 0;
215217
}
216218

219+
static int test_empty_bytes(void)
220+
{
221+
char bytes[] = { };
222+
avro_schema_t writer_schema = avro_schema_bytes();
223+
avro_datum_t datum;
224+
avro_datum_t expected_datum;
225+
226+
datum = avro_givebytes(bytes, sizeof(bytes), NULL);
227+
write_read_check(writer_schema, datum, NULL, NULL, "bytes");
228+
test_json(datum, "\"\"");
229+
avro_datum_decref(datum);
230+
avro_schema_decref(writer_schema);
231+
232+
datum = avro_givebytes(NULL, 0, NULL);
233+
avro_givebytes_set(datum, bytes, sizeof(bytes), NULL);
234+
expected_datum = avro_givebytes(bytes, sizeof(bytes), NULL);
235+
if (!avro_datum_equal(datum, expected_datum)) {
236+
fprintf(stderr,
237+
"Expected equal bytes instances.\n");
238+
exit(EXIT_FAILURE);
239+
}
240+
avro_datum_decref(datum);
241+
avro_datum_decref(expected_datum);
242+
243+
avro_schema_decref(writer_schema);
244+
return 0;
245+
}
246+
217247
static int test_int32(void)
218248
{
219249
int i;
@@ -657,6 +687,7 @@ int main(void)
657687
{
658688
"string", test_string}, {
659689
"bytes", test_bytes}, {
690+
"empty_bytes", test_empty_bytes}, {
660691
"int", test_int32}, {
661692
"long", test_int64}, {
662693
"float", test_float}, {

0 commit comments

Comments
 (0)