Skip to content

Commit

Permalink
Replace utf8proc with una
Browse files Browse the repository at this point in the history
  • Loading branch information
netheril96 committed Mar 11, 2024
1 parent fdaae1b commit c6e04f3
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 1,797 deletions.
12 changes: 4 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ target_link_libraries(
if(SECUREFS_USE_VCPKG)
find_package(cryptopp CONFIG REQUIRED)
target_link_libraries(securefs-static PUBLIC cryptopp::cryptopp)
find_package(unofficial-utf8proc CONFIG REQUIRED)
target_link_libraries(securefs-static PUBLIC utf8proc)
find_package(unofficial-argon2 CONFIG REQUIRED)
target_link_libraries(securefs-static PUBLIC unofficial::argon2::libargon2)
find_package(jsoncpp CONFIG REQUIRED)
Expand All @@ -92,18 +90,16 @@ if(SECUREFS_USE_VCPKG)
target_link_libraries(securefs-static PUBLIC unofficial::sqlite3::sqlite3)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(UTF8PROC REQUIRED libutf8proc)
pkg_check_modules(ARGON2 REQUIRED libargon2)
pkg_check_modules(JSONCPP REQUIRED jsoncpp)
pkg_check_modules(SQLITE sqlite3 REQUIRED)
target_include_directories(
securefs-static SYSTEM
PUBLIC ${UTF8PROC_INCLUDE_DIRS} ${ARGON2_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIRS} ${SQLITE_INCLUDE_DIRS})
PUBLIC ${ARGON2_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIRS}
${SQLITE_INCLUDE_DIRS})
target_link_libraries(
securefs-static
PUBLIC ${CRYPTOPP_LDFLAGS} ${UTF8PROC_LDFLAGS} ${ARGON2_LDFLAGS}
${JSONCPP_LDFLAGS} ${SQLITE_LDFLAGS})
securefs-static PUBLIC ${CRYPTOPP_LDFLAGS} ${ARGON2_LDFLAGS}
${JSONCPP_LDFLAGS} ${SQLITE_LDFLAGS})
find_library(CRYPTOPP_FLAGS NAMES cryptopp crypto++)
target_link_libraries(securefs-static PUBLIC ${CRYPTOPP_FLAGS})
endif()
Expand Down
1,639 changes: 0 additions & 1,639 deletions LICENSE.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions sources/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "platform.h"
#include "win_get_proc.h" // IWYU pragma: keep

#include <absl/strings/escaping.h>
#include <absl/strings/match.h>
#include <absl/strings/str_format.h>
#include <argon2.h>
Expand All @@ -23,7 +24,6 @@
#include <json/json.h>
#include <optional>
#include <tclap/CmdLine.h>
#include <utf8proc.h>

#include <algorithm>
#include <iostream>
Expand Down Expand Up @@ -1083,7 +1083,9 @@ class MountCommand : public _SinglePasswordCommandBase
std::string result;
for (const auto& a : args)
{
result.append(securefs::escape_nonprintable(a.data(), a.size()));
result.push_back('\"');
result.append(absl::Utf8SafeCEscape(a));
result.push_back('\"');
result.push_back(' ');
}
if (!result.empty())
Expand Down Expand Up @@ -1652,8 +1654,6 @@ class VersionCommand : public CommandBase
absl::PrintF("libfuse %d\n", fuse_version_func());
#endif

absl::PrintF("utf8proc %s\n", utf8proc_version());

#ifdef CRYPTOPP_DISABLE_ASM
fputs("\nBuilt without hardware acceleration\n", stdout);
#else
Expand Down
59 changes: 31 additions & 28 deletions sources/lite_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
#include <cryptopp/blake2.h>
#include <cryptopp/sha.h>
#include <fruit/fruit.h>
#include <utf8proc.h>
#include <uni_algo/case.h>
#include <uni_algo/norm.h>

#include <array>
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <memory>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -482,36 +484,45 @@ namespace
{
};

struct tPathNormOption
{
};

class PathNormalizingNameTranslator : public NameTranslator
{
public:
INJECT(PathNormalizingNameTranslator(ANNOTATED(tInnerTranslator, NameTranslator&) delegate,
ANNOTATED(tPathNormOption, utf8proc_option_t)
map_option))
: delegate_(delegate), map_option_(map_option)
const NameNormalizationFlags& flags))
: delegate_(delegate), flags_(flags)
{
}

std::string encrypt_full_path(std::string_view path,
std::string* out_encrypted_last_component) override
{
uint8_t* normed_path = nullptr;
DEFER(free(normed_path));
auto normed_length = utf8proc_map(reinterpret_cast<const uint8_t*>(path.data()),
path.size(),
&normed_path,
map_option_);
if (normed_length <= 0)
try
{
std::string normed_string;
if (flags_.should_case_fold && flags_.should_normalize_nfc)
{
normed_string = una::norm::to_nfc_utf8(una::cases::to_casefold_utf8(path));
}
else if (flags_.should_normalize_nfc)
{
normed_string = una::norm::to_nfc_utf8(path);
}
else if (flags_.should_case_fold)
{
normed_string = una::cases::to_casefold_utf8(path);
}
else
{
return delegate_.encrypt_full_path(path, out_encrypted_last_component);
}
return delegate_.encrypt_full_path(std::string_view(normed_string),
out_encrypted_last_component);
}
catch (const std::exception& e)
{
WARN_LOG("Failed to normalize path %s: %s", path, e.what());
return delegate_.encrypt_full_path(path, out_encrypted_last_component);
}
return delegate_.encrypt_full_path(
std::string_view(reinterpret_cast<const char*>(normed_path), normed_length),
out_encrypted_last_component);
}

absl::variant<InvalidNameTag, LongNameTag, std::string>
Expand All @@ -536,7 +547,7 @@ namespace

private:
NameTranslator& delegate_;
utf8proc_option_t map_option_;
NameNormalizationFlags flags_;
};

class DirectoryImpl : public Directory
Expand Down Expand Up @@ -1124,15 +1135,7 @@ get_name_translator_component(std::shared_ptr<NameNormalizationFlags> flags)
return fruit::createComponent()
.bind<NameTranslator, PathNormalizingNameTranslator>()
.install(get_inner_translator, flags->supports_long_name)
.bindInstance(*flags)
.registerProvider<fruit::Annotated<tPathNormOption, utf8proc_option_t>(
const NameNormalizationFlags&)>(
[](const NameNormalizationFlags& flags)
{
return static_cast<utf8proc_option_t>(
UTF8PROC_STABLE | (flags.should_case_fold ? UTF8PROC_CASEFOLD : 0)
| (flags.should_normalize_nfc ? UTF8PROC_COMPOSE : 0));
});
.bindInstance(*flags);
}

std::string_view NameTranslator::get_last_component(std::string_view path)
Expand Down
57 changes: 0 additions & 57 deletions sources/mystring.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
#include "mystring.h"
#include "exceptions.h"
#include "logger.h"
#include "myutils.h"

#include <utf8proc.h>

#include <ctype.h>
#include <stdint.h>

namespace securefs
{

Expand Down Expand Up @@ -268,27 +262,6 @@ void base32_decode(const char* input, size_t size, std::string& output)
}
}

std::string escape_nonprintable(const char* str, size_t size)
{
std::string result;
result.reserve(size + size / 16);
for (size_t i = 0; i < size; ++i)
{
char c = str[i];
if (isprint(static_cast<unsigned char>(c)))
{
result.push_back(c);
}
else
{
char tmp[10];
snprintf(tmp, sizeof(tmp), "\\x%02x", static_cast<unsigned char>(c));
result.append(tmp);
}
}
return result;
}

bool is_ascii(std::string_view str)
{
for (char c : str)
Expand All @@ -300,34 +273,4 @@ bool is_ascii(std::string_view str)
}
return true;
}

MultipleOwnershipString transform(std::string_view str, bool case_fold, bool nfc)
{
if (!case_fold && (!nfc || is_ascii(str)))
{
return MultipleOwnershipString(str);
}
utf8proc_uint8_t* result = nullptr;
int options = UTF8PROC_STABLE;
if (case_fold)
{
options |= UTF8PROC_CASEFOLD;
}
if (nfc)
{
options |= UTF8PROC_COMPOSE;
}
auto rc = utf8proc_map(reinterpret_cast<const utf8proc_uint8_t*>(str.data()),
static_cast<utf8proc_ssize_t>(str.size()),
&result,
static_cast<utf8proc_option_t>(options));
if (rc < 0 || !result)
{
ERROR_LOG("Failed to transform string \"%s\": %s",
escape_nonprintable(str.data(), str.size()).c_str(),
utf8proc_errmsg(rc));
return MultipleOwnershipString(str);
}
return MultipleOwnershipString(reinterpret_cast<char*>(result));
}
} // namespace securefs
30 changes: 0 additions & 30 deletions sources/mystring.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,5 @@ inline std::string hexify(const ByteContainer& c)
void base32_encode(const byte* input, size_t size, std::string& output);
void base32_decode(const char* input, size_t size, std::string& output);

std::string escape_nonprintable(const char* str, size_t size);
std::string case_fold(std::string_view str);

class MultipleOwnershipString
{
public:
explicit MultipleOwnershipString(std::string_view view) : holder_(view) {}
explicit MultipleOwnershipString(char* p) : holder_(std::unique_ptr<char, CFreer>(p)) {}

std::string_view view() const noexcept { return absl::visit(ViewVisitor(), holder_); }

private:
struct CFreer
{
void operator()(char* p) const noexcept { free(p); }
};
absl::variant<std::string_view, std::unique_ptr<char, CFreer>> holder_;

struct ViewVisitor
{
std::string_view operator()(std::string_view view) const noexcept { return view; }
std::string_view operator()(const std::unique_ptr<char, CFreer>& value) const noexcept
{
return value.get();
}
};
};

MultipleOwnershipString transform(std::string_view str, bool case_fold, bool nfc);

bool is_ascii(std::string_view str);
} // namespace securefs
7 changes: 2 additions & 5 deletions sources/operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,8 @@ namespace internal

FileGuard open_base_dir(FileSystemContext* fs, const char* path, std::string& last_component)
{
absl::InlinedVector<std::string, 32> components = absl::StrSplit(
transform(path, fs->flags & kOptionCaseFoldFileName, fs->flags & kOptionNFCFileName)
.view(),
absl::ByChar('/'),
absl::SkipEmpty());
absl::InlinedVector<std::string, 32> components
= absl::StrSplit(path, absl::ByChar('/'), absl::SkipEmpty());

FileGuard result(&fs->table, fs->table.open_as(fs->root_id, FileBase::DIRECTORY));
if (components.empty())
Expand Down
25 changes: 0 additions & 25 deletions test/test_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,31 +88,6 @@ TEST_CASE("our base32 against CryptoPP")
}
}

TEST_CASE("case fold")
{
auto case_fold
= [](const char* str) { return std::string(securefs::transform(str, true, false).view()); };

REQUIRE(case_fold("abCdEfG") == "abcdefg");
REQUIRE(case_fold("\xc8\xba") == "\xe2\xb1\xa5");
REQUIRE(case_fold(
"AabC\xce\xa3\xce\xaf\xcf\x83\xcf\x85\xcf\x86\xce\xbf\xcf\x82\xef\xac\x81\xc3\x86")
== "\x61\x61\x62\x63\xcf\x83\xce\xaf\xcf\x83\xcf\x85\xcf\x86\xce\xbf\xcf\x83\x66\x69"
"\xc3\xa6");
}

TEST_CASE("NFC")
{
auto nfc
= [](const char* str) { return std::string(securefs::transform(str, false, true).view()); };

REQUIRE(nfc("\x41\xcc\x88\x66\x66\x69\x6e") == "\xc3\x84\x66\x66\x69\x6e");
REQUIRE(nfc("Henry IV") == "Henry IV");
REQUIRE(nfc("") == "");
REQUIRE(nfc("abc") == "abc");
REQUIRE(nfc("\xe8\xb0\xb7\xe6\xad\x8c") == "\xe8\xb0\xb7\xe6\xad\x8c");
}

TEST_CASE("is_ascii")
{
REQUIRE(securefs::is_ascii(""));
Expand Down
1 change: 0 additions & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"argon2",
"cryptopp",
"tclap",
"utf8proc",
"doctest",
"jsoncpp",
"sqlite3",
Expand Down

0 comments on commit c6e04f3

Please sign in to comment.