Skip to content

Commit

Permalink
Reimplement hyphenator with Rust
Browse files Browse the repository at this point in the history
Bug: 319145324
Bug: 319140825
Bug: 339717607
Bug: 274835275
Bug: 346915432
Test: minikin_tests
Flag: com.android.text.flags.rust_hyphenator
Change-Id: I47a5612a05bd0177043d7533a373e1ad5d2e8f35
  • Loading branch information
nona-google committed Jun 13, 2024
1 parent 2b683b7 commit f127d5f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
9 changes: 9 additions & 0 deletions core/java/android/text/flags/flags.aconfig
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,12 @@ flag {
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"
}
24 changes: 13 additions & 11 deletions core/jni/android_text_Hyphenator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,43 @@ static std::string buildFileName(const std::string& locale) {
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) {
Expand Down

0 comments on commit f127d5f

Please sign in to comment.