diff options
author | Junio C Hamano <gitster@pobox.com> | 2022-02-26 02:47:36 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-02-26 02:47:36 +0300 |
commit | 0a01df08c03fe707e22795de7bd1d763ed02e9e1 (patch) | |
tree | b9ff98081b5cacb5106d303d21378cc5aeb99278 | |
parent | 294f296292711cc26c8844be9bd7118a0190cf79 (diff) | |
parent | 974c919d36d944e9005def346fb363d8a83399f7 (diff) |
Merge branch 'ab/date-mode-release'
Plug (some) memory leaks around parse_date_format().
* ab/date-mode-release:
date API: add and use a date_mode_release()
date API: add basic API docs
date API: provide and use a DATE_MODE_INIT
date API: create a date.h, split from cache.h
cache.h: remove always unused show_date_human() declaration
-rw-r--r-- | archive-zip.c | 1 | ||||
-rw-r--r-- | builtin/am.c | 1 | ||||
-rw-r--r-- | builtin/commit.c | 1 | ||||
-rw-r--r-- | builtin/fast-import.c | 1 | ||||
-rw-r--r-- | builtin/show-branch.c | 1 | ||||
-rw-r--r-- | builtin/tag.c | 1 | ||||
-rw-r--r-- | cache.h | 50 | ||||
-rw-r--r-- | config.c | 1 | ||||
-rw-r--r-- | date.c | 9 | ||||
-rw-r--r-- | date.h | 74 | ||||
-rw-r--r-- | http-backend.c | 1 | ||||
-rw-r--r-- | ident.c | 1 | ||||
-rw-r--r-- | object-name.c | 1 | ||||
-rw-r--r-- | pretty.h | 10 | ||||
-rw-r--r-- | ref-filter.c | 3 | ||||
-rw-r--r-- | reflog-walk.h | 1 | ||||
-rw-r--r-- | refs.c | 1 | ||||
-rw-r--r-- | strbuf.c | 1 | ||||
-rw-r--r-- | t/helper/test-date.c | 5 | ||||
-rwxr-xr-x | t/t0006-date.sh | 2 |
20 files changed, 112 insertions, 54 deletions
diff --git a/archive-zip.c b/archive-zip.c index 2961e01c75..8ea9d1a5da 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -9,6 +9,7 @@ #include "object-store.h" #include "userdiff.h" #include "xdiff-interface.h" +#include "date.h" static int zip_date; static int zip_time; diff --git a/builtin/am.c b/builtin/am.c index c0a3ff7b27..0f4111bafa 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -34,6 +34,7 @@ #include "string-list.h" #include "packfile.h" #include "repository.h" +#include "pretty.h" /** * Returns the length of the first line of msg. diff --git a/builtin/commit.c b/builtin/commit.c index 33ca9e99c8..8b8bdad395 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -37,6 +37,7 @@ #include "help.h" #include "commit-reach.h" #include "commit-graph.h" +#include "pretty.h" static const char * const builtin_commit_usage[] = { N_("git commit [<options>] [--] <pathspec>..."), diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 2b2e28bad7..28f2b9cc91 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -19,6 +19,7 @@ #include "mem-pool.h" #include "commit-reach.h" #include "khash.h" +#include "date.h" #define PACK_ID_BITS 16 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1) diff --git a/builtin/show-branch.c b/builtin/show-branch.c index e12c5e80e3..330b0553b9 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -8,6 +8,7 @@ #include "parse-options.h" #include "dir.h" #include "commit-slab.h" +#include "date.h" static const char* show_branch_usage[] = { N_("git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n" diff --git a/builtin/tag.c b/builtin/tag.c index 134b3f1edf..2479da0704 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -20,6 +20,7 @@ #include "oid-array.h" #include "column.h" #include "ref-filter.h" +#include "date.h" static const char * const git_tag_usage[] = { N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n" @@ -1558,48 +1558,6 @@ struct object *repo_peel_to_type(struct repository *r, #define peel_to_type(name, namelen, obj, type) \ repo_peel_to_type(the_repository, name, namelen, obj, type) -enum date_mode_type { - DATE_NORMAL = 0, - DATE_HUMAN, - DATE_RELATIVE, - DATE_SHORT, - DATE_ISO8601, - DATE_ISO8601_STRICT, - DATE_RFC2822, - DATE_STRFTIME, - DATE_RAW, - DATE_UNIX -}; - -struct date_mode { - enum date_mode_type type; - const char *strftime_fmt; - int local; -}; - -/* - * Convenience helper for passing a constant type, like: - * - * show_date(t, tz, DATE_MODE(NORMAL)); - */ -#define DATE_MODE(t) date_mode_from_type(DATE_##t) -struct date_mode *date_mode_from_type(enum date_mode_type type); - -const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode); -void show_date_relative(timestamp_t time, struct strbuf *timebuf); -void show_date_human(timestamp_t time, int tz, const struct timeval *now, - struct strbuf *timebuf); -int parse_date(const char *date, struct strbuf *out); -int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset); -int parse_expiry_date(const char *date, timestamp_t *timestamp); -void datestamp(struct strbuf *out); -#define approxidate(s) approxidate_careful((s), NULL) -timestamp_t approxidate_careful(const char *, int *); -timestamp_t approxidate_relative(const char *date); -void parse_date_format(const char *format, struct date_mode *mode); -int date_overflows(timestamp_t date); -time_t tm_to_time_t(const struct tm *tm); - #define IDENT_STRICT 1 #define IDENT_NO_DATE 2 #define IDENT_NO_NAME 4 @@ -1646,14 +1604,6 @@ struct ident_split { int split_ident_line(struct ident_split *, const char *, int); /* - * Like show_date, but pull the timestamp and tz parameters from - * the ident_split. It will also sanity-check the values and produce - * a well-known sentinel date if they appear bogus. - */ -const char *show_ident_date(const struct ident_split *id, - const struct date_mode *mode); - -/* * Compare split idents for equality or strict ordering. Note that we * compare only the ident part of the line, ignoring any timestamp. * @@ -6,6 +6,7 @@ * */ #include "cache.h" +#include "date.h" #include "branch.h" #include "config.h" #include "environment.h" @@ -5,6 +5,7 @@ */ #include "cache.h" +#include "date.h" /* * This is like mktime, but without normalization of tm_wday and tm_yday. @@ -205,11 +206,10 @@ void show_date_relative(timestamp_t time, struct strbuf *timebuf) struct date_mode *date_mode_from_type(enum date_mode_type type) { - static struct date_mode mode; + static struct date_mode mode = DATE_MODE_INIT; if (type == DATE_STRFTIME) BUG("cannot create anonymous strftime date_mode struct"); mode.type = type; - mode.local = 0; return &mode; } @@ -993,6 +993,11 @@ void parse_date_format(const char *format, struct date_mode *mode) die("unknown date format %s", format); } +void date_mode_release(struct date_mode *mode) +{ + free((char *)mode->strftime_fmt); +} + void datestamp(struct strbuf *out) { time_t now; diff --git a/date.h b/date.h new file mode 100644 index 0000000000..5d4eaba0a9 --- /dev/null +++ b/date.h @@ -0,0 +1,74 @@ +#ifndef DATE_H +#define DATE_H + +/** + * The date mode type. This has DATE_NORMAL at an explicit "= 0" to + * accommodate a memset([...], 0, [...]) initialization when "struct + * date_mode" is used as an embedded struct member, as in the case of + * e.g. "struct pretty_print_context" and "struct rev_info". + */ +enum date_mode_type { + DATE_NORMAL = 0, + DATE_HUMAN, + DATE_RELATIVE, + DATE_SHORT, + DATE_ISO8601, + DATE_ISO8601_STRICT, + DATE_RFC2822, + DATE_STRFTIME, + DATE_RAW, + DATE_UNIX +}; + +struct date_mode { + enum date_mode_type type; + const char *strftime_fmt; + int local; +}; + +#define DATE_MODE_INIT { \ + .type = DATE_NORMAL, \ +} + +/** + * Convenience helper for passing a constant type, like: + * + * show_date(t, tz, DATE_MODE(NORMAL)); + */ +#define DATE_MODE(t) date_mode_from_type(DATE_##t) +struct date_mode *date_mode_from_type(enum date_mode_type type); + +/** + * Format <'time', 'timezone'> into static memory according to 'mode' + * and return it. The mode is an initialized "struct date_mode" + * (usually from the DATE_MODE() macro). + */ +const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode); + +/** + * Parse a date format for later use with show_date(). + * + * When the "date_mode_type" is DATE_STRFTIME the "strftime_fmt" + * member of "struct date_mode" will be a malloc()'d format string to + * be used with strbuf_addftime(), in which case you'll need to call + * date_mode_release() later. + */ +void parse_date_format(const char *format, struct date_mode *mode); + +/** + * Release a "struct date_mode", currently only required if + * parse_date_format() has parsed a "DATE_STRFTIME" format. + */ +void date_mode_release(struct date_mode *mode); + +void show_date_relative(timestamp_t time, struct strbuf *timebuf); +int parse_date(const char *date, struct strbuf *out); +int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset); +int parse_expiry_date(const char *date, timestamp_t *timestamp); +void datestamp(struct strbuf *out); +#define approxidate(s) approxidate_careful((s), NULL) +timestamp_t approxidate_careful(const char *, int *); +timestamp_t approxidate_relative(const char *date); +int date_overflows(timestamp_t date); +time_t tm_to_time_t(const struct tm *tm); +#endif diff --git a/http-backend.c b/http-backend.c index 807fb8839e..81a7229ece 100644 --- a/http-backend.c +++ b/http-backend.c @@ -13,6 +13,7 @@ #include "packfile.h" #include "object-store.h" #include "protocol.h" +#include "date.h" static const char content_type[] = "Content-Type"; static const char content_length[] = "Content-Length"; @@ -7,6 +7,7 @@ */ #include "cache.h" #include "config.h" +#include "date.h" static struct strbuf git_default_name = STRBUF_INIT; static struct strbuf git_default_email = STRBUF_INIT; diff --git a/object-name.c b/object-name.c index 0230a87416..f0e327f91f 100644 --- a/object-name.c +++ b/object-name.c @@ -15,6 +15,7 @@ #include "submodule.h" #include "midx.h" #include "commit-reach.h" +#include "date.h" static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *); @@ -2,6 +2,7 @@ #define PRETTY_H #include "cache.h" +#include "date.h" #include "string-list.h" struct commit; @@ -163,4 +164,13 @@ int format_set_trailers_options(struct process_trailer_options *opts, const char **arg, char **invalid_arg); +/* + * Like show_date, but pull the timestamp and tz parameters from + * the ident_split. It will also sanity-check the values and produce + * a well-known sentinel date if they appear bogus. + */ +const char *show_ident_date(const struct ident_split *id, + const struct date_mode *mode); + + #endif /* PRETTY_H */ diff --git a/ref-filter.c b/ref-filter.c index f7a2f17bfd..7838bd22b8 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1251,7 +1251,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam char *zone; timestamp_t timestamp; long tz; - struct date_mode date_mode = { DATE_NORMAL }; + struct date_mode date_mode = DATE_MODE_INIT; const char *formatp; /* @@ -1276,6 +1276,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam goto bad; v->s = xstrdup(show_date(timestamp, tz, &date_mode)); v->value = timestamp; + date_mode_release(&date_mode); return; bad: v->s = xstrdup(""); diff --git a/reflog-walk.h b/reflog-walk.h index f26408f6cc..e9e00ffd47 100644 --- a/reflog-walk.h +++ b/reflog-walk.h @@ -5,6 +5,7 @@ struct commit; struct reflog_walk_info; +struct date_mode; void init_reflog_walk(struct reflog_walk_info **info); int add_reflog_for_walk(struct reflog_walk_info *info, @@ -19,6 +19,7 @@ #include "strvec.h" #include "repository.h" #include "sigchain.h" +#include "date.h" /* * List of all available backends @@ -2,6 +2,7 @@ #include "refs.h" #include "string-list.h" #include "utf8.h" +#include "date.h" int starts_with(const char *str, const char *prefix) { diff --git a/t/helper/test-date.c b/t/helper/test-date.c index 099eff4f0f..45951b1df8 100644 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@ -1,5 +1,6 @@ #include "test-tool.h" #include "cache.h" +#include "date.h" static const char *usage_msg = "\n" " test-tool date relative [time_t]...\n" @@ -34,7 +35,7 @@ static void show_human_dates(const char **argv) static void show_dates(const char **argv, const char *format) { - struct date_mode mode; + struct date_mode mode = DATE_MODE_INIT; parse_date_format(format, &mode); for (; *argv; argv++) { @@ -53,6 +54,8 @@ static void show_dates(const char **argv, const char *format) printf("%s -> %s\n", *argv, show_date(t, tz, &mode)); } + + date_mode_release(&mode); } static void parse_dates(const char **argv) diff --git a/t/t0006-date.sh b/t/t0006-date.sh index 794186961e..2490162071 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test date parsing and printing' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # arbitrary reference time: 2009-08-30 19:20:00 |