Reimplement hyphenator with Rust
Bug: 319145324
Bug: 319140825
Bug: 339717607
Bug: 274835275
Bug: 346915432
Test: minikin_tests
Flag: com.android.text.flags.rust_hyphenator
Change-Id: I47a5612a05bd0177043d7533a373e1ad5d2e8f35
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index 7023ef7..8836c8a 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -211,3 +211,12 @@
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "rust_hyphenator"
+ namespace: "text"
+ description: "Reimplement hyphenator for safe file read"
+ # Hyphenator is initialized in Zygote
+ is_fixed_read_only: true
+ bug: "346915432"
+}
diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp
index b6bf617..89fdeeb 100644
--- a/core/jni/android_text_Hyphenator.cpp
+++ b/core/jni/android_text_Hyphenator.cpp
@@ -36,41 +36,43 @@
return SYSTEM_HYPHENATOR_PREFIX + lowerLocale + SYSTEM_HYPHENATOR_SUFFIX;
}
-static const uint8_t* mmapPatternFile(const std::string& locale) {
+static std::pair<const uint8_t*, size_t> mmapPatternFile(const std::string& locale) {
const std::string hyFilePath = buildFileName(locale);
const int fd = open(hyFilePath.c_str(), O_RDONLY | O_CLOEXEC);
if (fd == -1) {
- return nullptr; // Open failed.
+ return std::make_pair(nullptr, 0); // Open failed.
}
struct stat st = {};
if (fstat(fd, &st) == -1) { // Unlikely to happen.
close(fd);
- return nullptr;
+ return std::make_pair(nullptr, 0);
}
void* ptr = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0 /* offset */);
close(fd);
if (ptr == MAP_FAILED) {
- return nullptr;
+ return std::make_pair(nullptr, 0);
}
- return reinterpret_cast<const uint8_t*>(ptr);
+ return std::make_pair(reinterpret_cast<const uint8_t*>(ptr), st.st_size);
}
static void addHyphenatorWithoutPatternFile(const std::string& locale, int minPrefix,
int minSuffix) {
- minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
- nullptr, minPrefix, minSuffix, locale));
+ minikin::addHyphenator(locale,
+ minikin::Hyphenator::loadBinary(nullptr, 0, minPrefix, minSuffix,
+ locale));
}
static void addHyphenator(const std::string& locale, int minPrefix, int minSuffix) {
- const uint8_t* ptr = mmapPatternFile(locale);
- if (ptr == nullptr) {
+ std::pair<const uint8_t*, size_t> r = mmapPatternFile(locale);
+ if (r.first == nullptr) {
ALOGE("Unable to find pattern file or unable to map it for %s", locale.c_str());
return;
}
- minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
- ptr, minPrefix, minSuffix, locale));
+ minikin::addHyphenator(locale,
+ minikin::Hyphenator::loadBinary(r.first, r.second, minPrefix, minSuffix,
+ locale));
}
static void addHyphenatorAlias(const std::string& from, const std::string& to) {