From 085f851bd8431a30bc84ee20bdb5c5aa51949f4e Mon Sep 17 00:00:00 2001 From: El Mehdi Fekari Date: Wed, 4 Dec 2013 16:58:25 +0100 Subject: QBBSystemLocale: Do not set fixed buffer size when reading pps objects Set dynamically the buffer size when reading pps objects since a pps file size is not always fix. Cherry-picked: qtbase/edf29a9aa93660ac8e4927db7fef2b5d925e9b59 Change-Id: Id55df6a474b6b79d96e3459e807f0bbfeacbf0cb Reviewed-by: Rafael Roquetto --- src/corelib/tools/qlocale_blackberry.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp index 44bf133..56bffbc 100644 --- a/src/corelib/tools/qlocale_blackberry.cpp +++ b/src/corelib/tools/qlocale_blackberry.cpp @@ -60,7 +60,7 @@ static const char ppsRegionLocalePath[] = "/pps/services/locale/settings"; static const char ppsLanguageLocalePath[] = "/pps/services/confstr/_CS_LOCALE"; static const char ppsHourFormatPath[] = "/pps/system/settings"; -static const size_t ppsBufferSize = 256; +static const int MAX_PPS_SIZE = 16000; QBBSystemLocaleData::QBBSystemLocaleData() : languageNotifier(0) @@ -186,9 +186,25 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd) if (!ppsObject || ppsFd == -1) return result; - char buffer[ppsBufferSize]; - int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1); + // PPS objects are of unknown size, but must be read all at once. + // Relying on the file size may not be a good idea since the size may change before reading. + // Let's try with an initial size (512), and if the buffer is too small try with bigger one, + // until we succeed or until other non buffer-size-related error occurs. + // Using QVarLengthArray means the first try (of size == 512) uses a buffer on the stack - no allocation necessary. + // Hopefully that covers most use cases. + int bytes; + QVarLengthArray buffer; + for (;;) { + errno = 0; + bytes = qt_safe_read(ppsFd, buffer.data(), buffer.capacity() - 1); + const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.capacity() < MAX_PPS_SIZE); + if (!bufferIsTooSmall) + break; + + buffer.resize(qMin(buffer.capacity()*2, MAX_PPS_SIZE)); + } + // This method is called in the ctor(), so do not use qWarning to log warnings // if qt_safe_read fails to read the pps file // since the user code may install a message handler that invokes QLocale API again @@ -202,7 +218,7 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd) pps_decoder_t ppsDecoder; pps_decoder_initialize(&ppsDecoder, 0); - if (pps_decoder_parse_pps_str(&ppsDecoder, buffer) == PPS_DECODER_OK) { + if (pps_decoder_parse_pps_str(&ppsDecoder, buffer.data()) == PPS_DECODER_OK) { pps_decoder_push(&ppsDecoder, 0); const char *ppsBuff; if (pps_decoder_get_string(&ppsDecoder, ppsObject, &ppsBuff) == PPS_DECODER_OK) { -- cgit v0.12