diff options
author | plundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 02:20:57 +0000 |
---|---|---|
committer | plundblad@chromium.org <plundblad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 02:20:57 +0000 |
commit | 593a7c08527f209bfa0649634ae7873ca84ef7bc (patch) | |
tree | 8d8257aefcf4c4266ef4cb7e7ded3f100d3e19a7 /third_party | |
parent | b051cdb6465736e7233cd22b807e255554378206 (diff) | |
download | chromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.zip chromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.tar.gz chromium_src-593a7c08527f209bfa0649634ae7873ca84ef7bc.tar.bz2 |
Fix braille backtranslation size limit.
Sometimes, a contracted string results in more than twice the
size of the input being the result of back translation. This is especially
true for small strings (e.g. a single letter k translating to knowledgable).
This CL uses a similar approach as
https://codereview.chromium.org/124403002
expanding the allocated buffer, working around liblouis api quirks.
BUG=310285
R=dtseng@chromium.org
Review URL: https://codereview.chromium.org/183653002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254023 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc index 67c6341..2fff14e 100644 --- a/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc +++ b/third_party/liblouis/nacl_wrapper/liblouis_wrapper.cc @@ -197,17 +197,39 @@ bool LibLouisWrapper::BackTranslate(const std::string& table_name, // Set the high-order bit to prevent liblouis from dropping empty cells. inbuf.push_back(*it | 0x8000); } - int inlen = inbuf.size(); - int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately. - std::vector<widechar> outbuf(outlen); + // To avoid unsigned/signed comparison warnings. + int inbufsize = inbuf.size(); + std::vector<widechar> outbuf; + int outlen; + + // Invoke liblouis. Do this in a loop since we can't precalculate the + // translated size. We add an extra slot in the output buffer so that + // common cases like single digits or capital letters won't always trigger + // retranslations (see the comments above the second exit condition inside + // the loop). We also set an arbitrary upper bound for the allocation + // to make sure the loop exits without running out of memory. + for (int outalloc = (inbufsize + 1) * 2, maxoutalloc = (inbufsize + 1) * 8; + outalloc <= maxoutalloc; outalloc *= 2) { + int inlen = inbufsize; + outlen = outalloc; + outbuf.resize(outalloc); - // Invoke liblouis. - int result = lou_backTranslateString(table_name.c_str(), - &inbuf[0], &inlen, &outbuf[0], &outlen, + int result = lou_backTranslateString( + table_name.c_str(), &inbuf[0], &inlen, &outbuf[0], &outlen, NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */); - if (result == 0) { - // TODO(njbroman): log this - return false; + if (result == 0) { + // TODO(jbroman): log this + return false; + } + + // If all of inbuf was not consumed, the output buffer must be too small + // and we have to retry with a larger buffer. + // In addition, if all of outbuf was exhausted, there's no way to know if + // more space was needed, so we'll have to retry the translation in that + // corner case as well. + if (inlen == inbufsize && outlen < outalloc) + break; + outbuf.clear(); } // Massage the result. |