libaacs | branch: master | npzacs <npz...@gmail.com> | Thu Oct 24 13:51:18 2013 +0300| [d0a4d77889e9f7891e20306830fa2a7e3f706137] | committer: npzacs
Avoid using realpath > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=d0a4d77889e9f7891e20306830fa2a7e3f706137 --- configure.ac | 2 - src/Makefile.am | 4 +- src/file/path.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/file/path.h | 31 ++++++++++++ src/libaacs/mmc.c | 13 ++--- 5 files changed, 179 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 2c3db97..db0454a 100644 --- a/configure.ac +++ b/configure.ac @@ -104,8 +104,6 @@ AC_SYS_LARGEFILE dnl required functions AC_CHECK_FUNC([snprintf],, [AC_MSG_ERROR($function_not_found)]) -AC_CHECK_FUNC([realpath],[AC_DEFINE([HAVE_REALPATH],[1],[realpath])]) - dnl required libraries dnl pthread check (not on win32) diff --git a/src/Makefile.am b/src/Makefile.am index 83ce5af..f3078cc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ libaacs_la_SOURCES=\ file/keydb.h \ file/keydbcfg-parser.y \ file/keydbcfg-lexer.l \ + file/path.h \ util/attributes.h \ util/macro.h \ util/logging.c \ @@ -42,7 +43,8 @@ libaacs_la_SOURCES+= \ file/dirs_win32.c else libaacs_la_SOURCES+= \ - file/dirs_xdg.c + file/dirs_xdg.c \ + file/path.c endif endif diff --git a/src/file/path.c b/src/file/path.c new file mode 100644 index 0000000..8a53a09 --- /dev/null +++ b/src/file/path.c @@ -0,0 +1,142 @@ +/* + * This file is part of libaacs + * Copyright (C) 2013 VideoLAN + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include "file.h" + +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#define MAX_LINKS 32 + +char *aacs_resolve_path(const char *path, char *resolved_path) +{ + char tmp_path[AACS_PATH_MAX]; + char link[AACS_PATH_MAX]; + char *new_path = resolved_path; + char *path_end = tmp_path + AACS_PATH_MAX - 1; + int readlinks = 0; + int n; + + if (!path || !*path || strlen(path) >= AACS_PATH_MAX - 2) { + return NULL; + } + + /* shadow original path with a copy */ + strcpy(tmp_path, path); + path = tmp_path; + + /* handle relative path */ + if (*path != '/') { + if (!getcwd(new_path, AACS_PATH_MAX - 1)) { + return NULL; + } + new_path += strlen(new_path); + if (new_path[-1] != '/') { + *new_path++ = '/'; + } + } else { + *new_path++ = '/'; + path++; + } + + + while (*path) { + /* "/" */ + if (*path == '/') { + path++; + continue; + } + /* "." */ + if (path[0] == '.' && (!path[1] || path[1] == '/')) { + path++; + continue; + } + /* ".." */ + if (path[0] == '.' && path[1] == '.' && (!path[2] || path[2] == '/')) { + path += 2; + /* not at root ? -> back up one level */ + if (new_path != resolved_path + 1) { + while ((--new_path)[-1] != '/'); + } + continue; + } + + /* copy next component */ + while (*path && *path != '/') { + if (path >= path_end) { + return NULL; + } + *new_path++ = *path++; + } + + /* avoid symlink loops */ + if (readlinks++ > MAX_LINKS) { + return NULL; + } + + /* resolve symlink */ + + *new_path = 0; + n = readlink(resolved_path, link, AACS_PATH_MAX - 1); + + if (n < 0) { + if (errno != EINVAL) { + return NULL; + } + /* file exists but isn't a symlink. */ + + } else if (n >= AACS_PATH_MAX - 1) { + return NULL; + + } else { + link[n] = 0; + if (*link == '/') { + new_path = resolved_path; + } else { + while (*(--new_path) != '/'); + } + + if (path + n >= path_end) { + return NULL; + } + + /* update what's left */ + strcat(link, path); + strcpy(tmp_path, link); + path = tmp_path; + } + + if (*path) { + *new_path++ = '/'; + } + } + + *new_path = 0; + return resolved_path; +} + +#ifdef TEST_AACS_RESOLVE_PATH +#include <stdio.h> +void main(int argc, char *argv[]) { + char path[AACS_PATH_MAX]; + printf("%s -> %s\n", argv[0], aacs_resolve_path(argv[0], path)); + printf("%s -> %s\n", argv[1], aacs_resolve_path(argv[1], path)); +} +#endif diff --git a/src/file/path.h b/src/file/path.h new file mode 100644 index 0000000..8d6f0c2 --- /dev/null +++ b/src/file/path.h @@ -0,0 +1,31 @@ +/* + * This file is part of libaacs + * Copyright (C) 2013 VideoLAN + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#ifndef AACS_PATH_H +#define AACS_PATH_H + +#include <util/attributes.h> + +#ifndef AACS_PATH_MAX +#define AACS_PATH_MAX 1024 +#endif + +AACS_PRIVATE char *aacs_resolve_path(const char *path, char *resolved_path); + +#endif /* AACS_PATH_H */ diff --git a/src/libaacs/mmc.c b/src/libaacs/mmc.c index 2cdfae5..969f543 100644 --- a/src/libaacs/mmc.c +++ b/src/libaacs/mmc.c @@ -25,6 +25,7 @@ #include "mmc.h" #include "crypto.h" +#include "file/path.h" #include "util/macro.h" #include "util/logging.h" @@ -872,18 +873,12 @@ MMC *mmc_open(const char *path) #elif defined(HAVE_MNTENT_H) -#ifdef HAVE_REALPATH - char *file_path = malloc(PATH_MAX); - if (!file_path || !realpath(path, file_path)) { + char file_path [AACS_PATH_MAX]; + if (!aacs_resolve_path(path, file_path)) { DEBUG(DBG_MMC | DBG_CRIT, "Failed resolving path %s\n", path); X_FREE(mmc); - X_FREE(file_path); return NULL; } -#else - char *file_path = (char*)malloc(strlen(path) + 1); - strcpy(file_path, path); -#endif int path_len = strlen(file_path); FILE *proc_mounts; @@ -924,8 +919,6 @@ MMC *mmc_open(const char *path) X_FREE(mmc); } - X_FREE(file_path); - #elif defined(_WIN32) char drive[] = { path[0], ':', '\\', 0 }; char volume[] = {'\\', '\\', '.', '\\', path[0], ':', 0}; _______________________________________________ libaacs-devel mailing list libaacs-devel@videolan.org https://mailman.videolan.org/listinfo/libaacs-devel