Skip to content

Commit

Permalink
[tz] handle invalid timezone
Browse files Browse the repository at this point in the history
Related to #1291
  • Loading branch information
tstack committed Aug 1, 2024
1 parent d45646f commit 586b507
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 26 deletions.
59 changes: 46 additions & 13 deletions src/base/time_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,26 @@ get_posix_zone(const char* name)
}
}

static const date::time_zone*
static std::optional<const date::time_zone*>
get_date_zone(const char* name)
{
if (name == nullptr) {
return date::current_zone();
try {
return date::current_zone();
} catch (const std::runtime_error& e) {
return std::nullopt;
}
}

try {
return date::locate_zone(name);
} catch (const std::runtime_error& e) {
log_error("invalid TZ value: %s -- %s", name, e.what());
return date::current_zone();
try {
return date::current_zone();
} catch (const std::runtime_error& e) {
return std::nullopt;
}
}
}

Expand All @@ -124,57 +132,82 @@ to_sys_time(date::local_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);

if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().to_sys(secs);
}

auto inf = TZ_DATE_ZONE->get_info(secs);
static const auto TZ_DATE_ZONE = get_date_zone(TZ);

return TZ_DATE_ZONE->to_sys(secs);
if (TZ_DATE_ZONE) {
auto inf = TZ_DATE_ZONE.value()->get_info(secs);

return TZ_DATE_ZONE.value()->to_sys(secs);
}

static const auto TZ_POSIX_UTC = get_posix_zone("UTC0");

return TZ_POSIX_UTC.value().to_sys(secs);
}

date::local_seconds
to_local_time(date::sys_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);

if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().to_local(secs);
}

return TZ_DATE_ZONE->to_local(secs);
static const auto TZ_DATE_ZONE = get_date_zone(TZ);

if (TZ_DATE_ZONE) {
return TZ_DATE_ZONE.value()->to_local(secs);
}

static const auto TZ_POSIX_UTC = get_posix_zone("UTC0");

return TZ_POSIX_UTC.value().to_local(secs);
}

date::sys_info
sys_time_to_info(date::sys_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);

if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().get_info(secs);
}

return TZ_DATE_ZONE->get_info(secs);
static const auto TZ_DATE_ZONE = get_date_zone(TZ);
if (TZ_DATE_ZONE) {
return TZ_DATE_ZONE.value()->get_info(secs);
}

static const auto TZ_POSIX_UTC = get_posix_zone("UTC0");

return TZ_POSIX_UTC.value().get_info(secs);
}

date::local_info
local_time_to_info(date::local_seconds secs)
{
static const auto* TZ = getenv("TZ");
static const auto TZ_POSIX_ZONE = get_posix_zone(TZ);
static const auto* TZ_DATE_ZONE = get_date_zone(TZ);

if (TZ_POSIX_ZONE) {
return TZ_POSIX_ZONE.value().get_info(secs);
}

return TZ_DATE_ZONE->get_info(secs);
static const auto TZ_DATE_ZONE = get_date_zone(TZ);
if (TZ_DATE_ZONE) {
return TZ_DATE_ZONE.value()->get_info(secs);
}

static const auto TZ_POSIX_UTC = get_posix_zone("UTC0");

return TZ_POSIX_UTC.value().get_info(secs);
}

} // namespace lnav
Expand Down
10 changes: 8 additions & 2 deletions src/logfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,14 @@ logfile::open(std::filesystem::path filename,
if (!phdr.h_timezone.empty()) {
log_info("setting default time zone from piper header: %s",
phdr.h_timezone.c_str());
fo.fo_default_zone.pp_value
= date::locate_zone(phdr.h_timezone);
try {
fo.fo_default_zone.pp_value
= date::locate_zone(phdr.h_timezone);
} catch (const std::runtime_error& e) {
log_error("unable to get tz from piper header %s -- %s",
phdr.h_timezone.c_str(),
e.what());
}
}
if (!fo.empty()) {
safe::WriteAccess<lnav::safe_file_options_hier>
Expand Down
8 changes: 6 additions & 2 deletions src/readline_possibilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,12 @@ add_tz_possibilities(ln_mode_t context)
auto* rc = lnav_data.ld_rl_view;

rc->clear_possibilities(context, "timezone");
for (const auto& tz : date::get_tzdb().zones) {
rc->add_possibility(context, "timezone", tz.name());
try {
for (const auto& tz : date::get_tzdb().zones) {
rc->add_possibility(context, "timezone", tz.name());
}
} catch (const std::runtime_error& e) {
log_error("unable to get tzdb -- %s", e.what());
}

{
Expand Down
2 changes: 2 additions & 0 deletions src/time_formats.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ TIME_FORMATS = \
"%y-%m-%dT%H:%M:%S.%f%z" \
"%Y-%m-%dT%H:%M:%S.%L%z" \
"%y-%m-%dT%H:%M:%S.%L%z" \
"%Y-%m-%dT%H:%M:%S.%L%Z" \
"%y-%m-%dT%H:%M:%S.%L%Z" \
"%Y-%m-%dT%H:%M:%S%z" \
"%Y-%m-%dT%H:%M:%S%z" \
"%Y-%m-%dT%H:%M:%S" \
Expand Down
2 changes: 2 additions & 0 deletions test/expected/expected.am
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_time_func.sh_123c85ff1178743f5cb78efeaf98b637bcbe55ff.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_14737ee9597b7d22519d23fbe34c0eb7d6c09ff2.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_14737ee9597b7d22519d23fbe34c0eb7d6c09ff2.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_1804a2824c5e7dee903ef7500a3b60a123b7de01.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_1804a2824c5e7dee903ef7500a3b60a123b7de01.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_1fbeb1ba69a95284eb1d4d052f5068ede7968704.err \
$(srcdir)/%reldir%/test_sql_time_func.sh_1fbeb1ba69a95284eb1d4d052f5068ede7968704.out \
$(srcdir)/%reldir%/test_sql_time_func.sh_20477acc218c96f1385dc97e4d28c80a05c93709.err \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
✘ error: invalid timestamp: 2022-03-02T10:20:30+
reason: the leading part of the timestamp was matched, however, the trailing text “+” was not
--> command-option:1
| ;SELECT timezone('UTC', '2022-03-02T10:20:30+')
= note: input matched time format “%Y-%m-%dT%H:%M:%S”
= note: 2022-03-02T10:20:30+
^ unrecognized input
= help: fix the timestamp or remove the trailing text
Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +0,0 @@
✘ error: invalid timestamp: 2022-03-02T10:20:30.400bad
reason: the leading part of the timestamp was matched, however, the trailing text “bad” was not
--> command-option:1
| ;SELECT timezone('UTC', '2022-03-02T10:20:30.400bad')
= note: input matched time format “%Y-%m-%dT%H:%M:%S”
= note: 2022-03-02T10:20:30.400bad
^-^ unrecognized input
= help: fix the timestamp or remove the trailing text
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
timezone('UTC', '2022-03-02T10:20:30.400bad')
2022-03-02T10:20:30.400000+0000
2 changes: 2 additions & 0 deletions test/logfile_invalid_tz.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2015-04-24T21:08:10.313913FOO err rbd [22968]lotuscreds:ERROR:Could not retrieve lotus account information from db
2015-04-24T21:08:58.430632FOO err rbd [24206]networkutil:ERROR:The configured address sg01-1-vc1.oc.vmware.com was invalid
2 changes: 1 addition & 1 deletion test/test_sql_time_func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,4 @@ run_cap_test ./drive_sql "SELECT timezone('UTC', '2022-03-02T10:20:30.400-0700')

run_cap_test ${lnav_test} -nN -c ";SELECT timezone('bad-zone', '2022-03-02T10:20:30.400-0700')"

run_cap_test ${lnav_test} -nN -c ";SELECT timezone('UTC', '2022-03-02T10:20:30.400bad')"
run_cap_test ${lnav_test} -nN -c ";SELECT timezone('UTC', '2022-03-02T10:20:30+')"

0 comments on commit 586b507

Please sign in to comment.