commit f9723081c18b7e34cbf6bb15792c3965670deaab from: Mark Jamsek date: Sat Jun 01 06:08:33 2024 UTC plug 'got diff obj1 obj2' line metadata memory leak Despite API callers not requesting it, we collect line metadata due to NULL pointer checks missing a level of indirection. Reported by Kyle Ackerman. ok op and stsp commit - f57c91b34d24c53c184e2840aa0f616a96d4f764 commit + f9723081c18b7e34cbf6bb15792c3965670deaab blob - 245df76cba6ccd1d6c155ecbb3632f386db7f3e1 blob + d4752ffbbc8e2e4f0c5be0615e93a70e3625ff54 --- lib/diff.c +++ lib/diff.c @@ -146,12 +146,15 @@ diff_blobs(struct got_diff_line **lines, size_t *nline off_t outoff = 0; int n; - if (lines && *lines && *nlines > 0) - outoff = (*lines)[*nlines - 1].offset; - else if (lines) { - err = add_line_metadata(lines, nlines, 0, GOT_DIFF_LINE_NONE); - if (err) - goto done; + if (lines && *lines) { + if (*nlines > 0) + outoff = (*lines)[*nlines - 1].offset; + else { + err = add_line_metadata(lines, nlines, + 0, GOT_DIFF_LINE_NONE); + if (err != NULL) + goto done; + } } if (resultp) @@ -218,7 +221,7 @@ diff_blobs(struct got_diff_line **lines, size_t *nline if (n < 0) goto done; outoff += n; - if (lines) { + if (lines && *lines) { err = add_line_metadata(lines, nlines, outoff, GOT_DIFF_LINE_BLOB_MIN); if (err) @@ -230,7 +233,7 @@ diff_blobs(struct got_diff_line **lines, size_t *nline if (n < 0) goto done; outoff += n; - if (lines) { + if (lines && *lines) { err = add_line_metadata(lines, nlines, outoff, GOT_DIFF_LINE_BLOB_PLUS); if (err) blob - 5f1c310ce05497519a9838e46b29d28af595d0b4 blob + cbcf460ffedf9f49ee66c34cb6c42ef6af887b45 --- lib/diffreg.c +++ lib/diffreg.c @@ -272,13 +272,13 @@ got_diffreg_output(struct got_diff_line **lines, size_ switch (output_format) { case GOT_DIFF_OUTPUT_UNIDIFF: rc = diff_output_unidiff( - lines ? &output_info : NULL, outfile, &info, + lines && *lines ? &output_info : NULL, outfile, &info, diff_result->result, context_lines); if (rc != DIFF_RC_OK) return got_error_set_errno(rc, "diff_output_unidiff"); break; case GOT_DIFF_OUTPUT_PLAIN: - rc = diff_output_plain(lines ? &output_info : NULL, + rc = diff_output_plain(lines && *lines ? &output_info : NULL, outfile, &info, diff_result->result, 1); if (rc != DIFF_RC_OK) return got_error_set_errno(rc, "diff_output_edscript");