From 68f76d61d74f9f73085105d541b4d0a5e7df0317 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 28 May 2024 00:05:45 -0400 Subject: [PATCH] libroot_build: Add a "hex-encoded attribute names" mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some systems (e.g. NTFS through WSL1) support arbitrarily-large extended attributes, but do not preserve case on attribute names (or disallow more characters than the existing manglers took care of.) So, this adds a mode in which attribute names are encoded as hexadecimal. At present it must be manually enabled; in the future it may be possible to modify ./configure to activate it automatically. Change-Id: If20e4cb1cf4153cccc918ce6d51761426055290c Reviewed-on: https://review.haiku-os.org/c/haiku/+/7698 Reviewed-by: waddlesplash Tested-by: Commit checker robot Reviewed-by: Jérôme Duval --- src/build/libroot/fs_attr_untyped.cpp | 47 +++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/build/libroot/fs_attr_untyped.cpp b/src/build/libroot/fs_attr_untyped.cpp index aa96cd041b..ded2574f04 100644 --- a/src/build/libroot/fs_attr_untyped.cpp +++ b/src/build/libroot/fs_attr_untyped.cpp @@ -62,7 +62,48 @@ static const size_t kMaxAttributeListingLength = 10240; static const size_t kMaxAttributeLength = 10240 * 4; -// mangle_attribute_name +//#define HEX_ENCODE_ATTRIBUTE_NAMES +#ifdef HEX_ENCODE_ATTRIBUTE_NAMES +static string +mangle_attribute_name(const char* name) +{ + string mangledName = kAttributeNamespace; + + static const char* const kHexChars = "0123456789abcdef"; + for (int i = 0; name[i] != '\0'; i++) { + mangledName += kHexChars[name[i] >> 4]; + mangledName += kHexChars[name[i] & 0xf]; + } + + return mangledName; +} + + +static bool +demangle_attribute_name(const char* name, string& demangledName) +{ + if (strncmp(name, kAttributeNamespace, kAttributeNamespaceLen) != 0) + return false; + + name += kAttributeNamespaceLen; + + demangledName = ""; + + for (int i = 0; name[i] != '\0'; i += 2) { + char c[3]; + c[2] = '\0'; + memcpy(c, name + i, 2); + + char out; + out = strtol(c, NULL, 16); + if (out == '\0') + return false; + demangledName += out; + } + + return true; +} +#else static string mangle_attribute_name(const char* name) { @@ -89,11 +130,10 @@ mangle_attribute_name(const char* name) } -// demangle_attribute_name static bool demangle_attribute_name(const char* name, string& demangledName) { - // chop of our xattr namespace and translate: + // chop off our xattr namespace and translate: // "%\" -> '/' // "%%" -> '%' @@ -120,6 +160,7 @@ demangle_attribute_name(const char* name, string& demangledName) return true; } +#endif namespace {