Per RFC-3339, these timezones are legal:
Z
+06:00
+0600
+06

Unfortunately, the only format supported by Rsyslog is the first two.

The spec includes the following ABNF constructs:

   time-numoffset    = ("+" / "-") time-hour [[":"] time-minute]
   time-zone         = "Z" / time-numoffset

   timeopt-hour      = "-" / (time-hour [":"])
   timeopt-minute    = "-" / (time-minute [":"])


We have several log sources which omit the optional ":" separator in the timezone. We've developed the attached patch to improve Rsyslog's support for valid RFC-3339 timezones.

One other minor fix in the patch - OffsetHour was originally declared as a "char" instead of an "int".

--Scott
--- rsyslog-5.8.13-original/runtime/datetime.c	2012-11-16 14:50:34.972270032 -0500
+++ rsyslog-5.8.13-patched/runtime/datetime.c	2012-11-16 14:54:49.160267175 -0500
@@ -212,7 +212,7 @@
 	int secfrac;	/* fractional seconds (must be 32 bit!) */
 	int secfracPrecision;
 	char OffsetMode;	/* UTC offset + or - */
-	char OffsetHour;	/* UTC offset in hours */
+	int OffsetHour;	/* UTC offset in hours */
 	int OffsetMinute;	/* UTC offset in minutes */
 	int lenStr;
 	/* end variables to temporarily hold time information while we parse */
@@ -292,15 +292,36 @@
 		--lenStr;
 		pszTS++;
 
+		int lenHourStart = lenStr;
 		OffsetHour = srSLMGParseInt32(&pszTS, &lenStr);
-		if(OffsetHour < 0 || OffsetHour > 23)
-			ABORT_FINALIZE(RS_RET_INVLD_TIME);
+		int lenHour = lenHourStart - lenStr;
 
-		if(lenStr == 0 || *pszTS++ != ':')
-			ABORT_FINALIZE(RS_RET_INVLD_TIME);
-		OffsetMinute = srSLMGParseInt32(&pszTS, &lenStr);
-		if(OffsetMinute < 0 || OffsetMinute > 59)
+		if(lenHour == 2 && (OffsetHour > 0 || OffsetHour < 23)) {
+			if(lenStr == 0) {
+				/* Per RFC-3339, minute offset is optional */
+				OffsetMinute = 0;
+			} else {
+				if(lenStr == 0 || *pszTS++ != ':')
+					ABORT_FINALIZE(RS_RET_INVLD_TIME);
+				OffsetMinute = srSLMGParseInt32(&pszTS, &lenStr);
+				if(OffsetMinute < 0 || OffsetMinute > 59)
+					ABORT_FINALIZE(RS_RET_INVLD_TIME);
+			}
+		} else if (lenHour == 4) {
+			/* Per RFC-3339, colon separator is optional */
+			int Offset = OffsetHour;
+
+			OffsetHour = Offset / 100;
+			if(OffsetHour < 0 || OffsetHour > 23)
+				ABORT_FINALIZE(RS_RET_INVLD_TIME);
+
+			OffsetMinute = Offset % 100;
+			if(OffsetMinute < 0 || OffsetMinute > 59)
+				ABORT_FINALIZE(RS_RET_INVLD_TIME);
+		} else {
 			ABORT_FINALIZE(RS_RET_INVLD_TIME);
+		
+		}
 	} else {
 		/* there MUST be TZ information */
 		ABORT_FINALIZE(RS_RET_INVLD_TIME);
_______________________________________________
rsyslog mailing list
http://lists.adiscon.net/mailman/listinfo/rsyslog
http://www.rsyslog.com/professional-services/
What's up with rsyslog? Follow https://twitter.com/rgerhards
NOTE WELL: This is a PUBLIC mailing list, posts are ARCHIVED by a myriad of 
sites beyond our control. PLEASE UNSUBSCRIBE and DO NOT POST if you DON'T LIKE 
THAT.

Reply via email to