commit 19cd36545777e20ca03c066d4a29d9c626b86b57
parent cce3b7638b0e9480c808c3893ede7d772d5ddc5e
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sun, 24 Feb 2019 14:07:02 +0100
fix RFC822 ANSI and military zones parsing
Diffstat:
M | sfeed.c | | | 23 | ++++++++++++++++++----- |
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/sfeed.c b/sfeed.c
@@ -402,7 +402,6 @@ gettzoffset(const char *s)
size_t len;
const int offhour;
} tzones[] = {
- { STRP("A"), -1 * 3600 },
{ STRP("CDT"), -5 * 3600 },
{ STRP("CST"), -6 * 3600 },
{ STRP("EDT"), -4 * 3600 },
@@ -411,12 +410,9 @@ gettzoffset(const char *s)
{ STRP("MST"), -7 * 3600 },
{ STRP("PDT"), -7 * 3600 },
{ STRP("PST"), -8 * 3600 },
- { STRP("M"), -2 * 3600 },
- { STRP("N"), 1 * 3600 },
- { STRP("Y"), 12 * 3600 },
};
const char *p;
- int tzhour = 0, tzmin = 0;
+ int tzhour = 0, tzmin = 0, c;
size_t i, namelen;
for (; *s && isspace((unsigned char)*s); s++)
@@ -438,6 +434,23 @@ gettzoffset(const char *s)
/* optimization: these are always non-matching */
if (namelen < 1 || namelen > 3)
return 0;
+ /* ANSI and military zones, defined wrong in RFC822,
+ see RFC2822 4.3 page 32.
+ NOTE: zone J is ambiguous (unused/local observed time) and
+ handled as UTC+0. */
+ if (namelen == 1) {
+ c = (int)*s;
+ /* NOTE: J is not handled: unused / observer local time */
+ if (c >= 'A' && c <= 'I')
+ return c - 'A' + 1; /* +1 through +9 */
+ else if (c >= 'K' && c <= 'M')
+ return c - 'K' + 10; /* 10 through 12 */
+ else if (c >= 'N' && c <= 'Y')
+ return ('Y' - c) - 12; /* -1 through -12 */
+ else
+ return 0;
+ }
+
/* compare tz and adjust offset relative to UTC */
for (i = 0; i < sizeof(tzones) / sizeof(*tzones); i++) {
if (tzones[i].len == namelen &&