#include <dirent.h>
#include "locale-root.h"
+#include "subpath.h"
/*
* Implementation of folder based localisation as described here:
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
*/
}
/* sort the folders */
- qsort(container->folders, container->count, sizeof *container->folders, compare_folders_for_qsort);
+ if (container->count)
+ qsort(container->folders, container->count, sizeof *container->folders, compare_folders_for_qsort);
/* build the parents links */
i = container->count;
*/
struct locale_root *locale_root_addref(struct locale_root *root)
{
- root->refcount++;
+ __atomic_add_fetch(&root->refcount, 1, __ATOMIC_RELAXED);
return root;
}
*/
static void internal_unref(struct locale_root *root)
{
- if (!--root->intcount) {
+ if (!__atomic_sub_fetch(&root->intcount, 1, __ATOMIC_RELAXED)) {
clear_container(&root->container);
close(root->rootfd);
free(root);
{
size_t i;
- if (root != NULL && !--root->refcount) {
+ if (root && !__atomic_sub_fetch(&root->refcount, 1, __ATOMIC_RELAXED)) {
/* clear circular references through searchs */
for (i = 0 ; i < LRU_COUNT ; i++)
locale_search_unref(root->lru[i]);
errno = ENOMEM;
} else {
/* init */
- root->intcount++;
+ __atomic_add_fetch(&root->intcount, 1, __ATOMIC_RELAXED);
search->root = root;
search->head = NULL;
search->refcount = 1;
*/
struct locale_search *locale_search_addref(struct locale_search *search)
{
- search->refcount++;
+ __atomic_add_fetch(&search->refcount, 1, __ATOMIC_RELAXED);
return search;
}
{
struct locale_search_node *it, *nx;
- if (search && !--search->refcount) {
+ if (search && !__atomic_sub_fetch(&search->refcount, 1, __ATOMIC_RELAXED)) {
it = search->head;
while(it != NULL) {
nx = it->next;
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)
{