bisect: check strbuf_getline_lf return when reading terms

get_terms() in builtin/bisect.c and read_bisect_terms() in bisect.c both read the BISECT_TERMS file but do not check the strbuf_getline_lf() return values. If the file is truncated (e.g., a partial write from a crash or disk-full condition), strbuf_getline_lf returns EOF and the strbuf remains empty. strbuf_detach then returns an empty string, and the term names silently become "" instead of the expected "bad"/"good" or custom terms. In get_terms(), check for EOF and return -1 on truncation, matching the existing -1 return for a missing file. In read_bisect_terms(), die with a descriptive message when a line cannot be read, consistent with the die_errno for a non-ENOENT open failure in the same function. Unlike get_terms(), read_bisect_terms() returns void and uses die() for all error paths, so the die is the appropriate error handling here. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jul 14, 2026 at 22:48 UTC bd97cddf278f81189487e742db2f394d94163764
2 files changed +12 -4
bisect.c
+4 -2
@@ -1019,10 +1019,12 @@ void read_bisect_terms(char **read_bad, char **read_good)
1019 die_errno(_("could not read file '%s'"), filename);
1020 }
1021 } else {
1022 - strbuf_getline_lf(&str, fp);
1022 + if (strbuf_getline_lf(&str, fp) == EOF)
1023 + die(_("could not read bad term from file '%s'"), filename);
1024 free(*read_bad);
1025 *read_bad = strbuf_detach(&str, NULL);
1025 - strbuf_getline_lf(&str, fp);
1026 + if (strbuf_getline_lf(&str, fp) == EOF)
1027 + die(_("could not read good term from file '%s'"), filename);
1028 free(*read_good);
1029 *read_good = strbuf_detach(&str, NULL);
1030 }
builtin/bisect.c
+8 -2
@@ -498,9 +498,15 @@ static int get_terms(struct bisect_terms *terms)
498 }
499
500 free_terms(terms);
501 - strbuf_getline_lf(&str, fp);
501 + if (strbuf_getline_lf(&str, fp) == EOF) {
502 + res = -1;
503 + goto finish;
504 + }
505 terms->term_bad = strbuf_detach(&str, NULL);
503 - strbuf_getline_lf(&str, fp);
506 + if (strbuf_getline_lf(&str, fp) == EOF) {
507 + res = -1;
508 + goto finish;
509 + }
510 terms->term_good = strbuf_detach(&str, NULL);
511
512 finish: