int
parse_forward_list(const uschar *s, int options, address_item **anchor,
- uschar **error, const uschar *incoming_domain, uschar *directory,
+ uschar **error, const uschar *incoming_domain, const uschar *directory,
error_block **syntax_errors)
{
int count = 0;
return FF_ERROR;
}
- if (flen > 255)
+ if (flen > sizeof(filename)-1)
{
*error = string_sprintf("included file name \"%s\" is too long", t);
return FF_ERROR;
return FF_ERROR;
}
- if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)))
+ if (is_tainted(filename))
+ {
+ *error = string_sprintf("Tainted name '%s' for included file not permitted\n",
+ filename);
return FF_ERROR;
+ }
/* Check file name if required */
if (directory)
{
int len = Ustrlen(directory);
- uschar * p = filename + len;
+ uschar * p;
+ while (len > 0 && directory[len-1] == '/') len--; /* ignore trailing '/' */
+ p = filename + len;
if (Ustrncmp(filename, directory, len) != 0 || *p != '/')
{
*error = string_sprintf("included file %s is not in directory %s",
with a flag that fails symlinks. */
{
- int fd = exim_open2(CS directory, O_RDONLY);
+ int fd = exim_open2(CCS directory, O_RDONLY);
if (fd < 0)
{
*error = string_sprintf("failed to open directory %s", directory);
{
uschar temp;
int fd2;
- uschar * q = p;
+ uschar * q = p + 1; /* skip dividing '/' */
- while (*++p && *p != '/') ;
+ while (*q == '/') q++; /* skip extra '/' */
+ while (*++p && *p != '/') ; /* end of component */
temp = *p;
*p = '\0';