Skip to content

Commit 5b56239

Browse files
author
senyong.wang
committed
fix: correct timeStrCache calculation to exclude unmatched trailing chars
Use strptimeResult position (actual matched end) instead of curTimeStr.length() when building the second-level cache. This fixes cache pollution when the time string contains trailing characters not matched by the format string (e.g. timezone suffix +08:00). Also add unit test to verify the fix.
1 parent 7099f79 commit 5b56239

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

core/plugin/processor/ProcessorParseTimestampNative.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,13 @@ bool ProcessorParseTimestampNative::ParseLogTime(const StringView& curTimeStr, /
203203
} else {
204204
strptimeResult = Strptime(curTimeStr.data(), mSourceFormat.c_str(), &logTime, nanosecondLength, mSourceYear);
205205
if (NULL != strptimeResult) {
206-
timeStrCache = curTimeStr.substr(0, curTimeStr.length() - nanosecondLength);
206+
// Use strptimeResult position (actual matched end) instead of curTimeStr.length()
207+
// to correctly exclude any unmatched trailing chars (e.g. timezone +08:00) from cache.
208+
int cacheLen = strptimeResult - curTimeStr.data();
209+
if (nanosecondLength > 0) {
210+
cacheLen -= nanosecondLength;
211+
}
212+
timeStrCache = curTimeStr.substr(0, cacheLen);
207213
logTime.tv_sec = logTime.tv_sec - mLogTimeZoneOffsetSecond;
208214
}
209215
}

core/unittest/processor/ProcessorParseTimestampNativeUnittest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,26 @@ void ProcessorParseLogTimeUnittest::TestParseLogTimeSecondCache() {
891891
APSARA_TEST_EQUAL(outTime.tv_nsec, c.exceptedLogTimeNanosecond);
892892
}
893893
}
894+
{ // case: %f format with trailing chars not in format
895+
config["SourceFormat"] = "%Y-%m-%dT%H:%M:%S.%f";
896+
config["SourceTimezone"] = "GMT+00:00";
897+
ProcessorParseTimestampNative& processor = *(new ProcessorParseTimestampNative);
898+
ProcessorInstance processorInstance(&processor, getPluginMeta());
899+
APSARA_TEST_TRUE_FATAL(processorInstance.Init(config, mContext));
900+
901+
LogtailTime outTime = {0, 0};
902+
uint64_t preciseTimestamp = 0;
903+
StringView timeStrCache;
904+
const std::string timeStr = "2026-03-09T14:39:49.985+08:00";
905+
906+
// cache is empty
907+
bool ret1 = processor.ParseLogTime(timeStr, "/var/log/message", outTime, preciseTimestamp, timeStrCache);
908+
APSARA_TEST_EQUAL(ret1, true);
909+
910+
// same string -> IsPrefixString hits the polluted cache -> enters fast path
911+
bool ret2 = processor.ParseLogTime(timeStr, "/var/log/message", outTime, preciseTimestamp, timeStrCache);
912+
APSARA_TEST_EQUAL(ret2, true);
913+
}
894914
}
895915

896916
void ProcessorParseLogTimeUnittest::TestAdjustTimeZone() {

0 commit comments

Comments
 (0)