]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Add parser for SMTP date
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 21 Dec 2016 13:26:23 +0000 (13:26 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 21 Dec 2016 13:26:23 +0000 (13:26 +0000)
src/ragel/smtp_date.rl
src/ragel/smtp_received_parser.rl

index eb5d0cdc528ddb037fc3c5ec2f087db97056af76..23ab3cabaa3e79b6060a31d960f9b3e45ebec2f7 100644 (file)
   # SMTP date spec
   # Obtained from: http://tools.ietf.org/html/rfc5322#section_3.3
 
+
+  action Day_Start {
+    tmp = p;
+  }
+  action Day_End {
+    if (p > tmp) {
+      gulong n;
+      if (rspamd_strtoul (tmp, p - tmp, &n)) {
+        if (n > 0 && n <= 31) {
+          tm.tm_mday = n;
+        }
+      }
+    }
+  }
+  action Month_End {
+
+  }
+  action Year_Start {
+    tmp = p;
+  }
+  action Year_End {
+    if (p > tmp) {
+      gulong n;
+      if (rspamd_strtoul (tmp, p - tmp, &n)) {
+        if (n < 1000) {
+          tm.tm_year = n + 1900;
+        }
+        else {
+          tm.tm_year = n;
+        }
+      }
+    }
+  }
+  action Hour_Start {
+    tmp = p;
+  }
+  action Hour_End {
+    if (p > tmp) {
+      gulong n;
+      if (rspamd_strtoul (tmp, p - tmp, &n)) {
+        if (n < 24) {
+          tm.tm_hour = n;
+        }
+      }
+    }
+  }
+  action Minute_Start {
+    tmp = p;
+  }
+  action Minute_End {
+    if (p > tmp) {
+      gulong n;
+      if (rspamd_strtoul (tmp, p - tmp, &n)) {
+        if (n < 60) {
+          tm.tm_min = n;
+        }
+      }
+    }
+  }
+  action Second_Start {
+    tmp = p;
+  }
+  action Second_End {
+    if (p > tmp) {
+      gulong n;
+      if (rspamd_strtoul (tmp, p - tmp, &n)) {
+        if (n <= 60) { /* Leap second */
+          tm.tm_sec = n;
+        }
+      }
+    }
+  }
+  action TZ_Sign {
+    tmp = p - 1;
+  }
+  action TZ_Offset_Start {
+
+  }
+  action TZ_Offset_End {
+    if (p > tmp + 1) {
+      rspamd_strtoul (tmp + 1, p - tmp - 1, (gulong *)&tz);
+
+      if (*tmp == '-') {
+        tz = -(tz);
+      }
+    }
+  }
+  action Obs_Zone_End {
+  }
+  action DT_End {
+  }
+
+  # Specific actions
+  # Months
+  action Month_Jan {
+    tm.tm_mon = 0;
+  }
+  action Month_Feb {
+    tm.tm_mon = 1;
+  }
+  action Month_Mar {
+    tm.tm_mon = 2;
+  }
+  action Month_Apr {
+    tm.tm_mon = 3;
+  }
+  action Month_May {
+    tm.tm_mon = 4;
+  }
+  action Month_Jun {
+    tm.tm_mon = 5;
+  }
+  action Month_Jul {
+    tm.tm_mon = 6;
+  }
+  action Month_Aug {
+    tm.tm_mon = 7;
+  }
+  action Month_Sep {
+    tm.tm_mon = 8;
+  }
+  action Month_Oct {
+    tm.tm_mon = 9;
+  }
+  action Month_Nov {
+    tm.tm_mon = 10;
+  }
+  action Month_Dec {
+    tm.tm_mon = 11;
+  }
+  # Obsoleted timezones
+  action TZ_UT {
+    tz = 0;
+  }
+  action TZ_GMT {
+    tz = 0;
+  }
+  action TZ_EST {
+    tz = -500;
+  }
+  action TZ_EDT {
+    tz = -400;
+  }
+  action TZ_CST {
+    tz = -600;
+  }
+  action TZ_CDT {
+    tz = -500;
+  }
+  action TZ_MST {
+    tz = -700;
+  }
+  action TZ_MDT {
+    tz = -600;
+  }
+  action TZ_PST {
+    tz = -800;
+  }
+  action TZ_PDT {
+    tz = -700;
+  }
   digit_2         =   digit{2};
   digit_4         =   digit{4};
   day_name        =    "Mon" | "Tue" | "Wed" | "Thu" |
                        "Fri" | "Sat" | "Sun";
   day_of_week     =   FWS? day_name;
   day             =   FWS? digit{1,2} FWS;
-  month           =    "Jan" | "Feb" | "Mar" | "Apr" |
-                       "May" | "Jun" | "Jul" | "Aug" |
-                       "Sep" | "Oct" | "Nov" | "Dec";
-  year            =   FWS digit{4,} FWS;
-  date            =   day month year;
+  month           =    "Jan" %Month_Jan | "Feb" %Month_Feb | "Mar" %Month_Mar | "Apr" %Month_Apr |
+                       "May" %Month_May | "Jun" %Month_Jun | "Jul" %Month_Jul | "Aug" %Month_Aug |
+                       "Sep" %Month_Sep | "Oct" %Month_Oct | "Nov" %Month_Nov | "Dec" %Month_Dec;
+  year            =   FWS digit{2,} FWS;
+  date            =   day >Day_Start %Day_End month %Month_End year >Year_Start %Year_End;
   hour            =   digit_2;
   minute          =   digit_2;
   second          =   digit_2;
-  time_of_day     =   hour ":" minute (":" second )?;
-  zone            =   FWS ("+" | "-") digit_4;
-  time            =   time_of_day zone;
+  time_of_day     =   hour >Hour_Start %Hour_End ":" minute >Minute_Start %Minute_End (":" second >Second_Start %Second_End )?;
+  zone            =   FWS ("+" | "-") %TZ_Sign digit_4 >TZ_Offset_Start %TZ_Offset_End;
+  obs_zone        =   "UT" %TZ_UT | "GMT" %TZ_GMT |
+                     "EST" %TZ_EST | "EDT" %TZ_EDT |
+                     "CST" %TZ_CST | "CDT" %TZ_CDT |
+                     "MST" %TZ_MST | "MDT" %TZ_MDT |
+                     "PST" %TZ_PST | "PDT" %TZ_PDT |
+                     [a-iA-I] | [k-zK-Z];
+  time            =   time_of_day %DT_End (zone | obs_zone %Obs_Zone_End);
   date_time       =   (day_of_week ",")? date time;
 }%%
\ No newline at end of file
index c599e0495e081f20ac4a59e3812b6c97c5bb4aa9..cc4d37e0c3ae7157aca2abc6ef26afc34970d3b3 100644 (file)
@@ -284,10 +284,12 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l
               *reported_domain_start, *reported_domain_end,
               *reported_ip_start, *reported_ip_end,
               *ip_start, *ip_end, *date_start,
-              *for_start, *for_end;
+              *for_start, *for_end, *tmp;
+  struct tm tm;
   const char *p = data, *pe = data + len, *eof;
   int cs, in_v6 = 0, *stack = NULL;
   gsize top = 0;
+  glong tz = 0;
   struct _ragel_st_storage {
     int *data;
     gsize size;
@@ -295,6 +297,7 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l
 
   memset (&st_storage, 0, sizeof (st_storage));
   memset (rh, 0, sizeof (*rh));
+  memset (&tm, 0, sizeof (tm));
   real_domain_start = NULL;
   real_domain_end = NULL;
   real_ip_start = NULL;