summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/documents/src/androidTest/java/org/the_jk/cleversync/documents/DocumentTreeAndroidTest.kt5
-rw-r--r--libs/samba/src/main/cpp/jni.cpp43
-rw-r--r--libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt13
3 files changed, 42 insertions, 19 deletions
diff --git a/libs/documents/src/androidTest/java/org/the_jk/cleversync/documents/DocumentTreeAndroidTest.kt b/libs/documents/src/androidTest/java/org/the_jk/cleversync/documents/DocumentTreeAndroidTest.kt
index d0d6bb3..8510ef1 100644
--- a/libs/documents/src/androidTest/java/org/the_jk/cleversync/documents/DocumentTreeAndroidTest.kt
+++ b/libs/documents/src/androidTest/java/org/the_jk/cleversync/documents/DocumentTreeAndroidTest.kt
@@ -133,6 +133,11 @@ class DocumentTreeAndroidTest : TreeAbstractTest() {
runTest { super.lastModified() }
}
+ @Test
+ override fun unicodeFilename() {
+ runTest { super.unicodeFilename() }
+ }
+
override fun supportSymlinks() = false
override fun idle() {
diff --git a/libs/samba/src/main/cpp/jni.cpp b/libs/samba/src/main/cpp/jni.cpp
index b7bbd1a..d3336ac 100644
--- a/libs/samba/src/main/cpp/jni.cpp
+++ b/libs/samba/src/main/cpp/jni.cpp
@@ -36,25 +36,26 @@ const char *_jni_error(jint err) {
const char* u8_read(const char* str, uint32_t& out) {
// Assume valid UTF-8 for speed and so it can be used to read modified utf-8 as well
- switch (*str >> 4) {
+ auto* const d = reinterpret_cast<const uint8_t*>(str);
+ switch (d[0] >> 4) {
case 0xf: // 4 byte
- out = (static_cast<uint32_t>(str[0] & 0x7) << 18) |
- (static_cast<uint32_t>(str[1] & 0x3f) << 12) |
- (static_cast<uint32_t>(str[2] & 0x3f) << 6) |
- static_cast<uint8_t>(str[3] & 0x3f);
+ out = (static_cast<uint32_t>(d[0] & 0x7) << 18) |
+ (static_cast<uint32_t>(d[1] & 0x3f) << 12) |
+ (static_cast<uint32_t>(d[2] & 0x3f) << 6) |
+ static_cast<uint8_t>(d[3] & 0x3f);
return str + 4;
case 0xe: // 3 byte
- out = (static_cast<uint32_t>(str[0] & 0xf) << 12) |
- (static_cast<uint32_t>(str[1] & 0x3f) << 6) |
- static_cast<uint8_t>(str[2] & 0x3f);
+ out = (static_cast<uint32_t>(d[0] & 0xf) << 12) |
+ (static_cast<uint32_t>(d[1] & 0x3f) << 6) |
+ static_cast<uint8_t>(d[2] & 0x3f);
return str + 3;
case 0xd:
case 0xc: // 2 byte
- out = (static_cast<uint32_t>(str[0] & 0x1f) << 6) |
- static_cast<uint8_t>(str[1] & 0x3f);
+ out = (static_cast<uint32_t>(d[0] & 0x1f) << 6) |
+ static_cast<uint8_t>(d[1] & 0x3f);
return str + 2;
default: // 1 byte
- out = static_cast<uint8_t>(str[0]);
+ out = static_cast<uint8_t>(d[0]);
return str + 1;
}
}
@@ -77,16 +78,17 @@ void u8_write(std::string& ret, uint32_t c) {
}
}
-std::string MakeModifiedUTF8(const char* str, const char* ptr, uint32_t c) {
+std::string MakeModifiedUTF8(const char* str, const char* prev, const char* ptr, uint32_t c) {
std::string ret;
while (true) {
- ret.append(str, ptr - str);
+ ret.append(str, prev - str);
str = ptr;
u8_write(ret, 0xd800 + ((c & 0xffff) >> 10));
u8_write(ret, 0xdc00 + (c & 0x3ff));
if (!*ptr) break;
do {
- ptr = u8_read(ptr, c);
+ prev = ptr;
+ ptr = u8_read(prev, c);
if (c > 0xffff)
break;
} while (*ptr);
@@ -98,15 +100,17 @@ std::optional<std::string> MakeModifiedUTF8IfNeeded(const char* str) {
auto* ptr = str;
while (*ptr) {
uint32_t c;
- ptr = u8_read(ptr, c);
+ auto* next = u8_read(ptr, c);
if (c > 0xffff) {
- return MakeModifiedUTF8(str, ptr, c);
+ return MakeModifiedUTF8(str, ptr, next, c);
}
+ ptr = next;
}
return std::nullopt;
}
-const char* splice(std::string& str, const char* start, const char* end, const char* insert, size_t size) {
+const char* splice(std::string& str, const char* start, const char* end,
+ const char* insert, size_t size) {
auto pos = start - str.c_str();
str.replace(pos, end - start, insert, size);
return str.c_str() + pos + size;
@@ -229,8 +233,9 @@ LocalRef<jthrowable> ExceptionOccurred(JNIEnv* env) {
std::string StringToUTF8(JNIEnv* env, const Ref<jstring>& str) {
if (!str) return "null";
- auto len = env->GetStringUTFLength(str.get());
- std::string ret(len, ' ');
+ auto size = env->GetStringUTFLength(str.get());
+ auto len = env->GetStringLength(str.get());
+ std::string ret(size, ' ');
env->GetStringUTFRegion(str.get(), 0, len, ret.data());
UnmodifyUTF8(ret);
return ret;
diff --git a/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt b/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt
index 396e801..2555195 100644
--- a/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt
+++ b/libs/test-utils/src/main/java/org/the_jk/cleversync/TreeAbstractTest.kt
@@ -353,6 +353,19 @@ abstract class TreeAbstractTest {
assertThat(old.isBefore(new) || old == new).isTrue()
}
+ @Test
+ open fun unicodeFilename() {
+ val file = tree.createFile("r\u00E4ksm\u00f6rg\u00E4s")
+ file.write().use { it.write("Delicious".toByteArray()) }
+ val dir = tree.createDirectory("\uD83D\uDCA9")
+
+ val content = tree.list()
+ assertThat(content.directories).hasSize(1)
+ assertThat(content.directories[0].name).isEqualTo(dir.name)
+ assertThat(content.files).hasSize(1)
+ assertThat(content.files[0].name).isEqualTo(file.name)
+ }
+
protected abstract fun supportSymlinks(): Boolean
protected abstract fun idle()