/*
- Copyright 2015 IoT.bzh
+ Copyright (C) 2015-2020 "IoT.bzh"
author: José Bollo <jose.bollo@iot.bzh>
#include <dirent.h>
#include "locale-root.h"
+#include "subpath.h"
/*
* Implementation of folder based localisation as described here:
struct locale_folder {
struct locale_folder *parent;
size_t length;
- char name[1];
+ char name[];
};
struct locale_container {
struct locale_root *root;
struct locale_search_node *head;
int refcount;
- char definition[1];
+ char definition[];
};
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
*/
if (folders != NULL) {
container->folders = folders;
length = strlen(name);
- folders[count] = malloc(sizeof **folders + length);
+ folders[count] = malloc(sizeof **folders + 1 + length);
if (folders[count] != NULL) {
folders[count]->parent = NULL;
folders[count]->length = length;
return f;
if (c >= 0)
high = mid;
- else
+ else
low = mid + 1;
}
return NULL;
*/
static int init_container(struct locale_container *container, int dirfd)
{
- int rc, sfd;
+ int rc = 0, sfd;
DIR *dir;
struct dirent *dent;
struct stat st;
return -1;
break;
}
- if (dent->d_type == DT_DIR || (dent->d_type == DT_UNKNOWN && fstatat(sfd, dent->d_name, &st, 0) == 0 && S_ISDIR(st.st_mode))) {
+ rc = fstatat(sfd, dent->d_name, &st, 0);
+ if (rc == 0 && S_ISDIR(st.st_mode)) {
/* directory aka folder */
if (dent->d_name[0] == '.' && (dent->d_name[1] == 0 || (dent->d_name[1] == '.' && dent->d_name[2] == 0))) {
/* nothing to do for special directories, basic detection, improves if needed */
struct locale_search_node *node;
/* allocate the structure */
- search = malloc(sizeof *search + length);
+ search = malloc(sizeof *search + 1 + length);
if (search == NULL) {
errno = ENOMEM;
} else {
int rootfd, fd;
/* check the path and normalize it */
- filename = normalsubpath(filename);
+ filename = subpath_force(filename);
if (filename == NULL)
goto inval;
int rootfd;
/* check the path and normalize it */
- filename = normalsubpath(filename);
+ filename = subpath_force(filename);
if (filename == NULL)
goto inval;
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)
{