Blame src/lib/concat_path_file.c

Packit Service 779887
/*
Packit Service 779887
 * Utility routines.
Packit Service 779887
 *
Packit Service 779887
 * Copyright (C) 2001 Erik Andersen
Packit Service 779887
 *
Packit Service 779887
 * This program is free software; you can redistribute it and/or modify
Packit Service 779887
 * it under the terms of the GNU General Public License as published by
Packit Service 779887
 * the Free Software Foundation; either version 2 of the License, or
Packit Service 779887
 * (at your option) any later version.
Packit Service 779887
 *
Packit Service 779887
 * This program is distributed in the hope that it will be useful,
Packit Service 779887
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 779887
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 779887
 * GNU General Public License for more details.
Packit Service 779887
 *
Packit Service 779887
 * You should have received a copy of the GNU General Public License along
Packit Service 779887
 * with this program; if not, write to the Free Software Foundation, Inc.,
Packit Service 779887
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit Service 779887
 */
Packit Service 779887
#include "internal_libreport.h"
Packit Service 779887
Packit Service 779887
/* Concatenate path and filename to new allocated buffer.
Packit Service 779887
 * Add '/' only as needed (no duplicate // are produced).
Packit Service 779887
 * If path is NULL, it is assumed to be "/".
Packit Service 779887
 * filename should not be NULL.
Packit Service 779887
 */
Packit Service 779887
char *concat_path_file(const char *path, const char *filename)
Packit Service 779887
{
Packit Service 779887
	if (!path)
Packit Service 779887
		path = "";
Packit Service 779887
	const char *end = path + strlen(path);
Packit Service 779887
	while (*filename == '/')
Packit Service 779887
		filename++;
Packit Service 779887
	return xasprintf("%s%s%s", path, (end != path && end[-1] != '/' ? "/" : ""), filename);
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
char *concat_path_basename(const char *path, const char *filename)
Packit Service 779887
{
Packit Service 779887
    char *abspath = realpath(filename, NULL);
Packit Service 779887
    char *base = strrchr((abspath ? abspath : filename), '/');
Packit Service 779887
Packit Service 779887
    /* If realpath failed and filename is malicious (say, "/foo/.."),
Packit Service 779887
     * we may end up tricked into doing some bad things. Don't allow that.
Packit Service 779887
     */
Packit Service 779887
    char buf[sizeof("tmp-"LIBREPORT_ISO_DATE_STRING_SAMPLE"-%lu")];
Packit Service 779887
    if (base && base[1] != '\0' && base[1] != '.')
Packit Service 779887
    {
Packit Service 779887
        /* We have a slash and it's not "foo/" or "foo/.<something>" */
Packit Service 779887
        base++;
Packit Service 779887
    }
Packit Service 779887
    else
Packit Service 779887
    {
Packit Service 779887
        sprintf(buf, "tmp-%s-%lu", iso_date_string(NULL), (long)getpid());
Packit Service 779887
        base = buf;
Packit Service 779887
    }
Packit Service 779887
    char *name = concat_path_file(path, base);
Packit Service 779887
    free(abspath);
Packit Service 779887
    return name;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
bool str_is_correct_filename(const char *str)
Packit Service 779887
{
Packit Service 779887
#define NOT_PRINTABLE(c) (c < ' ' || c == 0x7f)
Packit Service 779887
Packit Service 779887
    if (NOT_PRINTABLE(*str) || *str == '/' || *str == '\0')
Packit Service 779887
        return false;
Packit Service 779887
    ++str;
Packit Service 779887
Packit Service 779887
    if (*str == '\0')
Packit Service 779887
        return *(str-1) != '.';
Packit Service 779887
    if (NOT_PRINTABLE(*str) || *str == '/')
Packit Service 779887
        return false;
Packit Service 779887
    ++str;
Packit Service 779887
Packit Service 779887
    if (*str == '\0')
Packit Service 779887
        return !(*(str-2) == '.' && *(str-1) == '.');
Packit Service 779887
    if (NOT_PRINTABLE(*str) || *str == '/')
Packit Service 779887
        return false;
Packit Service 779887
    ++str;
Packit Service 779887
Packit Service 779887
    for (unsigned i = 0; *str != '\0' && i < 61; ++str, ++i)
Packit Service 779887
        if (NOT_PRINTABLE(*str) || *str == '/')
Packit Service 779887
            return false;
Packit Service 779887
Packit Service 779887
    return *str == '\0';
Packit Service 779887
Packit Service 779887
#undef NOT_PRINTABLE
Packit Service 779887
}