Git fork

Merge branch 'rs/date-mode-pass-by-value'

The codepaths that reach date_mode_from_type() have been updated to
pass "struct date_mode" by value to make them thread safe.

* rs/date-mode-pass-by-value:
date: make DATE_MODE thread-safe

+44 -44
+2 -2
builtin/blame.c
··· 316 316 size_t time_width; 317 317 int tz; 318 318 tz = atoi(tz_str); 319 - time_str = show_date(time, tz, &blame_date_mode); 319 + time_str = show_date(time, tz, blame_date_mode); 320 320 strbuf_addstr(&time_buf, time_str); 321 321 /* 322 322 * Add space paddings to time_buf to display a fixed width ··· 1029 1029 blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700"); 1030 1030 break; 1031 1031 case DATE_STRFTIME: 1032 - blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */ 1032 + blame_date_width = strlen(show_date(0, 0, blame_date_mode)) + 1; /* add the null */ 1033 1033 break; 1034 1034 } 1035 1035 blame_date_width -= 1; /* strip the null */
+18 -18
date.c
··· 207 207 (diff + 183) / 365); 208 208 } 209 209 210 - struct date_mode *date_mode_from_type(enum date_mode_type type) 210 + struct date_mode date_mode_from_type(enum date_mode_type type) 211 211 { 212 - static struct date_mode mode = DATE_MODE_INIT; 212 + struct date_mode mode = DATE_MODE_INIT; 213 213 if (type == DATE_STRFTIME) 214 214 BUG("cannot create anonymous strftime date_mode struct"); 215 215 mode.type = type; 216 - return &mode; 216 + return mode; 217 217 } 218 218 219 219 static void show_date_normal(struct strbuf *buf, timestamp_t time, struct tm *tm, int tz, struct tm *human_tm, int human_tz, int local) ··· 283 283 strbuf_addf(buf, " %+05d", tz); 284 284 } 285 285 286 - const char *show_date(timestamp_t time, int tz, const struct date_mode *mode) 286 + const char *show_date(timestamp_t time, int tz, struct date_mode mode) 287 287 { 288 288 struct tm *tm; 289 289 struct tm tmbuf = { 0 }; ··· 291 291 int human_tz = -1; 292 292 static struct strbuf timebuf = STRBUF_INIT; 293 293 294 - if (mode->type == DATE_UNIX) { 294 + if (mode.type == DATE_UNIX) { 295 295 strbuf_reset(&timebuf); 296 296 strbuf_addf(&timebuf, "%"PRItime, time); 297 297 return timebuf.buf; 298 298 } 299 299 300 - if (mode->type == DATE_HUMAN) { 300 + if (mode.type == DATE_HUMAN) { 301 301 struct timeval now; 302 302 303 303 get_time(&now); ··· 306 306 human_tz = local_time_tzoffset(now.tv_sec, &human_tm); 307 307 } 308 308 309 - if (mode->local) 309 + if (mode.local) 310 310 tz = local_tzoffset(time); 311 311 312 - if (mode->type == DATE_RAW) { 312 + if (mode.type == DATE_RAW) { 313 313 strbuf_reset(&timebuf); 314 314 strbuf_addf(&timebuf, "%"PRItime" %+05d", time, tz); 315 315 return timebuf.buf; 316 316 } 317 317 318 - if (mode->type == DATE_RELATIVE) { 318 + if (mode.type == DATE_RELATIVE) { 319 319 strbuf_reset(&timebuf); 320 320 show_date_relative(time, &timebuf); 321 321 return timebuf.buf; 322 322 } 323 323 324 - if (mode->local) 324 + if (mode.local) 325 325 tm = time_to_tm_local(time, &tmbuf); 326 326 else 327 327 tm = time_to_tm(time, tz, &tmbuf); ··· 331 331 } 332 332 333 333 strbuf_reset(&timebuf); 334 - if (mode->type == DATE_SHORT) 334 + if (mode.type == DATE_SHORT) 335 335 strbuf_addf(&timebuf, "%04d-%02d-%02d", tm->tm_year + 1900, 336 336 tm->tm_mon + 1, tm->tm_mday); 337 - else if (mode->type == DATE_ISO8601) 337 + else if (mode.type == DATE_ISO8601) 338 338 strbuf_addf(&timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d", 339 339 tm->tm_year + 1900, 340 340 tm->tm_mon + 1, 341 341 tm->tm_mday, 342 342 tm->tm_hour, tm->tm_min, tm->tm_sec, 343 343 tz); 344 - else if (mode->type == DATE_ISO8601_STRICT) { 344 + else if (mode.type == DATE_ISO8601_STRICT) { 345 345 strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d", 346 346 tm->tm_year + 1900, 347 347 tm->tm_mon + 1, ··· 354 354 tz = abs(tz); 355 355 strbuf_addf(&timebuf, "%02d:%02d", tz / 100, tz % 100); 356 356 } 357 - } else if (mode->type == DATE_RFC2822) 357 + } else if (mode.type == DATE_RFC2822) 358 358 strbuf_addf(&timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d", 359 359 weekday_names[tm->tm_wday], tm->tm_mday, 360 360 month_names[tm->tm_mon], tm->tm_year + 1900, 361 361 tm->tm_hour, tm->tm_min, tm->tm_sec, tz); 362 - else if (mode->type == DATE_STRFTIME) 363 - strbuf_addftime(&timebuf, mode->strftime_fmt, tm, tz, 364 - !mode->local); 362 + else if (mode.type == DATE_STRFTIME) 363 + strbuf_addftime(&timebuf, mode.strftime_fmt, tm, tz, 364 + !mode.local); 365 365 else 366 - show_date_normal(&timebuf, time, tm, tz, &human_tm, human_tz, mode->local); 366 + show_date_normal(&timebuf, time, tm, tz, &human_tm, human_tz, mode.local); 367 367 return timebuf.buf; 368 368 } 369 369
+3 -3
date.h
··· 22 22 23 23 struct date_mode { 24 24 enum date_mode_type type; 25 - const char *strftime_fmt; 26 25 int local; 26 + const char *strftime_fmt; 27 27 }; 28 28 29 29 #define DATE_MODE_INIT { \ ··· 36 36 * show_date(t, tz, DATE_MODE(NORMAL)); 37 37 */ 38 38 #define DATE_MODE(t) date_mode_from_type(DATE_##t) 39 - struct date_mode *date_mode_from_type(enum date_mode_type type); 39 + struct date_mode date_mode_from_type(enum date_mode_type type); 40 40 41 41 /** 42 42 * Format <'time', 'timezone'> into static memory according to 'mode' 43 43 * and return it. The mode is an initialized "struct date_mode" 44 44 * (usually from the DATE_MODE() macro). 45 45 */ 46 - const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode); 46 + const char *show_date(timestamp_t time, int timezone, struct date_mode mode); 47 47 48 48 /** 49 49 * Parse a date format for later use with show_date().
+1 -1
gpg-interface.c
··· 483 483 484 484 if (sigc->payload_timestamp) 485 485 strbuf_addf(&verify_time, "-Overify-time=%s", 486 - show_date(sigc->payload_timestamp, 0, &verify_date_mode)); 486 + show_date(sigc->payload_timestamp, 0, verify_date_mode)); 487 487 488 488 /* Find the principal from the signers */ 489 489 strvec_pushl(&ssh_keygen.args, fmt->program,
+1 -1
log-tree.c
··· 773 773 */ 774 774 show_reflog_message(opt->reflog_info, 775 775 opt->commit_format == CMIT_FMT_ONELINE, 776 - &opt->date_mode, 776 + opt->date_mode, 777 777 opt->date_mode_explicit); 778 778 if (opt->commit_format == CMIT_FMT_ONELINE) 779 779 return;
+3 -3
oss-fuzz/fuzz-date.c
··· 11 11 int16_t tz; 12 12 timestamp_t ts; 13 13 enum date_mode_type dmtype; 14 - struct date_mode *dm; 14 + struct date_mode dm; 15 15 16 16 if (size <= 4) 17 17 /* ··· 40 40 free(str); 41 41 42 42 dm = date_mode_from_type(dmtype); 43 - dm->local = local; 43 + dm.local = local; 44 44 show_date(ts, (int)tz, dm); 45 45 46 - date_mode_release(dm); 46 + date_mode_release(&dm); 47 47 48 48 return 0; 49 49 }
+9 -9
pretty.c
··· 428 428 } 429 429 430 430 const char *show_ident_date(const struct ident_split *ident, 431 - const struct date_mode *mode) 431 + struct date_mode mode) 432 432 { 433 433 timestamp_t date = 0; 434 434 long tz = 0; ··· 592 592 switch (pp->fmt) { 593 593 case CMIT_FMT_MEDIUM: 594 594 strbuf_addf(sb, "Date: %s\n", 595 - show_ident_date(&ident, &pp->date_mode)); 595 + show_ident_date(&ident, pp->date_mode)); 596 596 break; 597 597 case CMIT_FMT_EMAIL: 598 598 case CMIT_FMT_MBOXRD: ··· 601 601 break; 602 602 case CMIT_FMT_FULLER: 603 603 strbuf_addf(sb, "%sDate: %s\n", what, 604 - show_ident_date(&ident, &pp->date_mode)); 604 + show_ident_date(&ident, pp->date_mode)); 605 605 break; 606 606 default: 607 607 /* notin' */ ··· 775 775 776 776 static size_t format_person_part(struct strbuf *sb, char part, 777 777 const char *msg, int len, 778 - const struct date_mode *dmode) 778 + struct date_mode dmode) 779 779 { 780 780 /* currently all placeholders have same length */ 781 781 const int placeholder_len = 2; ··· 1034 1034 static int format_reflog_person(struct strbuf *sb, 1035 1035 char part, 1036 1036 struct reflog_walk_info *log, 1037 - const struct date_mode *dmode) 1037 + struct date_mode dmode) 1038 1038 { 1039 1039 const char *ident; 1040 1040 ··· 1602 1602 if (c->pretty_ctx->reflog_info) 1603 1603 get_reflog_selector(sb, 1604 1604 c->pretty_ctx->reflog_info, 1605 - &c->pretty_ctx->date_mode, 1605 + c->pretty_ctx->date_mode, 1606 1606 c->pretty_ctx->date_mode_explicit, 1607 1607 (placeholder[1] == 'd')); 1608 1608 return 2; ··· 1617 1617 return format_reflog_person(sb, 1618 1618 placeholder[1], 1619 1619 c->pretty_ctx->reflog_info, 1620 - &c->pretty_ctx->date_mode); 1620 + c->pretty_ctx->date_mode); 1621 1621 } 1622 1622 return 0; /* unknown %g placeholder */ 1623 1623 case 'N': ··· 1712 1712 case 'a': /* author ... */ 1713 1713 return format_person_part(sb, placeholder[1], 1714 1714 msg + c->author.off, c->author.len, 1715 - &c->pretty_ctx->date_mode); 1715 + c->pretty_ctx->date_mode); 1716 1716 case 'c': /* committer ... */ 1717 1717 return format_person_part(sb, placeholder[1], 1718 1718 msg + c->committer.off, c->committer.len, 1719 - &c->pretty_ctx->date_mode); 1719 + c->pretty_ctx->date_mode); 1720 1720 case 'e': /* encoding */ 1721 1721 if (c->commit_encoding) 1722 1722 strbuf_addstr(sb, c->commit_encoding);
+1 -1
pretty.h
··· 167 167 * a well-known sentinel date if they appear bogus. 168 168 */ 169 169 const char *show_ident_date(const struct ident_split *id, 170 - const struct date_mode *mode); 170 + struct date_mode mode); 171 171 172 172 173 173 #endif /* PRETTY_H */
+1 -1
ref-filter.c
··· 1627 1627 tz = strtol(zone, NULL, 10); 1628 1628 if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE) 1629 1629 goto bad; 1630 - v->s = xstrdup(show_date(timestamp, tz, &date_mode)); 1630 + v->s = xstrdup(show_date(timestamp, tz, date_mode)); 1631 1631 v->value = timestamp; 1632 1632 date_mode_release(&date_mode); 1633 1633 return;
+2 -2
reflog-walk.c
··· 223 223 224 224 void get_reflog_selector(struct strbuf *sb, 225 225 struct reflog_walk_info *reflog_info, 226 - const struct date_mode *dmode, int force_date, 226 + struct date_mode dmode, int force_date, 227 227 int shorten) 228 228 { 229 229 struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog; ··· 297 297 } 298 298 299 299 void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline, 300 - const struct date_mode *dmode, int force_date) 300 + struct date_mode dmode, int force_date) 301 301 { 302 302 if (reflog_info && reflog_info->last_commit_reflog) { 303 303 struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
+2 -2
reflog-walk.h
··· 10 10 int add_reflog_for_walk(struct reflog_walk_info *info, 11 11 struct commit *commit, const char *name); 12 12 void show_reflog_message(struct reflog_walk_info *info, int, 13 - const struct date_mode *, int force_date); 13 + struct date_mode, int force_date); 14 14 void get_reflog_message(struct strbuf *sb, 15 15 struct reflog_walk_info *reflog_info); 16 16 const char *get_reflog_ident(struct reflog_walk_info *reflog_info); 17 17 timestamp_t get_reflog_timestamp(struct reflog_walk_info *reflog_info); 18 18 void get_reflog_selector(struct strbuf *sb, 19 19 struct reflog_walk_info *reflog_info, 20 - const struct date_mode *dmode, int force_date, 20 + struct date_mode dmode, int force_date, 21 21 int shorten); 22 22 23 23 int reflog_walk_empty(struct reflog_walk_info *walk);
+1 -1
t/helper/test-date.c
··· 52 52 arg++; 53 53 tz = atoi(arg); 54 54 55 - printf("%s -> %s\n", *argv, show_date(t, tz, &mode)); 55 + printf("%s -> %s\n", *argv, show_date(t, tz, mode)); 56 56 } 57 57 58 58 date_mode_release(&mode);