Skip to content

Commit

Permalink
Address LeakSanitizer errors in unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nirosys committed Jul 7, 2022
1 parent 312503f commit 67fa600
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 47 deletions.
39 changes: 34 additions & 5 deletions test/test_ion_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ TEST(IonWriterAddAnnotation, SameInTextAndBinary) {
ION_ASSERT_OK(ion_event_stream_read_all_from_bytes(binary_data, binary_len, NULL, &binary_stream));
ION_ASSERT_OK(ion_event_stream_read_all_from_bytes(text_data, text_len, NULL, &text_stream));
ASSERT_TRUE(ion_compare_streams(&binary_stream, &text_stream));
free(binary_data);
free(text_data);
}

TEST(IonBinaryTimestamp, WriterConvertsToUTC) {
Expand All @@ -79,6 +81,8 @@ TEST(IonBinaryTimestamp, WriterConvertsToUTC) {

// Expected: 2008-02-29T23:59 with offset of +1 minutes.
assertBytesEqual("\xE0\x01\x00\xEA\x67\x81\x0F\xD8\x82\x9D\x97\xBB", 12, result, result_len);

free(result);
}

TEST(IonBinaryTimestamp, ReaderConvertsFromUTC) {
Expand Down Expand Up @@ -115,6 +119,8 @@ TEST(IonBinaryTimestamp, WriterIgnoresSuperfluousOffset) {

// Expected: 0001T with unknown local offset (C0 == -0 == unknown local offset).
assertBytesEqual("\xE0\x01\x00\xEA\x62\xC0\x81", 7, result, result_len);

free(result);
}

TEST(IonBinaryTimestamp, ReaderIgnoresSuperfluousOffset) {
Expand Down Expand Up @@ -149,6 +155,7 @@ TEST(IonBinarySymbol, WriterWritesSymbolValueThatLooksLikeSymbolZero) {
// NOTE: the symbol value refers to \x0A (i.e. SID 10 -- a local symbol), NOT \x00 (SID 0). This is because the
// ion_writer_write_symbol API, which takes a string from the user, was used.
assertBytesEqual("\x71\x0A", 2, result + result_len - 2, 2);
free(result);
}

TEST(IonBinarySymbol, WriterWritesSymbolValueSymbolZero) {
Expand All @@ -163,6 +170,7 @@ TEST(IonBinarySymbol, WriterWritesSymbolValueSymbolZero) {

// NOTE: symbol zero is NOT added to the local symbol table. Symbol zero is not present in ANY symbol table.
assertBytesEqual("\xE0\x01\x00\xEA\x70", 5, result, result_len);
free(result);
}

TEST(IonBinarySymbol, WriterWritesAnnotationThatLooksLikeSymbolZero) {
Expand All @@ -182,6 +190,7 @@ TEST(IonBinarySymbol, WriterWritesAnnotationThatLooksLikeSymbolZero) {
// NOTE: the annotation refers to \x8A (i.e. SID 10 -- a local symbol), NOT \x80 (SID 0). This is because the
// ion_writer_add_annotation API, which takes a string from the user, was used.
assertBytesEqual("\xE3\x81\x8A\x70", 4, result + result_len - 4, 4);
free(result);
}

TEST(IonBinarySymbol, WriterWritesAnnotationSymbolZero) {
Expand All @@ -197,6 +206,7 @@ TEST(IonBinarySymbol, WriterWritesAnnotationSymbolZero) {

// NOTE: symbol zero is NOT added to the local symbol table. Symbol zero is not present in ANY symbol table.
assertBytesEqual("\xE0\x01\x00\xEA\xE3\x81\x80\x70", 8, result, result_len);
free(result);
}

TEST(IonBinarySymbol, WriterWritesFieldNameThatLooksLikeSymbolZero) {
Expand All @@ -219,6 +229,7 @@ TEST(IonBinarySymbol, WriterWritesFieldNameThatLooksLikeSymbolZero) {
// NOTE: the field name and annotation refer to \x8A (i.e. SID 10 -- a local symbol), NOT \x80 (SID 0).
// This is due to use of APIs that accept a string from the user.
assertBytesEqual("\xD5\x8A\xE3\x81\x8A\x70", 6, result + result_len - 6, 6);
free(result);
}

TEST(IonBinarySymbol, WriterWritesFieldNameSymbolZero) {
Expand All @@ -237,6 +248,7 @@ TEST(IonBinarySymbol, WriterWritesFieldNameSymbolZero) {

// NOTE: symbol zero is NOT added to the local symbol table. Symbol zero is not present in ANY symbol table.
assertBytesEqual("\xE0\x01\x00\xEA\xD5\x80\xE3\x81\x80\x70", 10, result, result_len);
free(result);
}

TEST(IonBinarySymbol, ReaderReadsSymbolValueZeroAsString) {
Expand Down Expand Up @@ -293,6 +305,7 @@ TEST(IonBinarySymbol, WriterWritesSymbolValueIVM) {
ION_ASSERT_OK(ion_test_writer_get_bytes(writer, ion_stream, &result, &result_len));

assertBytesEqual("\xE0\x01\x00\xEA\x20\x21\x01\x21\x02", 9, result, result_len);
free(result);
}

TEST(IonBinarySymbol, ReaderReadsSymbolValueIVMNoOpAtEOF) {
Expand Down Expand Up @@ -345,6 +358,7 @@ TEST(IonBinaryReader, UnpositionedReaderHasTypeNone) {
ION_ASSERT_OK(ion_reader_open_buffer(&reader, data, 4, NULL));
ION_ASSERT_OK(ion_reader_get_type(reader, &type));
ASSERT_EQ(tid_none, type);
ION_ASSERT_OK(ion_reader_close(reader));
}

TEST(IonBinarySymbol, ReaderReadsNullSymbol) {
Expand Down Expand Up @@ -392,6 +406,7 @@ void test_ion_binary_write_from_reader_rejects_negative_zero_int(BYTE *data, siz
ION_ASSERT_FAIL(ion_writer_write_one_value(writer, reader));
ION_ASSERT_OK(ion_writer_close(writer));
ION_ASSERT_OK(ion_reader_close(reader));
ION_ASSERT_OK(ion_stream_close(stream));
}

TEST(IonBinaryInt, ReaderRejectsNegativeZeroMixedIntOneByte) {
Expand All @@ -406,7 +421,7 @@ void test_ion_binary_reader_threshold_for_int64_as_big_int(BYTE *data, size_t le
hREADER reader;
ION_TYPE type;
int64_t value;
ION_INT big_int_expected;
ION_INT *big_int_expected;
SIZE str_len, written;

ION_ASSERT_OK(ion_reader_open_buffer(&reader, data, len, NULL));
Expand All @@ -417,16 +432,21 @@ void test_ion_binary_reader_threshold_for_int64_as_big_int(BYTE *data, size_t le
ASSERT_EQ(IERR_NUMERIC_OVERFLOW,ion_reader_read_int64(reader, &value));

// initialize ION_INT and read it as big integer
ION_ASSERT_OK(ion_int_init(&big_int_expected, NULL));
ION_ASSERT_OK(ion_reader_read_ion_int(reader, &big_int_expected));
ION_ASSERT_OK(ion_int_alloc(NULL, &big_int_expected));
ION_ASSERT_OK(ion_int_init(big_int_expected, NULL));
ION_ASSERT_OK(ion_reader_read_ion_int(reader, big_int_expected));
ION_ASSERT_OK(ion_reader_close(reader));

// convert big integer to string for comparison
ion_int_char_length(&big_int_expected, &str_len);
ion_int_char_length(big_int_expected, &str_len);
char *int_str = (char *)malloc(str_len * sizeof(char));
ion_int_to_char(&big_int_expected, (BYTE *)int_str, str_len, &written);
ion_int_to_char(big_int_expected, (BYTE *)int_str, str_len, &written);
ion_int_free(big_int_expected);

// compare string representation of the value
ASSERT_STREQ(actual_value, int_str);

free(int_str);
}

void test_ion_binary_reader_threshold_for_int64_as_int64(BYTE *data, size_t len, int64_t actual_value) {
Expand All @@ -443,6 +463,8 @@ void test_ion_binary_reader_threshold_for_int64_as_int64(BYTE *data, size_t len,

// compare actual and generated int64 values
ASSERT_EQ(actual_value, value);

ION_ASSERT_OK(ion_reader_close(reader));
}

TEST(IonBinaryReader, ReaderPositiveThresholdForInt64) {
Expand All @@ -468,6 +490,7 @@ void test_ion_binary_reader_requires_timestamp_fraction_less_than_one(BYTE *data
ION_ASSERT_OK(ion_reader_next(reader, &type));
ASSERT_EQ(tid_TIMESTAMP, type);
ASSERT_EQ(IERR_INVALID_BINARY, ion_reader_read_timestamp(reader, &ts));
ION_ASSERT_OK(ion_reader_close(reader));
}

TEST(IonBinaryTimestamp, ReaderRequiresTimestampFractionLessThanOne) {
Expand All @@ -489,6 +512,7 @@ void test_ion_binary_reader_supports_32_bit_floats(BYTE *data, size_t len, float
ASSERT_EQ(tid_FLOAT, type);
ION_ASSERT_OK(ion_reader_read_double(reader, &actual));
ASSERT_FLOAT_EQ(expected, (float) actual);
ION_ASSERT_OK(ion_reader_close(reader));
}

TEST(IonBinaryFloat, ReaderSupports32BitFloats) {
Expand Down Expand Up @@ -526,6 +550,7 @@ TEST(IonBinaryFloat, ReaderSupports32BitFloatNan) {
ION_ASSERT_OK(ion_reader_read_double(reader, &actual));
ASSERT_TRUE(std::isnan(nan));
ASSERT_TRUE(std::isnan(actual));
ION_ASSERT_OK(ion_reader_close(reader));
}

/**
Expand Down Expand Up @@ -619,6 +644,8 @@ void test_ion_binary_writer_supports_32_bit_floats(float value, const char *expe
ION_ASSERT_OK(ion_test_writer_get_bytes(writer, ion_stream, &result, &result_len));

assertBytesEqual(expected, expected_len, result, result_len);

free(result);
}


Expand Down Expand Up @@ -662,6 +689,8 @@ void test_ion_binary_writer_supports_compact_floats(BOOL compact_floats, double
ION_ASSERT_OK(ion_test_writer_get_bytes(writer, ion_stream, &result, &result_len));

assertBytesEqual(expected, expected_len, result, result_len);

free(result);
}

TEST(IonBinaryFloat, WriterSupportsCompactFloatsOption) {
Expand Down
14 changes: 14 additions & 0 deletions test/test_ion_cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ TEST(IonCli, ProcessSymbolsWithUnknownTextWithoutCatalog) {
test_ion_cli_process(filepath.c_str(), IO_TYPE_FILE, &command_output, &report, OUTPUT_TYPE_EVENTS);
ASSERT_FALSE(report.hasComparisonFailures());
ASSERT_FALSE(report.hasErrors());

IonCliCommonArgs common_args;
test_ion_cli_init_common_args(&common_args);
IonEventStream stream;
Expand Down Expand Up @@ -507,11 +508,14 @@ TEST(IonCli, FirstValueHasError) {
ASSERT_FALSE(report1.hasComparisonFailures());
ASSERT_TRUE(report1.hasErrors());
char *events = ion_string_strdup(&command_output);
ion_cli_free_command_output(&command_output);
test_ion_cli_process(events, IO_TYPE_MEMORY, &command_output, &report2);
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
ASSERT_EQ(0, command_output.length);
free(events);

ion_cli_free_command_output(&command_output);
}

TEST(IonCli, ParsingFailureDoesNotYieldEvent) {
Expand All @@ -523,11 +527,14 @@ TEST(IonCli, ParsingFailureDoesNotYieldEvent) {
ASSERT_FALSE(report1.hasComparisonFailures());
ASSERT_TRUE(report1.hasErrors());
char *events = ion_string_strdup(&command_output);
ion_cli_free_command_output(&command_output);
test_ion_cli_process(events, IO_TYPE_MEMORY, &command_output, &report2);
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
ASSERT_EQ(0, command_output.length);
free(events);

ion_cli_free_command_output(&command_output);
}

TEST(IonCli, ComparingBadListWithElementsFromEventStreamSucceeds) {
Expand All @@ -543,6 +550,8 @@ TEST(IonCli, ComparingBadListWithElementsFromEventStreamSucceeds) {
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
free(events);

ion_cli_free_command_output(&command_output);
}

TEST(IonCli, ComparingBadListWithoutElementsFromEventStreamSucceeds) {
Expand All @@ -558,6 +567,8 @@ TEST(IonCli, ComparingBadListWithoutElementsFromEventStreamSucceeds) {
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
free(events);

ion_cli_free_command_output(&command_output);
}

TEST(IonCli, ComparingSymbolZeroFromEventStreamSucceeds) {
Expand All @@ -573,6 +584,7 @@ TEST(IonCli, ComparingSymbolZeroFromEventStreamSucceeds) {
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
free(events);
ion_cli_free_command_output(&command_output);
}

TEST(IonCli, ComparingInnerVersionMarkersSucceeds) {
Expand All @@ -588,4 +600,6 @@ TEST(IonCli, ComparingInnerVersionMarkersSucceeds) {
ASSERT_FALSE(report2.hasComparisonFailures());
ASSERT_FALSE(report2.hasErrors());
free(events);

ion_cli_free_command_output(&command_output);
}
5 changes: 4 additions & 1 deletion test/test_ion_decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,15 @@
ION_ASSERT_OK(ion_writer_write_ion_decimal(writer, &ion_decimal)); \
ION_ASSERT_OK(ion_test_writer_get_bytes(writer, ion_stream, &result, &result_len));


#define ION_DECIMAL_BINARY_READER_EXPECT_OVERFLOW(func, decimal_digits) \
ION_DECIMAL_TEXT_TO_BINARY(decimal_digits); \
ION_ASSERT_OK(ion_reader_close(reader)); \
reader = NULL; \
/* This new reader only supports decQuad precision, which the input exceeds. */ \
ION_DECIMAL_EXPECT_OVERFLOW(func, DECQUAD_Pmax); \
free(result); \
ION_DECIMAL_FREE_1(&ion_decimal); \
ION_DECIMAL_FREE_1(&ion_decimal);


/* Reading/writing tests */
Expand Down
1 change: 0 additions & 1 deletion test/test_ion_extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ TEST(IonExtractorSucceedsWhen, ARelativePathMatches) {
ION_ASSERT_OK(ion_reader_next(reader, &type)); // foo
ASSERT_EQ(tid_STRUCT, type);
ION_ASSERT_OK(ion_reader_step_in(reader)); //bar
ION_ASSERT_OK(ion_extractor_open(&extractor, &options));

ION_EXTRACTOR_TEST_PATH_FROM_TEXT("(baz)", &assertMatchesInt1or3);
ION_EXTRACTOR_TEST_PATH_FROM_TEXT("(foo bar baz)", &assertPathNeverMatches); // Never matches because the extractor is scoped at depth 2.
Expand Down
19 changes: 13 additions & 6 deletions test/test_ion_integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,25 @@ iERR test_ion_int_to_int64_t_overflow_detection(const char * p_chars) {
const uint32_t max_string_length = 32;
uint32_t string_length = strnlen(p_chars, max_string_length);
// Create an uninitialized Ion integer.
ION_INT iint;
ION_INT *iint = NULL;
// Create an int64_t that we will later populate with the value of iint.
int64_t value_out;

// Allocate ION_INT on the heap so we don't have to free the inner data manually.
ion_int_alloc(NULL, &iint);
// Initialize the Ion integer, setting its owner to NULL.
IONCHECK(ion_int_init(&iint, NULL));
IONCHECK(ion_int_init(iint, NULL));
// Populate the Ion integer with the value of the provided base-10 string
IONCHECK(ion_int_from_chars(&iint, p_chars, string_length));
IONCHECK(ion_int_from_chars(iint, p_chars, string_length));
// Attempt to read the Ion integer's value back out into the int64_t.
// If the number is outside the range of values that can be represented by
// an int64_t, this should return IERR_NUMERIC_OVERFLOW.
IONCHECK(ion_int_to_int64(&iint, &value_out));
iRETURN;
IONCHECK(ion_int_to_int64(iint, &value_out));

fail:
ion_int_free(iint);

RETURN(__location_name__, __line__, __count__++, err);
}

TEST(IonInteger, IIntToInt64Overflow) {
Expand Down Expand Up @@ -118,4 +125,4 @@ TEST(IonInteger, IIntToInt64Overflow) {
iERR error_value = test_ion_int_to_int64_t_overflow_detection(oversized_integer);
ASSERT_EQ(error_value, IERR_NUMERIC_OVERFLOW);
}
}
}
13 changes: 11 additions & 2 deletions test/test_ion_reader_seek.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,9 @@ TEST_P(TextAndBinary, ReaderHandlesContainerValueOffsetSeek) {
ION_ASSERT_OK(ion_reader_seek(reader, pos_second, -1));
ION_ASSERT_OK(ion_reader_next(reader, &type));
ASSERT_EQ(tid_SYMBOL, type);

ION_ASSERT_OK(ion_reader_close(reader));
free(data);
}

TEST_P(TextAndBinary, ReaderHandlesInitialUnannotatedContainerValueOffsetSeek) {
Expand Down Expand Up @@ -679,6 +682,8 @@ TEST_P(TextAndBinary, ReaderHandlesInitialUnannotatedContainerValueOffsetSeek) {
ION_ASSERT_OK(ion_reader_seek(reader, pos_second, -1));
ION_ASSERT_OK(ion_reader_next(reader, &type));
ASSERT_EQ(tid_SYMBOL, type);
ION_ASSERT_OK(ion_reader_close(reader));
free(data);
}

TEST_P(TextAndBinary, ReaderPopulatesStructFieldsOnSeek) {
Expand Down Expand Up @@ -709,7 +714,7 @@ TEST_P(TextAndBinary, ReaderPopulatesStructFieldsOnSeek) {
hREADER reader = NULL;
ION_TYPE type;
POSITION pos_field1, pos_field2;
ION_STRING read_field1, read_val1, read_field2, read_val2;
ION_STRING read_val1, read_val2;

// We use this reader to capture offsets
ION_ASSERT_OK(ion_test_new_reader(data, data_length, &reader));
Expand Down Expand Up @@ -751,10 +756,14 @@ TEST_P(TextAndBinary, ReaderPopulatesStructFieldsOnSeek) {
char *cread_val2 = ion_string_strdup(&read_val2);

ION_ASSERT_OK(ion_reader_close(reader));
free(data);

// Assert:

// Easy assertions: there's only one value, "value," and we should have read it both times
assertStringsEqual((char *)value1.value, cread_val1, strlen(cread_val1));
assertStringsEqual((char *)value2.value, cread_val2, strlen(cread_val2));
}

free(cread_val1);
free(cread_val2);
}
Loading

0 comments on commit 67fa600

Please sign in to comment.