diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-08-10 12:11:31 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-08-10 12:11:31 +0200 |
commit | 15059fa1ed5f94c3b5d96357c9be6adfa5ea37b0 (patch) | |
tree | e9fa4256af8e1806ea0baaa6da672a851de258c7 | |
parent | a2efb09440814063cf6472b7111ff72c4582f1b2 (diff) |
subpath: creation for splitting locale-root
Change-Id: Ia339dc1d1291ef52fbec3c928537721ed7410694
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/locale-root.c | 85 | ||||
-rw-r--r-- | src/subpath.c | 128 | ||||
-rw-r--r-- | src/subpath.h | 22 |
4 files changed, 154 insertions, 82 deletions
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 <dirent.h> #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 <stdio.h> -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 <jose.bollo@iot.bzh> + + 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <limits.h> +#include <string.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> + +#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 <stdio.h> +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 <jose.bollo@iot.bzh> + * + * 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); |