Commit d0a4d778 authored by npzacs's avatar npzacs
Browse files

Avoid using realpath

parent e9329e42
......@@ -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)
......
......@@ -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
......
/*
* 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
/*
* 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 */
......@@ -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};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment