#include "exim.h"
-static uschar *last_comment_position;
+static const uschar *last_comment_position;
Returns: pointer to the last @ in an address, or NULL if none
*/
-uschar *
-parse_find_at(uschar *s)
+const uschar *
+parse_find_at(const uschar *s)
{
-uschar *t = s + Ustrlen(s);
+const uschar * t = s + Ustrlen(s);
while (--t >= s)
- {
if (*t == '@')
{
int backslash_count = 0;
- uschar *tt = t - 1;
+ const uschar *tt = t - 1;
while (tt > s && *tt-- == '\\') backslash_count++;
if ((backslash_count & 1) == 0) return t;
}
- else if (*t == '\"') return NULL;
- }
+ else if (*t == '\"')
+ return NULL;
+
return NULL;
}
Returns: new character pointer
*/
-static uschar *
-skip_comment(uschar *s)
+static const uschar *
+skip_comment(const uschar *s)
{
last_comment_position = s;
while (*s)
Returns: new character pointer
*/
-static uschar *
-read_domain(uschar *s, uschar *t, uschar **errorptr)
+static const uschar *
+read_domain(const uschar *s, uschar *t, uschar **errorptr)
{
uschar *tt = t;
s = skip_comment(s);
Returns: new character pointer
*/
-static uschar *
-read_local_part(uschar *s, uschar *t, uschar **error, BOOL allow_null)
+static const uschar *
+read_local_part(const uschar *s, uschar *t, uschar **error, BOOL allow_null)
{
uschar *tt = t;
*error = NULL;
Returns: new character pointer
*/
-static uschar *
-read_route(uschar *s, uschar *t, uschar **errorptr)
+static const uschar *
+read_route(const uschar *s, uschar *t, uschar **errorptr)
{
BOOL commas = FALSE;
*errorptr = NULL;
Returns: new character pointer
*/
-static uschar *
-read_addr_spec(uschar *s, uschar *t, int term, uschar **errorptr,
+static const uschar *
+read_addr_spec(const uschar *s, uschar *t, int term, uschar **errorptr,
uschar **domainptr)
{
s = read_local_part(s, t, errorptr, FALSE);
#define FAILED(s) { *errorptr = s; goto PARSE_FAILED; }
uschar *
-parse_extract_address(uschar *mailbox, uschar **errorptr, int *start, int *end,
+parse_extract_address(const uschar *mailbox, uschar **errorptr, int *start, int *end,
int *domain, BOOL allow_null)
{
uschar *yield = store_get(Ustrlen(mailbox) + 1, is_tainted(mailbox));
-uschar *startptr, *endptr;
-uschar *s = US mailbox;
+const uschar *startptr, *endptr;
+const uschar *s = US mailbox;
uschar *t = US yield;
*domain = 0;
/* No non-printers; use the RFC 822 quoting rules */
-buffer = store_get(len*4, is_tainted(phrase));
+if (len <= 0 || len >= INT_MAX/4)
+ {
+ return string_copy_taint(CUS"", is_tainted(phrase));
+ }
+
+buffer = store_get((len+1)*4, is_tainted(phrase));
s = phrase;
end = s + len;
{
if (ss >= end) ss--;
*t++ = '(';
- Ustrncpy(t, s, ss-s);
- t += ss-s;
- s = ss;
+ if (ss > s)
+ {
+ Ustrncpy(t, s, ss-s);
+ t += ss-s;
+ s = ss;
+ }
}
}
else
{
int start, end, domain;
- uschar *recipient = NULL;
+ const uschar *recipient = NULL;
int save = s[len];
s[len] = 0;
recipient = ((options & RDO_REWRITE) != 0)?
rewrite_address(recipient, TRUE, FALSE, global_rewrite_rules,
rewrite_existflags) :
- rewrite_address_qualify(recipient, TRUE);
- addr = deliver_make_addr(recipient, TRUE); /* TRUE => copy recipient */
+ rewrite_address_qualify(recipient, TRUE); /*XXX loses track of const */
+ addr = deliver_make_addr(US recipient, TRUE); /* TRUE => copy recipient, so deconst ok */
}
/* Restore the final character in the original data, and add to the
Returns: points after the processed message-id or NULL on error
*/
-uschar *
-parse_message_id(uschar *str, uschar **yield, uschar **error)
+const uschar *
+parse_message_id(const uschar *str, uschar **yield, uschar **error)
{
uschar *domain = NULL;
uschar *id;
*id++ = 0;
store_release_above(id);
-str = skip_comment(str);
-return str;
+return skip_comment(str);
}
Returns: points after the processed date or NULL on error
*/
-static uschar *
-parse_number(uschar *str, int *n, int digits)
+static const uschar *
+parse_number(const uschar *str, int *n, int digits)
{
- *n=0;
- while (digits--)
+*n=0;
+while (digits--)
{
- if (*str<'0' || *str>'9') return NULL;
- *n=10*(*n)+(*str++-'0');
+ if (*str<'0' || *str>'9') return NULL;
+ *n=10*(*n)+(*str++-'0');
}
- return str;
+return str;
}
Returns: points after the parsed day or NULL on error
*/
-static uschar *
-parse_day_of_week(uschar *str)
+static const uschar *
+parse_day_of_week(const uschar * str)
{
/*
day-of-week = ([FWS] day-name) / obs-day-of-week
int i;
uschar day[4];
-str=skip_comment(str);
-for (i=0; i<3; ++i)
+str = skip_comment(str);
+for (i = 0; i < 3; ++i)
{
- if ((day[i]=tolower(*str))=='\0') return NULL;
+ if ((day[i] = tolower(*str)) == '\0') return NULL;
++str;
}
-day[3]='\0';
-for (i=0; i<7; ++i) if (Ustrcmp(day,day_name[i])==0) break;
-if (i==7) return NULL;
-str=skip_comment(str);
-return str;
+day[3] = '\0';
+for (i = 0; i<7; ++i) if (Ustrcmp(day,day_name[i]) == 0) break;
+if (i == 7) return NULL;
+return skip_comment(str);
}
Returns: points after the processed date or NULL on error
*/
-static uschar *
-parse_date(uschar *str, int *d, int *m, int *y)
+static const uschar *
+parse_date(const uschar *str, int *d, int *m, int *y)
{
/*
date = day month year
obs-day = [CFWS] 1*2DIGIT [CFWS]
*/
-uschar *c,*n;
+const uschar * s, * n;
static const uschar *month_name[]={ US"jan", US"feb", US"mar", US"apr", US"may", US"jun", US"jul", US"aug", US"sep", US"oct", US"nov", US"dec" };
int i;
uschar month[4];
-str=skip_comment(str);
-if ((str=parse_number(str,d,1))==NULL) return NULL;
-if (*str>='0' && *str<='9') *d=10*(*d)+(*str++-'0');
-c=skip_comment(str);
-if (c==str) return NULL;
-else str=c;
-for (i=0; i<3; ++i) if ((month[i]=tolower(*(str+i)))=='\0') return NULL;
-month[3]='\0';
-for (i=0; i<12; ++i) if (Ustrcmp(month,month_name[i])==0) break;
-if (i==12) return NULL;
+str = skip_comment(str);
+if ((str = parse_number(str,d,1)) == NULL) return NULL;
+
+if (*str>='0' && *str<='9') *d = 10*(*d)+(*str++-'0');
+s = skip_comment(str);
+if (s == str) return NULL;
+str = s;
+
+for (i = 0; i<3; ++i) if ((month[i]=tolower(*(str+i))) == '\0') return NULL;
+month[3] = '\0';
+for (i = 0; i<12; ++i) if (Ustrcmp(month,month_name[i]) == 0) break;
+if (i == 12) return NULL;
str+=3;
-*m=i;
-c=skip_comment(str);
-if (c==str) return NULL;
-else str=c;
-if ((n=parse_number(str,y,4)))
+*m = i;
+s = skip_comment(str);
+if (s == str) return NULL;
+str=s;
+
+if ((n = parse_number(str,y,4)))
{
- str=n;
+ str = n;
if (*y<1900) return NULL;
- *y=*y-1900;
+ *y = *y-1900;
}
-else if ((n=parse_number(str,y,2)))
+else if ((n = parse_number(str,y,2)))
{
- str=skip_comment(n);
- while (*(str-1)==' ' || *(str-1)=='\t') --str; /* match last FWS later */
+ str = skip_comment(n);
+ while (*(str-1) == ' ' || *(str-1) == '\t') --str; /* match last FWS later */
if (*y<50) *y+=100;
}
else return NULL;
Returns: points after the processed time or NULL on error
*/
-static uschar *
-parse_time(uschar *str, int *h, int *m, int *s, int *z)
+static const uschar *
+parse_time(const uschar *str, int *h, int *m, int *s, int *z)
{
/*
time = time-of-day FWS zone
%d107-122 ; upper and lower case
*/
-uschar *c;
+const uschar * c;
-str=skip_comment(str);
-if ((str=parse_number(str,h,2))==NULL) return NULL;
-str=skip_comment(str);
+str = skip_comment(str);
+if ((str = parse_number(str,h,2)) == NULL) return NULL;
+str = skip_comment(str);
if (*str!=':') return NULL;
++str;
-str=skip_comment(str);
-if ((str=parse_number(str,m,2))==NULL) return NULL;
-c=skip_comment(str);
-if (*str==':')
+str = skip_comment(str);
+if ((str = parse_number(str,m,2)) == NULL) return NULL;
+c = skip_comment(str);
+if (*str == ':')
{
++str;
- str=skip_comment(str);
- if ((str=parse_number(str,s,2))==NULL) return NULL;
- c=skip_comment(str);
+ str = skip_comment(str);
+ if ((str = parse_number(str,s,2)) == NULL) return NULL;
+ c = skip_comment(str);
}
-if (c==str) return NULL;
+if (c == str) return NULL;
else str=c;
-if (*str=='+' || *str=='-')
+if (*str == '+' || *str == '-')
{
int neg;
- neg=(*str=='-');
+ neg = (*str == '-');
++str;
- if ((str=parse_number(str,z,4))==NULL) return NULL;
- *z=(*z/100)*3600+(*z%100)*60;
- if (neg) *z=-*z;
+ if ((str = parse_number(str,z,4)) == NULL) return NULL;
+ *z = (*z/100)*3600+(*z%100)*60;
+ if (neg) *z = -*z;
}
else
{
char zone[5];
- struct { const char *name; int off; } zone_name[10]=
+ struct { const char *name; int off; } zone_name[10] =
{ {"gmt",0}, {"ut",0}, {"est",-5}, {"edt",-4}, {"cst",-6}, {"cdt",-5}, {"mst",-7}, {"mdt",-6}, {"pst",-8}, {"pdt",-7}};
int i,j;
- for (i=0; i<4; ++i)
+ for (i = 0; i<4; ++i)
{
- zone[i]=tolower(*(str+i));
+ zone[i] = tolower(*(str+i));
if (zone[i]<'a' || zone[i]>'z') break;
}
- zone[i]='\0';
- for (j=0; j<10 && strcmp(zone,zone_name[j].name); ++j);
+ zone[i] = '\0';
+ for (j = 0; j<10 && strcmp(zone,zone_name[j].name); ++j);
/* Besides zones named in the grammar, RFC 2822 says other alphabetic */
/* time zones should be treated as unknown offsets. */
if (j<10)
{
- *z=zone_name[j].off*3600;
+ *z = zone_name[j].off*3600;
str+=i;
}
else if (zone[0]<'a' || zone[1]>'z') return 0;
else
{
while ((*str>='a' && *str<='z') || (*str>='A' && *str<='Z')) ++str;
- *z=0;
+ *z = 0;
}
}
return str;
Returns: points after the processed date-time or NULL on error
*/
-uschar *
-parse_date_time(uschar *str, time_t *t)
+const uschar *
+parse_date_time(const uschar *str, time_t *t)
{
/*
date-time = [ day-of-week "," ] date FWS time [CFWS]
char **old_environ;
static char gmt0[]="TZ=GMT0";
static char *gmt_env[]={ gmt0, (char*)0 };
-uschar *try;
+const uschar * try;
-if ((try=parse_day_of_week(str)))
+if ((try = parse_day_of_week(str)))
{
- str=try;
+ str = try;
if (*str!=',') return 0;
++str;
}
-if ((str=parse_date(str,&tm.tm_mday,&tm.tm_mon,&tm.tm_year))==NULL) return NULL;
+if ((str = parse_date(str,&tm.tm_mday,&tm.tm_mon,&tm.tm_year)) == NULL) return NULL;
if (*str!=' ' && *str!='\t') return NULL;
-while (*str==' ' || *str=='\t') ++str;
-if ((str=parse_time(str,&tm.tm_hour,&tm.tm_min,&tm.tm_sec,&zone))==NULL) return NULL;
-tm.tm_isdst=0;
-old_environ=environ;
-environ=gmt_env;
-*t=mktime(&tm);
-environ=old_environ;
-if (*t==-1) return NULL;
+while (*str == ' ' || *str == '\t') ++str;
+if ((str = parse_time(str,&tm.tm_hour,&tm.tm_min,&tm.tm_sec,&zone)) == NULL) return NULL;
+tm.tm_isdst = 0;
+old_environ = environ;
+environ = gmt_env;
+*t = mktime(&tm);
+environ = old_environ;
+if (*t == -1) return NULL;
*t-=zone;
-str=skip_comment(str);
-return str;
+return skip_comment(str);
}