From 95e4129773089f139a1d36d662b735c55c945ad1 Mon Sep 17 00:00:00 2001 From: stacknil Date: Thu, 28 May 2026 10:15:13 +0800 Subject: [PATCH] fix(parser): accept numeric journalctl timezones --- src/parser.cpp | 2 +- tests/test_parser.cpp | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/parser.cpp b/src/parser.cpp index b0b3861..a7b2a9f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -181,7 +181,7 @@ bool parse_timezone_token(std::string_view token, std::chrono::minutes& offset) if (negative) { offset = -offset; } - return false; + return true; } void parse_program_tag(std::string_view tag, std::string& program, std::optional& pid) { diff --git a/tests/test_parser.cpp b/tests/test_parser.cpp index 4f42267..a2b33c8 100644 --- a/tests/test_parser.cpp +++ b/tests/test_parser.cpp @@ -357,9 +357,7 @@ void test_session_opened_event() { } void test_journalctl_short_full_event() { - const loglens::AuthLogParser parser(loglens::ParserConfig{ - loglens::InputMode::JournalctlShortFull, - std::nullopt}); + const auto parser = make_journalctl_parser(); const auto event = parser.parse_line( "Tue 2026-03-10 08:11:22 UTC example-host sshd[2234]: Failed password for invalid user admin from 203.0.113.10 port 51022 ssh2", 8); @@ -372,6 +370,32 @@ void test_journalctl_short_full_event() { "expected journalctl timestamp to preserve embedded year and timezone"); } +void test_journalctl_numeric_timezone_offsets() { + const auto parser = make_journalctl_parser(); + std::string error; + const auto compact_offset_event = parser.parse_line( + "Tue 2026-03-10 08:11:22 +0800 example-host sshd[2235]: Failed password for root from 203.0.113.13 port 51023 ssh2", + 9, + &error); + + expect(compact_offset_event.has_value(), "expected compact numeric timezone event"); + expect(error.empty(), "expected compact numeric timezone to parse cleanly"); + expect(compact_offset_event->username == "root", "expected compact numeric timezone username"); + expect(loglens::format_timestamp(compact_offset_event->timestamp) == "2026-03-10 00:11:22", + "expected compact numeric timezone to normalize to UTC"); + + const auto colon_offset_event = parser.parse_line( + "Tue 2026-03-10 08:11:22 -05:00 example-host sshd[2236]: Accepted password for alice from 203.0.113.14 port 51024 ssh2", + 10, + &error); + + expect(colon_offset_event.has_value(), "expected colon numeric timezone event"); + expect(error.empty(), "expected colon numeric timezone to parse cleanly"); + expect(colon_offset_event->username == "alice", "expected colon numeric timezone username"); + expect(loglens::format_timestamp(colon_offset_event->timestamp) == "2026-03-10 13:11:22", + "expected colon numeric timezone to normalize to UTC"); +} + void test_input_mode_aliases() { expect(loglens::parse_input_mode("syslog") == loglens::InputMode::SyslogLegacy, "expected syslog mode alias"); @@ -767,6 +791,7 @@ int main() { test_pam_sss_received_failure_event(); test_session_opened_event(); test_journalctl_short_full_event(); + test_journalctl_numeric_timezone_offsets(); test_input_mode_aliases(); test_syslog_auth_family_fixture_file(); test_journalctl_auth_family_fixture_file();