From ce207ac7cd523109e2478ce831a9034e0ecd2a94 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Thu, 23 Apr 2015 13:21:41 +0200 Subject: [PATCH] lib: add a function checking file names Move the code from ABRT and extend it a bit: * allow only 64 characters * allow '.' in names (vmcore_dmesg.txt) * forbid '/' * forbid "." * forbid ".." Related: #1214451 Signed-off-by: Jakub Filak --- src/include/internal_libreport.h | 6 ++++++ src/lib/concat_path_file.c | 25 ++++++++++++++++++++++ tests/dump_dir.at | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h index e66ca96..a4303de 100644 --- a/src/include/internal_libreport.h +++ b/src/include/internal_libreport.h @@ -131,6 +131,12 @@ char *concat_path_file(const char *path, const char *filename); #define concat_path_basename libreport_concat_path_basename char *concat_path_basename(const char *path, const char *filename); +/* Allows all printable characters except '/', + * the string must not exceed 64 characters of length + * and must not equal neither "." nor ".." (these strings may appear in the string) */ +#define str_is_correct_filename libreport_str_is_correct_filename +bool str_is_correct_filename(const char *str); + /* A-la fgets, but malloced and of unlimited size */ #define xmalloc_fgets libreport_xmalloc_fgets char *xmalloc_fgets(FILE *file); diff --git a/src/lib/concat_path_file.c b/src/lib/concat_path_file.c index 39ae07a..24e4cbd 100644 --- a/src/lib/concat_path_file.c +++ b/src/lib/concat_path_file.c @@ -57,3 +57,28 @@ char *concat_path_basename(const char *path, const char *filename) free(abspath); return name; } + +bool str_is_correct_filename(const char *str) +{ +#define NOT_PRINTABLE(c) (c < ' ' || c == 0x7f) + + if (NOT_PRINTABLE(*str) || *str == '/' || *str == '\0') + return false; + ++str; + + if (NOT_PRINTABLE(*str) || *str =='/' || (*str == '\0' && *(str-1) == '.')) + return false; + ++str; + + if (NOT_PRINTABLE(*str) || *str =='/' || (*str == '\0' && *(str-1) == '.' && *(str-2) == '.')) + return false; + ++str; + + for (unsigned i = 0; *str != '\0' && i < 61; ++str, ++i) + if (NOT_PRINTABLE(*str) || *str == '/') + return false; + + return *str == '\0'; + +#undef NOT_PRINTABLE +} diff --git a/tests/dump_dir.at b/tests/dump_dir.at index efec63f..19584d1 100644 --- a/tests/dump_dir.at +++ b/tests/dump_dir.at @@ -49,3 +49,49 @@ int main(int argc, char **argv) return 0; } ]]) + +## ----------------------- ## +## str_is_correct_filename ## +## ----------------------- ## + +AT_TESTFUN([str_is_correct_filename], +[[ +#include "internal_libreport.h" +#include +# +int main(void) +{ + g_verbose = 3; + + assert(str_is_correct_filename("") == false); + assert(str_is_correct_filename("/") == false); + assert(str_is_correct_filename("//") == false); + assert(str_is_correct_filename(".") == false); + assert(str_is_correct_filename(".") == false); + assert(str_is_correct_filename("..") == false); + assert(str_is_correct_filename("..") == false); + assert(str_is_correct_filename("/.") == false); + assert(str_is_correct_filename("//.") == false); + assert(str_is_correct_filename("./") == false); + assert(str_is_correct_filename(".//") == false); + assert(str_is_correct_filename("/./") == false); + assert(str_is_correct_filename("/..") == false); + assert(str_is_correct_filename("//..") == false); + assert(str_is_correct_filename("../") == false); + assert(str_is_correct_filename("..//") == false); + assert(str_is_correct_filename("/../") == false); + assert(str_is_correct_filename("/.././") == false); + + assert(str_is_correct_filename("looks-good-but-evil/") == false); + assert(str_is_correct_filename("looks-good-but-evil/../../") == false); + + assert(str_is_correct_filename(".meta-data") == true); + assert(str_is_correct_filename("..meta-meta-data") == true); + assert(str_is_correct_filename("meta-..-data") == true); + + assert(str_is_correct_filename("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-") == true); + assert(str_is_correct_filename("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890+-=") == false); + + return 0; +} +]]) -- 2.1.0