mirror of
https://github.com/kiwix/libkiwix.git
synced 2026-09-12 21:47:24 -04:00
Introduce a ContentOrigin struct and a resolveContentOrigin() helper that will let readOpds() take a single contentOriginUri parameter instead of separate urlHost/libraryPath ones. As a first step, wire readOpds()'s body to use resolveContentOrigin() to derive baseDir from libraryPath (replacing parseOpdsDom()'s internal removeLastPathElement() call), while urlHost is still passed through untouched. This is not yet functional as a single-parameter API: readOpds()'s public signature and callers are unchanged, and the urlHost side of resolveContentOrigin() isn't exercised yet. That follows in the next commit.
292 lines
10 KiB
C++
292 lines
10 KiB
C++
/*
|
|
* Copyright (C) 2019 Matthieu Gautier
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
|
|
* NON-INFRINGEMENT. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
#include "gtest/gtest.h"
|
|
#include <string>
|
|
#include <vector>
|
|
#ifndef _WIN32
|
|
# include <unistd.h>
|
|
# include <fcntl.h>
|
|
#endif
|
|
#include "../include/tools.h"
|
|
#include "../src/tools/pathTools.h"
|
|
#include "./path_testing_tools.h"
|
|
|
|
|
|
std::vector<std::string> normalizeParts(std::vector<std::string>& parts, bool absolute);
|
|
std::vector<std::string> nParts(std::vector<std::string> parts, bool absolute) {
|
|
return normalizeParts(parts, absolute);
|
|
}
|
|
#ifdef _WIN32
|
|
std::wstring Utf8ToWide(const std::string& str);
|
|
std::string WideToUtf8(const std::wstring& wstr);
|
|
#endif
|
|
|
|
namespace
|
|
{
|
|
|
|
#define V std::vector<std::string>
|
|
TEST(pathTools, normalizePartsAbsolute)
|
|
{
|
|
#define N(...) nParts(__VA_ARGS__, true)
|
|
ASSERT_EQ(N({}), V({}));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(N({"c:"}), V({"c:"}));
|
|
#else
|
|
ASSERT_EQ(N({""}), V({"", ""}));
|
|
#endif
|
|
ASSERT_EQ(N({AS, "a"}), V({AS, "a"}));
|
|
ASSERT_EQ(N({AS, "a", "b"}), V({AS, "a", "b"}));
|
|
ASSERT_EQ(N({AS, "a", "b", ".."}), V({AS, "a"}));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(N({AS, "a", "b", "..", ".."}), V({AS}));
|
|
#else
|
|
ASSERT_EQ(N({AS, "a", "b", "..", ".."}), V({AS, ""}));
|
|
#endif
|
|
ASSERT_EQ(N({AS, "a", "b", "..", "..", "..", "foo"}), V({AS, "foo"}));
|
|
ASSERT_EQ(N({AS, "..", "..", "c", "d", ".", "..", "foo"}), V({AS, "c", "foo"}));
|
|
ASSERT_EQ(N({AS, "a", "b", ".", "c", "d", "..", "foo"}), V({AS, "a", "b", "c", "foo"}));
|
|
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(N({"c:", "a", "b", ".", "c", "d:", "..", "foo"}), V({"d:", "foo"}));
|
|
ASSERT_EQ(N({"","","samba","a","b"}), V({"\\\\samba", "a", "b"}));
|
|
#endif
|
|
#undef N
|
|
}
|
|
|
|
TEST(pathTools, normalizePartsRelative)
|
|
{
|
|
#define N(...) nParts(__VA_ARGS__, false)
|
|
ASSERT_EQ(N({}), V({}));
|
|
ASSERT_EQ(N({""}), V({}));
|
|
ASSERT_EQ(N({"a"}), V({"a"}));
|
|
ASSERT_EQ(N({"a", "b"}), V({"a", "b"}));
|
|
ASSERT_EQ(N({"a", "b", ".."}), V({"a"}));
|
|
ASSERT_EQ(N({"a", "b", "..", ".."}), V({}));
|
|
ASSERT_EQ(N({"a", "b", "..", "..", "..", "foo"}), V({"..", "foo"}));
|
|
ASSERT_EQ(N({"..", "..", "c", "d", ".", "..", "foo"}), V({"..", "..", "c", "foo"}));
|
|
ASSERT_EQ(N({"a", "b", ".", "c", "d", "..", "foo"}), V({"a", "b", "c", "foo"}));
|
|
#undef N
|
|
}
|
|
|
|
TEST(pathTools, isRelativePath)
|
|
{
|
|
ASSERT_TRUE(kiwix::isRelativePath("foo"));
|
|
ASSERT_TRUE(kiwix::isRelativePath(P2("foo","bar")));
|
|
ASSERT_TRUE(kiwix::isRelativePath(P3(".","foo","bar")));
|
|
ASSERT_TRUE(kiwix::isRelativePath(P2("..","foo")));
|
|
ASSERT_TRUE(kiwix::isRelativePath(P4("foo","","bar","")));
|
|
ASSERT_FALSE(kiwix::isRelativePath(A1("foo")));
|
|
ASSERT_FALSE(kiwix::isRelativePath(A2("foo", "bar")));
|
|
#ifdef _WIN32
|
|
ASSERT_FALSE(kiwix::isRelativePath(P2(A_SAMBA, "foo")));
|
|
ASSERT_FALSE(kiwix::isRelativePath(P3(A_SAMBA, "foo", "bar")));
|
|
#endif
|
|
}
|
|
|
|
TEST(pathTools, computeAbsolutePath)
|
|
{
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A2("a","b"), "foo"),
|
|
A3("a","b","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b",""), "foo"),
|
|
A3("a","b","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A2("a","b"), P2(".","foo")),
|
|
A3("a","b","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A2("a","b"), P2("..","foo")),
|
|
A2("a","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b",""), P2("..","foo")),
|
|
A2("a","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A5("a","b","c","d","e"), P2("..","foo")),
|
|
A5("a","b","c","d","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A5("a","b","c","d","e"), P5("..","..","..","g","foo")),
|
|
A4("a","b","g","foo"));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b",""), P2("..","foo")),
|
|
P3(A_SAMBA,"a","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P6(A_SAMBA,"a","b","c","d","e"), P5("..","..","..","g","foo")),
|
|
P5(A_SAMBA,"a","b","g","foo"));
|
|
#endif
|
|
}
|
|
|
|
TEST(pathTools, computeRelativePath)
|
|
{
|
|
ASSERT_EQ(kiwix::computeRelativePath(A2("a","b"), A3("a","b","foo")),
|
|
"foo");
|
|
ASSERT_EQ(kiwix::computeRelativePath(A3("a","b",""), A3("a","b","foo")),
|
|
"foo");
|
|
ASSERT_EQ(kiwix::computeRelativePath(A2("a","b"), A2("a","foo")),
|
|
P2("..","foo"));
|
|
ASSERT_EQ(kiwix::computeRelativePath(A3("a","b",""), A2("a","foo")),
|
|
P2("..","foo"));
|
|
ASSERT_EQ(kiwix::computeRelativePath(A5("a","b","c","d","e"), A5("a","b","c","d","foo")),
|
|
P2("..","foo"));
|
|
ASSERT_EQ(kiwix::computeRelativePath(A5("a","b","c","d","e"), A4("a","b","g","foo")),
|
|
P5("..","..","..","g","foo"));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(kiwix::computeRelativePath(P3(A_SAMBA,"a","b"), P3(A_SAMBA,"a","foo")),
|
|
P2("..","foo"));
|
|
ASSERT_EQ(kiwix::computeRelativePath(P6(A_SAMBA,"a","b","c","d","e"), P5(A_SAMBA,"a","b","g","foo")),
|
|
P5("..","..","..","g","foo"));
|
|
|
|
#endif
|
|
}
|
|
|
|
TEST(pathTools, removeLastPathElement)
|
|
{
|
|
ASSERT_EQ(kiwix::removeLastPathElement(P3("a","b","c")),
|
|
P2("a","b"));
|
|
ASSERT_EQ(kiwix::removeLastPathElement(A3("a","b","c")),
|
|
A2("a","b"));
|
|
ASSERT_EQ(kiwix::removeLastPathElement(P4("a","b","c","")),
|
|
P2("a","b"));
|
|
ASSERT_EQ(kiwix::removeLastPathElement(A4("a","b","c","")),
|
|
A2("a","b"));
|
|
}
|
|
|
|
TEST(pathTools, appendToDirectory)
|
|
{
|
|
ASSERT_EQ(kiwix::appendToDirectory(P3("a","b","c"), "foo.xml"),
|
|
P4("a","b","c","foo.xml"));
|
|
ASSERT_EQ(kiwix::appendToDirectory(P4("a","b","c",""), "foo.xml"),
|
|
P4("a","b","c","foo.xml"));
|
|
ASSERT_EQ(kiwix::appendToDirectory(P3("a","b","c"), P2("d","foo.xml")),
|
|
P5("a","b","c","d","foo.xml"));
|
|
ASSERT_EQ(kiwix::appendToDirectory(P4("a","b","c",""), P2("d","foo.xml")),
|
|
P5("a","b","c","d","foo.xml"));
|
|
ASSERT_EQ(kiwix::appendToDirectory(P3("a","b","c"), P2(".","foo.xml")),
|
|
P5("a","b","c",".","foo.xml"));
|
|
ASSERT_EQ(kiwix::appendToDirectory(P4("a","b","c",""), P2(".","foo.xml")),
|
|
P5("a","b","c",".","foo.xml"));
|
|
}
|
|
|
|
TEST(pathTools, fileExists)
|
|
{
|
|
ASSERT_TRUE(kiwix::fileExists(P3(".","test","example.zim")));
|
|
ASSERT_FALSE(kiwix::fileExists(P3(".","test","noFile.zim")));
|
|
}
|
|
|
|
TEST(pathTools, fileReadable)
|
|
{
|
|
ASSERT_TRUE(kiwix::fileReadable(P3(".","test","example.zim")));
|
|
ASSERT_FALSE(kiwix::fileReadable(P3(".","test","noFile.zim")));
|
|
#ifdef _POSIX_SOURCE
|
|
std::string path = P3(".","test","example.zim");
|
|
auto myprivs = geteuid();
|
|
if (myprivs != 0) {
|
|
int fd = open(path.c_str(), O_RDONLY);
|
|
if (fd != -1) {
|
|
int wResp = fchmod(fd, ~(S_IRWXU | S_IRWXG | S_IRWXO)); // remove all permissions
|
|
if (wResp == 0) {
|
|
EXPECT_FALSE(kiwix::fileReadable(P3(".","test","example.zim")));
|
|
}
|
|
int resetResp = fchmod(fd, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP); // reset back permissions to -rw-rw-r--
|
|
if (resetResp == 0) {
|
|
EXPECT_TRUE(kiwix::fileReadable(P3(".","test","example.zim")));
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
TEST(pathTools, goUp)
|
|
{
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), ".."),
|
|
A2("a", "b"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P2("..","..")),
|
|
A1("a"));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P3("..","..","..")),
|
|
"c:");
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P4("..","..","..","..")),
|
|
"c:");
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), ".."),
|
|
P3(A_SAMBA,"a", "b"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), P2("..","..")),
|
|
P2(A_SAMBA,"a"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), P3("..","..","..")),
|
|
A_SAMBA);
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), P4("..","..","..","..")),
|
|
A_SAMBA);
|
|
|
|
#else
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P3("..","..","..")),
|
|
"/");
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P4("..","..","..","..")),
|
|
"/");
|
|
#endif
|
|
|
|
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P2("..", "foo")),
|
|
A3("a", "b","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P3("..","..","foo")),
|
|
A2("a","foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P4("..","..","..","foo")),
|
|
A1("foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(A3("a","b","c"), P5("..","..","..","..","foo")),
|
|
A1("foo"));
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), P4("..","..","..","foo")),
|
|
P2(A_SAMBA,"foo"));
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(P4(A_SAMBA,"a","b","c"), P5("..","..","..","..","foo")),
|
|
P2(A_SAMBA,"foo"));
|
|
#endif
|
|
}
|
|
|
|
|
|
#ifdef _WIN32
|
|
TEST(pathTools, dirChange)
|
|
{
|
|
std::string p1("c:\\a\\b\\c");
|
|
std::string p2("d:\\d\\e\\foo.xml");
|
|
{
|
|
std::string relative_path = kiwix::computeRelativePath(p1, p2);
|
|
ASSERT_EQ(relative_path, p2);
|
|
std::string abs_path = kiwix::computeAbsolutePath(p1, relative_path);
|
|
ASSERT_EQ(abs_path, p2);
|
|
ASSERT_EQ(kiwix::computeAbsolutePath(p1, "..\\..\\..\\..\\..\\d:\\d\\e\\foo.xml"), p2);
|
|
}
|
|
std::string ps("\\\\samba\\d\\e\\foo.xml");
|
|
{
|
|
std::string relative_path = kiwix::computeRelativePath(p1, ps);
|
|
ASSERT_EQ(relative_path, ps);
|
|
std::string abs_path = kiwix::computeAbsolutePath(p1, relative_path);
|
|
ASSERT_EQ(abs_path, ps);
|
|
// I'm not sure this test is valid on windows :/
|
|
// ASSERT_EQ(kiwix::computeAbsolutePath(p1, "..\\..\\..\\..\\..\\\\samba\\d\\e\\foo.xml"), ps);
|
|
}
|
|
}
|
|
|
|
TEST(pathTools, Utf8ToWide)
|
|
{
|
|
ASSERT_EQ(Utf8ToWide(u8""), L"");
|
|
ASSERT_EQ(Utf8ToWide(u8"test"), L"test");
|
|
ASSERT_EQ(Utf8ToWide(u8"testé`œà"), L"testé`œà");
|
|
}
|
|
|
|
TEST(pathTools, WideToUtf8)
|
|
{
|
|
ASSERT_EQ(WideToUtf8(L""), u8"");
|
|
ASSERT_EQ(WideToUtf8(L"test"), u8"test");
|
|
ASSERT_EQ(WideToUtf8(L"testé`œà"), u8"testé`œà");
|
|
}
|
|
#endif
|
|
|
|
|
|
};
|