Skip to content

Commit dd0d388

Browse files
peffgitster
authored andcommitted
logmsg_reencode: never return NULL
The logmsg_reencode function will return the reencoded commit buffer, or NULL if reencoding failed or no reencoding was necessary. Since every caller then ends up checking for NULL and just using the commit's original buffer, anyway, we can be a bit more helpful and just return that buffer when we would have returned NULL. Since the resulting string may or may not need to be freed, we introduce a logmsg_free, which checks whether the buffer came from the commit object or not (callers either implemented the same check already, or kept two separate pointers, one to mark the buffer to be used, and one for the to-be-freed string). Pushing this logic into logmsg_* simplifies the callers, and will let future patches lazily load the commit buffer in a single place. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 200ebe3 commit dd0d388

File tree

4 files changed

+29
-33
lines changed

4 files changed

+29
-33
lines changed

builtin/blame.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ static void get_commit_info(struct commit *commit,
14201420
{
14211421
int len;
14221422
const char *subject, *encoding;
1423-
char *reencoded, *message;
1423+
char *message;
14241424

14251425
commit_info_init(ret);
14261426

@@ -1438,14 +1438,13 @@ static void get_commit_info(struct commit *commit,
14381438
sha1_to_hex(commit->object.sha1));
14391439
}
14401440
encoding = get_log_output_encoding();
1441-
reencoded = logmsg_reencode(commit, encoding);
1442-
message = reencoded ? reencoded : commit->buffer;
1441+
message = logmsg_reencode(commit, encoding);
14431442
get_ac_line(message, "\nauthor ",
14441443
&ret->author, &ret->author_mail,
14451444
&ret->author_time, &ret->author_tz);
14461445

14471446
if (!detailed) {
1448-
free(reencoded);
1447+
logmsg_free(message, commit);
14491448
return;
14501449
}
14511450

@@ -1459,7 +1458,7 @@ static void get_commit_info(struct commit *commit,
14591458
else
14601459
strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));
14611460

1462-
free(reencoded);
1461+
logmsg_free(message, commit);
14631462
}
14641463

14651464
/*

builtin/commit.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -946,24 +946,14 @@ static void handle_untracked_files_arg(struct wt_status *s)
946946

947947
static const char *read_commit_message(const char *name)
948948
{
949-
const char *out_enc, *out;
949+
const char *out_enc;
950950
struct commit *commit;
951951

952952
commit = lookup_commit_reference_by_name(name);
953953
if (!commit)
954954
die(_("could not lookup commit %s"), name);
955955
out_enc = get_commit_output_encoding();
956-
out = logmsg_reencode(commit, out_enc);
957-
958-
/*
959-
* If we failed to reencode the buffer, just copy it
960-
* byte for byte so the user can try to fix it up.
961-
* This also handles the case where input and output
962-
* encodings are identical.
963-
*/
964-
if (out == NULL)
965-
out = commit->buffer;
966-
return out;
956+
return logmsg_reencode(commit, out_enc);
967957
}
968958

969959
static int parse_and_validate_options(int argc, const char *argv[],

commit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ extern int has_non_ascii(const char *text);
101101
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
102102
extern char *logmsg_reencode(const struct commit *commit,
103103
const char *output_encoding);
104+
extern void logmsg_free(char *msg, const struct commit *commit);
104105
extern void get_commit_format(const char *arg, struct rev_info *);
105106
extern const char *format_subject(struct strbuf *sb, const char *msg,
106107
const char *line_separator);

pretty.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,11 @@ static void add_merge_info(const struct pretty_print_context *pp,
524524
strbuf_addch(sb, '\n');
525525
}
526526

527-
static char *get_header(const struct commit *commit, const char *key)
527+
static char *get_header(const struct commit *commit, const char *msg,
528+
const char *key)
528529
{
529530
int key_len = strlen(key);
530-
const char *line = commit->buffer;
531+
const char *line = msg;
531532

532533
while (line) {
533534
const char *eol = strchr(line, '\n'), *next;
@@ -588,25 +589,36 @@ char *logmsg_reencode(const struct commit *commit,
588589
static const char *utf8 = "UTF-8";
589590
const char *use_encoding;
590591
char *encoding;
592+
char *msg = commit->buffer;
591593
char *out;
592594

593595
if (!output_encoding || !*output_encoding)
594-
return NULL;
595-
encoding = get_header(commit, "encoding");
596+
return msg;
597+
encoding = get_header(commit, msg, "encoding");
596598
use_encoding = encoding ? encoding : utf8;
597599
if (same_encoding(use_encoding, output_encoding))
598600
if (encoding) /* we'll strip encoding header later */
599601
out = xstrdup(commit->buffer);
600602
else
601-
return NULL; /* nothing to do */
603+
return msg; /* nothing to do */
602604
else
603605
out = reencode_string(commit->buffer,
604606
output_encoding, use_encoding);
605607
if (out)
606608
out = replace_encoding_header(out, output_encoding);
607609

608610
free(encoding);
609-
return out;
611+
/*
612+
* If the re-encoding failed, out might be NULL here; in that
613+
* case we just return the commit message verbatim.
614+
*/
615+
return out ? out : msg;
616+
}
617+
618+
void logmsg_free(char *msg, const struct commit *commit)
619+
{
620+
if (msg != commit->buffer)
621+
free(msg);
610622
}
611623

612624
static int mailmap_name(const char **email, size_t *email_len,
@@ -1278,14 +1290,11 @@ void format_commit_message(const struct commit *commit,
12781290
context.pretty_ctx = pretty_ctx;
12791291
context.wrap_start = sb->len;
12801292
context.message = logmsg_reencode(commit, output_enc);
1281-
if (!context.message)
1282-
context.message = commit->buffer;
12831293

12841294
strbuf_expand(sb, format, format_commit_item, &context);
12851295
rewrap_message_tail(sb, &context, 0, 0, 0);
12861296

1287-
if (context.message != commit->buffer)
1288-
free(context.message);
1297+
logmsg_free(context.message, commit);
12891298
free(context.signature.gpg_output);
12901299
free(context.signature.signer);
12911300
}
@@ -1432,7 +1441,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
14321441
{
14331442
unsigned long beginning_of_body;
14341443
int indent = 4;
1435-
const char *msg = commit->buffer;
1444+
const char *msg;
14361445
char *reencoded;
14371446
const char *encoding;
14381447
int need_8bit_cte = pp->need_8bit_cte;
@@ -1443,10 +1452,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
14431452
}
14441453

14451454
encoding = get_log_output_encoding();
1446-
reencoded = logmsg_reencode(commit, encoding);
1447-
if (reencoded) {
1448-
msg = reencoded;
1449-
}
1455+
msg = reencoded = logmsg_reencode(commit, encoding);
14501456

14511457
if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL)
14521458
indent = 0;
@@ -1503,7 +1509,7 @@ void pretty_print_commit(const struct pretty_print_context *pp,
15031509
if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body)
15041510
strbuf_addch(sb, '\n');
15051511

1506-
free(reencoded);
1512+
logmsg_free(reencoded, commit);
15071513
}
15081514

15091515
void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,

0 commit comments

Comments
 (0)