summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Abecasis <joao@abecasis.name>2009-11-20 12:50:41 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2009-11-23 12:13:17 (GMT)
commit6adeb8be007bfdeaeb7e1d4a730abf32dbdb0f7d (patch)
tree2398fdf65014314156c4850ce22fecc0535f89c0
parentd180aa547065698cf18d25c65730689ae456c802 (diff)
downloadQt-6adeb8be007bfdeaeb7e1d4a730abf32dbdb0f7d.zip
Qt-6adeb8be007bfdeaeb7e1d4a730abf32dbdb0f7d.tar.gz
Qt-6adeb8be007bfdeaeb7e1d4a730abf32dbdb0f7d.tar.bz2
Fix regression introduced in 1e6b424b692b20dcfec920f8d3563e520ec1ff05
When processing the result of QIODevice::readLine, forgot to take into account that a '\0' is appended to the array. The terminating character is not accounted for in the number of bytes returned. By pre-allocating a byte for the terminating null character, we make sure we'll actually read 16k bytes on each and every iteration. Task-number: QTBUG-6019 Reviewed-by: Thiago Macieira (cherry picked from commit b7692016f282251002b3e85dfcb5567bd91a12c0)
-rw-r--r--src/corelib/io/qiodevice.cpp6
-rw-r--r--tests/auto/qiodevice/tst_qiodevice.cpp112
2 files changed, 117 insertions, 1 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 0248224..3b569b7 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1164,6 +1164,10 @@ QByteArray QIODevice::readLine(qint64 maxSize)
// If resize fails or maxSize == 0, read incrementally
if (maxSize == 0)
maxSize = INT_MAX;
+
+ // The first iteration needs to leave an extra byte for the terminating null
+ result.resize(1);
+
qint64 readResult;
do {
result.resize(int(qMin(maxSize, result.size() + QIODEVICE_BUFFERSIZE)));
@@ -1171,7 +1175,7 @@ QByteArray QIODevice::readLine(qint64 maxSize)
if (readResult > 0 || readBytes == 0)
readBytes += readResult;
} while (readResult == QIODEVICE_BUFFERSIZE
- && result[int(readBytes)] != '\n');
+ && result[int(readBytes - 1)] != '\n');
} else
readBytes = readLine(result.data(), result.size());
diff --git a/tests/auto/qiodevice/tst_qiodevice.cpp b/tests/auto/qiodevice/tst_qiodevice.cpp
index 340bf3a..af6d52c 100644
--- a/tests/auto/qiodevice/tst_qiodevice.cpp
+++ b/tests/auto/qiodevice/tst_qiodevice.cpp
@@ -77,6 +77,9 @@ private slots:
void readLine_data();
void readLine();
+
+ void readLine2_data();
+ void readLine2();
};
// Testing get/set functions
@@ -453,5 +456,114 @@ void tst_QIODevice::readLine()
QCOMPARE(line.size(), linelen);
}
+void tst_QIODevice::readLine2_data()
+{
+ QTest::addColumn<QByteArray>("line");
+
+ QTest::newRow("1024 - 4") << QByteArray(1024 - 4, 'x');
+ QTest::newRow("1024 - 3") << QByteArray(1024 - 3, 'x');
+ QTest::newRow("1024 - 2") << QByteArray(1024 - 2, 'x');
+ QTest::newRow("1024 - 1") << QByteArray(1024 - 1, 'x');
+ QTest::newRow("1024" ) << QByteArray(1024 , 'x');
+ QTest::newRow("1024 + 1") << QByteArray(1024 + 1, 'x');
+ QTest::newRow("1024 + 2") << QByteArray(1024 + 2, 'x');
+
+ QTest::newRow("4096 - 4") << QByteArray(4096 - 4, 'x');
+ QTest::newRow("4096 - 3") << QByteArray(4096 - 3, 'x');
+ QTest::newRow("4096 - 2") << QByteArray(4096 - 2, 'x');
+ QTest::newRow("4096 - 1") << QByteArray(4096 - 1, 'x');
+ QTest::newRow("4096" ) << QByteArray(4096 , 'x');
+ QTest::newRow("4096 + 1") << QByteArray(4096 + 1, 'x');
+ QTest::newRow("4096 + 2") << QByteArray(4096 + 2, 'x');
+
+ QTest::newRow("8192 - 4") << QByteArray(8192 - 4, 'x');
+ QTest::newRow("8192 - 3") << QByteArray(8192 - 3, 'x');
+ QTest::newRow("8192 - 2") << QByteArray(8192 - 2, 'x');
+ QTest::newRow("8192 - 1") << QByteArray(8192 - 1, 'x');
+ QTest::newRow("8192" ) << QByteArray(8192 , 'x');
+ QTest::newRow("8192 + 1") << QByteArray(8192 + 1, 'x');
+ QTest::newRow("8192 + 2") << QByteArray(8192 + 2, 'x');
+
+ QTest::newRow("16384 - 4") << QByteArray(16384 - 4, 'x');
+ QTest::newRow("16384 - 3") << QByteArray(16384 - 3, 'x');
+ QTest::newRow("16384 - 2") << QByteArray(16384 - 2, 'x');
+ QTest::newRow("16384 - 1") << QByteArray(16384 - 1, 'x');
+ QTest::newRow("16384" ) << QByteArray(16384 , 'x');
+ QTest::newRow("16384 + 1") << QByteArray(16384 + 1, 'x');
+ QTest::newRow("16384 + 2") << QByteArray(16384 + 2, 'x');
+
+ QTest::newRow("20000") << QByteArray(20000, 'x');
+
+ QTest::newRow("32768 - 4") << QByteArray(32768 - 4, 'x');
+ QTest::newRow("32768 - 3") << QByteArray(32768 - 3, 'x');
+ QTest::newRow("32768 - 2") << QByteArray(32768 - 2, 'x');
+ QTest::newRow("32768 - 1") << QByteArray(32768 - 1, 'x');
+ QTest::newRow("32768" ) << QByteArray(32768 , 'x');
+ QTest::newRow("32768 + 1") << QByteArray(32768 + 1, 'x');
+ QTest::newRow("32768 + 2") << QByteArray(32768 + 2, 'x');
+
+ QTest::newRow("40000") << QByteArray(40000, 'x');
+}
+
+void tst_QIODevice::readLine2()
+{
+ QFETCH(QByteArray, line);
+
+ int length = line.size();
+
+ QByteArray data("First line.\r\n");
+ data.append(line);
+ data.append("\r\n");
+ data.append(line);
+ data.append("\r\n");
+ data.append("\r\n0123456789");
+
+ {
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+
+ buffer.seek(0);
+ QByteArray temp;
+ temp.resize(64536);
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(13));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(2));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(10));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(-1));
+
+ buffer.seek(0);
+ QCOMPARE(buffer.readLine().size(), 13);
+ QCOMPARE(buffer.readLine().size(), length + 2);
+ QCOMPARE(buffer.readLine().size(), length + 2);
+ QCOMPARE(buffer.readLine().size(), 2);
+ QCOMPARE(buffer.readLine().size(), 10);
+ QVERIFY(buffer.readLine().isNull());
+ }
+
+ {
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly | QIODevice::Text);
+
+ buffer.seek(0);
+ QByteArray temp;
+ temp.resize(64536);
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(12));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(length + 1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(1));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(10));
+ QCOMPARE(buffer.readLine(temp.data(), temp.size()), qint64(-1));
+
+ buffer.seek(0);
+ QCOMPARE(buffer.readLine().size(), 12);
+ QCOMPARE(buffer.readLine().size(), length + 1);
+ QCOMPARE(buffer.readLine().size(), length + 1);
+ QCOMPARE(buffer.readLine().size(), 1);
+ QCOMPARE(buffer.readLine().size(), 10);
+ QVERIFY(buffer.readLine().isNull());
+ }
+}
+
QTEST_MAIN(tst_QIODevice)
#include "tst_qiodevice.moc"