From 15059fa1ed5f94c3b5d96357c9be6adfa5ea37b0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Thu, 10 Aug 2017 12:11:31 +0200 Subject: [PATCH] subpath: creation for splitting locale-root MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: Ia339dc1d1291ef52fbec3c928537721ed7410694 Signed-off-by: José Bollo --- src/CMakeLists.txt | 1 + src/locale-root.c | 85 ++--------------------------------- src/subpath.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/subpath.h | 22 +++++++++ 4 files changed, 154 insertions(+), 82 deletions(-) create mode 100644 src/subpath.c create mode 100644 src/subpath.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cf7547c..737faa66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ ADD_LIBRARY(afb-lib STATIC locale-root.c sd-fds.c sig-monitor.c + subpath.c verbose.c websock.c wrap-json.c diff --git a/src/locale-root.c b/src/locale-root.c index 8386e669..c9cdf7dd 100644 --- a/src/locale-root.c +++ b/src/locale-root.c @@ -32,6 +32,7 @@ #include #include "locale-root.h" +#include "subpath.h" /* * Implementation of folder based localisation as described here: @@ -78,62 +79,6 @@ struct locale_root { struct locale_search *default_search; }; -/* a valid subpath is a relative path not looking deeper than root using .. */ -static int validsubpath(const char *subpath) -{ - int l = 0, i = 0; - - /* absolute path is not valid */ - if (subpath[i] == '/') - return 0; - - /* inspect the path */ - while(subpath[i]) { - switch(subpath[i++]) { - case '.': - if (!subpath[i]) - break; - if (subpath[i] == '/') { - i++; - break; - } - if (subpath[i++] == '.') { - if (!subpath[i]) { - l--; - break; - } - if (subpath[i++] == '/') { - l--; - break; - } - } - default: - while(subpath[i] && subpath[i] != '/') - i++; - if (l >= 0) - l++; - case '/': - break; - } - } - return l >= 0; -} - -/* - * Normalizes and checks the 'subpath'. - * Removes any starting '/' and checks that 'subpath' - * does not contains sequence of '..' going deeper than - * root. - * Returns the normalized subpath or NULL in case of - * invalid subpath. - */ -static const char *normalsubpath(const char *subpath) -{ - while(*subpath == '/') - subpath++; - return validsubpath(subpath) ? subpath : NULL; -} - /* * Clear a container content */ @@ -595,7 +540,7 @@ static int do_open(struct locale_search *search, const char *filename, int flags int rootfd, fd; /* check the path and normalize it */ - filename = normalsubpath(filename); + filename = subpath_force(filename); if (filename == NULL) goto inval; @@ -686,7 +631,7 @@ static char *do_resolve(struct locale_search *search, const char *filename, stru int rootfd; /* check the path and normalize it */ - filename = normalsubpath(filename); + filename = subpath_force(filename); if (filename == NULL) goto inval; @@ -768,30 +713,6 @@ char *locale_search_resolve(struct locale_search *search, const char *filename) return do_resolve(search, filename, search->root); } -#if defined(TEST_locale_root_validsubpath) -#include -void t(const char *subpath, int validity) { - printf("%s -> %d = %d, %s\n", subpath, validity, validsubpath(subpath), validsubpath(subpath)==validity ? "ok" : "NOT OK"); -} -int main() { - t("/",0); - t("..",0); - t(".",1); - t("../a",0); - t("a/..",1); - t("a/../////..",0); - t("a/../b/..",1); - t("a/b/c/..",1); - t("a/b/c/../..",1); - t("a/b/c/../../..",1); - t("a/b/c/../../../.",1); - t("./..a/././..b/..c/./.././.././../.",1); - t("./..a/././..b/..c/./.././.././.././..",0); - t("./..a//.//./..b/..c/./.././/./././///.././.././a/a/a/a/a",1); - return 0; -} -#endif - #if defined(TEST_locale_root) int main(int ac,char**av) { diff --git a/src/subpath.c b/src/subpath.c new file mode 100644 index 00000000..a8441638 --- /dev/null +++ b/src/subpath.c @@ -0,0 +1,128 @@ +/* + Copyright 2015 IoT.bzh + + author: José Bollo + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "subpath.h" + +/* a valid subpath is a relative path not looking deeper than root using .. */ +int subpath_is_valid(const char *path) +{ + int l = 0, i = 0; + + /* absolute path is not valid */ + if (path[i] == '/') + return 0; + + /* inspect the path */ + while(path[i]) { + switch(path[i++]) { + case '.': + if (!path[i]) + break; + if (path[i] == '/') { + i++; + break; + } + if (path[i++] == '.') { + if (!path[i]) { + l--; + break; + } + if (path[i++] == '/') { + l--; + break; + } + } + default: + while(path[i] && path[i] != '/') + i++; + if (l >= 0) + l++; + case '/': + break; + } + } + return l >= 0; +} + +/* + * Return the path or NULL is not valid. + * Ensure that the path doesn't start with '/' and that + * it does not contains sequence of '..' going deeper than + * root. + * Returns the path or NULL in case of + * invalid path. + */ +const char *subpath(const char *path) +{ + return path && subpath_is_valid(path) ? (path[0] ? path : ".") : NULL; +} + +/* + * Normalizes and checks the 'path'. + * Removes any starting '/' and checks that 'path' + * does not contains sequence of '..' going deeper than + * root. + * Returns the normalized path or NULL in case of + * invalid path. + */ +const char *subpath_force(const char *path) +{ + while(path && *path == '/') + path++; + return subpath(path); +} + +#if defined(TEST_subpath) +#include +void t(const char *subpath, int validity) { + printf("%s -> %d = %d, %s\n", subpath, validity, subpath_is_valid(subpath), subpath_is_valid(subpath)==validity ? "ok" : "NOT OK"); +} +int main() { + t("/",0); + t("..",0); + t(".",1); + t("../a",0); + t("a/..",1); + t("a/../////..",0); + t("a/../b/..",1); + t("a/b/c/..",1); + t("a/b/c/../..",1); + t("a/b/c/../../..",1); + t("a/b/c/../../../.",1); + t("./..a/././..b/..c/./.././.././../.",1); + t("./..a/././..b/..c/./.././.././.././..",0); + t("./..a//.//./..b/..c/./.././/./././///.././.././a/a/a/a/a",1); + return 0; +} +#endif + diff --git a/src/subpath.h b/src/subpath.h new file mode 100644 index 00000000..f64f6e76 --- /dev/null +++ b/src/subpath.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author: José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +extern int subpath_is_valid(const char *path); +extern const char *subpath(const char *path); +extern const char *subpath_force(const char *path); -- 2.16.6