From 54ecf8d017580b495d6501e53ca54e453a73a364 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Thu, 23 Apr 2015 13:21:41 +0200 Subject: [LIBREPORT 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/Makefile.am | 3 ++- tests/dump_dir.at | 49 ++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/dump_dir.at diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h index 4c5c72a..8d84fd4 100644 --- a/src/include/internal_libreport.h +++ b/src/include/internal_libreport.h @@ -132,6 +132,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/Makefile.am b/tests/Makefile.am index a680f05..eaf1ac2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,7 +42,8 @@ TESTSUITE_AT = \ report_python.at \ xfuncs.at \ string_list.at \ - ureport.at + ureport.at \ + dump_dir.at EXTRA_DIST += $(TESTSUITE_AT) TESTSUITE = $(srcdir)/testsuite diff --git a/tests/dump_dir.at b/tests/dump_dir.at new file mode 100644 index 0000000..a579243 --- /dev/null +++ b/tests/dump_dir.at @@ -0,0 +1,49 @@ +# -*- Autotest -*- + +AT_BANNER([dump directories]) + +## ----------------------- ## +## 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; +} +]]) diff --git a/tests/testsuite.at b/tests/testsuite.at index abad32b..41107e7 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -17,3 +17,4 @@ m4_include([xml_definition.at]) m4_include([report_python.at]) m4_include([string_list.at]) m4_include([ureport.at]) +m4_include([dump_dir.at]) -- 1.8.3.1