From: Junio C Hamano Date: Thu, 18 Sep 2025 15:36:07 GMT Subject: Re: [PATCH v3 3/8] reftable: check for trailing newline in 'tables.list' Message-ID: In-Reply-To: <20250918-228-reftable-introduce-consistency-checks-v3-3-271af03eb34d@gmail.com> 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). > cl_assert(out != NULL); > cl_assert_equal_s(out[0], "a"); > /* simply '\n' should be dropped as empty string */