diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2023-03-28 20:15:23 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2023-04-01 09:34:37 +0200 |
commit | 811b7c2f7eaac22e64cbb92508b67ccad5eed07c (patch) | |
tree | eb03e87880cf0d7916fee62f732018e1d54b5ce3 /src/linguist | |
parent | ec9dacb2e1c26caa4ae146e6ca30187a1f0e24fa (diff) | |
download | qttools-811b7c2f7eaac22e64cbb92508b67ccad5eed07c.tar.gz |
lupdate: Fix assert when applying number heuristics
There's an edge case in the number heuristics of lupdate that triggers a
Q_ASSERT due to an out-of-bounds string character access. To run into
the assert, the following must be true:
- oldSource == oldTranslation
- oldSource must contain a number followed immediately by more than one
characters
- oldSource and newSource must differ only in the character after the
number
Examples that trigger the assert:
| oldSource | newSource |
|------------+------------|
| "%1MiB" | "%1Kib" |
| "1Mi" | "1Ki" |
| "1M " | "1Ki " |
| "123abcde" | "123xbcde" |
Examples that do not trigger the assert:
| oldSource | newSource |
|------------+------------|
| "%1MiB" | "%1Kob" |
| "1M" | "1K" |
| "123abcde" | "123xxcde" |
Add a test case that triggers the Q_ASSERT.
Add a check to avoid the out-of-bounds access as a minimal fix. The
whole number heuristics algorithm is fishy and produces results that
don't match the source code comments. But it's been like that "forever",
so let's not change existing behavior people may rely on.
Pick-to: 6.5
Fixes: QTBUG-111775
Change-Id: Ibb6bcce9115f7060b6de3f97451e38105623c003
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
Diffstat (limited to 'src/linguist')
-rw-r--r-- | src/linguist/lupdate/merge.cpp | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/src/linguist/lupdate/merge.cpp b/src/linguist/lupdate/merge.cpp index 910aa1845..273ace6ad 100644 --- a/src/linguist/lupdate/merge.cpp +++ b/src/linguist/lupdate/merge.cpp @@ -106,10 +106,12 @@ static QString translationAttempt(const QString &oldTranslation, for (i = 0; i < oldTranslation.size(); i++) { attempt += oldTranslation[i]; for (k = 0; k < p; k++) { - if (oldTranslation[i] == oldNumbers[k][matchedYet[k]]) + if (matchedYet[k] < oldNumbers[k].size() && + oldTranslation[i] == oldNumbers[k][matchedYet[k]]) { matchedYet[k]++; - else + } else { matchedYet[k] = 0; + } } /* |