QMessagePattern: don't use strncpy()

When Qt is configured to return nullptr from isNull() QStrings
(QT5_NULL_STRINGS != 1), then we'd be feeding a nullptr src into
strncpy(), which is UB. I couldn't rule the case of a null QString
lexeme out with local reasoning, seeing as the code is in the else
branch of an if (lexeme.startsWith(~~~) && lexeme.endsWith(~~~)), so
it might be null.

Instead of porting to qstrncpy(), which can deal with a nullptr src
(albeit up to recently, badly), note that the strncpy + the char[]
allocation is a qstrdup(), so use that instead. This also does away
with the queasiness of taking the size() of a UTF-16 string to limit
strncpy() for the L1-recoded version (which, in this instance is safe,
as toLatin1().constData() is NUL-terminated, but in some other
instances was not).

As a drive-by, make sure we don't leak the strdup()'ed string if the
emplace_back() fails.

Amends be98fa32c7.

Qt 5 is not affected, as constData() never returns nullptr there.

Pick-to: 6.5 6.4 6.2
Change-Id: I178d356e560d2749cd6ce0b9364c710a2d117304
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Marc Mutz 2023-02-16 23:09:47 +01:00
parent 9f5a687ffe
commit 4a9e918d4e

View File

@ -1338,11 +1338,8 @@ void QMessagePattern::setPattern(const QString &pattern)
.arg(lexeme); .arg(lexeme);
} }
} else { } else {
char *literal = new char[lexeme.size() + 1]; using UP = std::unique_ptr<char[]>;
strncpy(literal, lexeme.toLatin1().constData(), lexeme.size()); tokens[i] = literalsVar.emplace_back(UP(qstrdup(lexeme.toLatin1().constData()))).get();
literal[lexeme.size()] = '\0';
literalsVar.emplace_back(literal);
tokens[i] = literal;
} }
} }
if (nestedIfError) if (nestedIfError)