From: Karthik Nayak Date: Tue, 23 Sep 2025 15:42:39 GMT Subject: Re: [PATCH v3 3/8] reftable: check for trailing newline in 'tables.list' Message-ID: In-Reply-To: Junio C Hamano writes: > Karthik Nayak writes: > >> diff --git a/reftable/basics.h b/reftable/basics.h >> index 7d22f96261..019dfe6d7e 100644 >> --- a/reftable/basics.h >> +++ b/reftable/basics.h >> @@ -167,10 +167,11 @@ void free_names(char **a); >> >> /* >> * Parse a newline separated list of names. `size` is the length of the buffer, >> - * without terminating '\0'. Empty names are discarded. Returns a `NULL` >> - * pointer when allocations fail. >> + * without terminating '\0'. Empty names are discarded. >> + * >> + * Errors are assigned to the `err` variable. >> */ >> -char **parse_names(char *buf, int size); >> +char **parse_names(char *buf, int size, int *err); >> >> /* compares two NULL-terminated arrays of strings. */ >> int names_equal(const char **a, const char **b); > > Makes sense. > >> diff --git a/reftable/stack.c b/reftable/stack.c >> index f91ce50bcd..955be1edb6 100644 >> --- a/reftable/stack.c >> +++ b/reftable/stack.c >> @@ -109,11 +109,9 @@ static int fd_read_lines(int fd, char ***namesp) >> } >> buf[size] = 0; >> >> - *namesp = parse_names(buf, size); >> - if (!*namesp) { >> - err = REFTABLE_OUT_OF_MEMORY_ERROR; >> + *namesp = parse_names(buf, size, &err); >> + if (!*namesp) >> goto done; > > Nice. > >> diff --git a/t/unit-tests/u-reftable-basics.c b/t/unit-tests/u-reftable-basics.c >> index a0471083e7..f77ec96429 100644 >> --- a/t/unit-tests/u-reftable-basics.c >> +++ b/t/unit-tests/u-reftable-basics.c >> @@ -9,6 +9,7 @@ license that can be found in the LICENSE file or at >> #include "unit-test.h" >> #include "lib-reftable.h" >> #include "reftable/basics.h" >> +#include "reftable/reftable-error.h" >> >> struct integer_needle_lesseq_args { >> int needle; >> @@ -79,14 +80,17 @@ void test_reftable_basics__names_equal(void) >> void test_reftable_basics__parse_names(void) >> { >> char in1[] = "line\n"; >> - char in2[] = "a\nb\nc"; >> - char **out = parse_names(in1, strlen(in1)); >> + char in2[] = "a\nb\nc\n"; >> + int err = 0; >> + char **out = parse_names(in1, strlen(in1), &err); >> + cl_assert(err == 0); >> cl_assert(out != NULL); >> cl_assert_equal_s(out[0], "line"); >> cl_assert(!out[1]); >> free_names(out); >> >> - out = parse_names(in2, strlen(in2)); >> + out = parse_names(in2, strlen(in2), &err); >> + cl_assert(err == 0); >> cl_assert(out != NULL); >> cl_assert_equal_s(out[0], "a"); >> cl_assert_equal_s(out[1], "b"); > > Sensible. > >> @@ -95,10 +99,21 @@ void test_reftable_basics__parse_names(void) >> free_names(out); >> } >> >> +void test_reftable_basics__parse_names_missing_newline(void) >> +{ >> + char in1[] = "line\nline2"; >> + int err = 0; >> + char **out = parse_names(in1, strlen(in1), &err); >> + cl_assert(err == REFTABLE_FORMAT_ERROR); >> + cl_assert(out == NULL); >> +} > > OK. > >> void test_reftable_basics__parse_names_drop_empty_string(void) >> { >> char in[] = "a\n\nb\n"; >> - char **out = parse_names(in, strlen(in)); >> + int err = 0; >> + char **out = parse_names(in, strlen(in), &err); >> + cl_assert(err == 0); > > I'll drop an extra SP after == here (no need to resend only to fix > this). > Ah! thanks for doing that. I'll patch it locally incase I need to reroll! Karthik