diff options
Diffstat (limited to 'tests/auto/gui')
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 8 | ||||
-rw-r--r-- | tests/auto/gui/image/qimagereader/images/oss-fuzz-23988.xpm | 1 | ||||
-rw-r--r-- | tests/auto/gui/image/qimagereader/tst_qimagereader.cpp | 45 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qwindow/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 3 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 31 | ||||
-rw-r--r-- | tests/auto/gui/text/qfont/tst_qfont.cpp | 4 | ||||
-rw-r--r-- | tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp | 193 | ||||
-rw-r--r-- | tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp | 57 |
9 files changed, 332 insertions, 13 deletions
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index bb81b9f61f..b2873d6f8a 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -3324,6 +3324,14 @@ void tst_QImage::pixelColor() // Try setting an invalid color. QTest::ignoreMessage(QtWarningMsg, "QImage::setPixelColor: color is invalid"); argb32.setPixelColor(0, 0, QColor()); + + // Test correct premultiplied handling of RGBA64 as well + QImage rgba64(1, 1, QImage::Format_RGBA64); + QImage rgba64pm(1, 1, QImage::Format_RGBA64_Premultiplied); + rgba64.setPixelColor(QPoint(0, 0), c); + rgba64pm.setPixelColor(QPoint(0, 0), c); + QCOMPARE(rgba64.pixelColor(QPoint(0, 0)), c); + QCOMPARE(rgba64pm.pixelColor(QPoint(0, 0)), c); } void tst_QImage::pixel() diff --git a/tests/auto/gui/image/qimagereader/images/oss-fuzz-23988.xpm b/tests/auto/gui/image/qimagereader/images/oss-fuzz-23988.xpm new file mode 100644 index 0000000000..7e6c1e4ca2 --- /dev/null +++ b/tests/auto/gui/image/qimagereader/images/oss-fuzz-23988.xpm @@ -0,0 +1 @@ +/* XPM "20 8 1 7"" ÿÿ c ÿ" " ÿÿÿÿÿÿÿ "
\ No newline at end of file diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 1eee2f273e..61b11a7779 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -167,6 +167,9 @@ private slots: void devicePixelRatio_data(); void devicePixelRatio(); + void xpmBufferOverflow(); + void xbmBufferHandling(); + private: QString prefix; QTemporaryDir m_temporaryDir; @@ -2002,5 +2005,47 @@ void tst_QImageReader::devicePixelRatio() QCOMPARE(img.devicePixelRatio(), dpr); } +void tst_QImageReader::xpmBufferOverflow() +{ + // Please note that the overflow only showed when Qt was configured with "-sanitize address". + QImageReader(":/images/oss-fuzz-23988.xpm").read(); +} + +void tst_QImageReader::xbmBufferHandling() +{ + uint8_t original_buffer[256]; + for (int i = 0; i < 256; ++i) + original_buffer[i] = i; + + QImage image(original_buffer, 256, 8, QImage::Format_MonoLSB); + image.setColorTable({0xff000000, 0xffffffff}); + + QByteArray buffer; + { + QBuffer buf(&buffer); + QImageWriter writer(&buf, "xbm"); + writer.write(image); + } + + QCOMPARE(QImage::fromData(buffer, "xbm"), image); + + auto i = buffer.indexOf(','); + buffer.insert(i + 1, " "); + QCOMPARE(QImage::fromData(buffer, "xbm"), image); + buffer.insert(i + 1, " "); + QCOMPARE(QImage::fromData(buffer, "xbm"), image); + buffer.insert(i + 1, " "); +#if 0 // Lines longer than 300 chars not supported currently + QCOMPARE(QImage::fromData(buffer, "xbm"), image); +#endif + + i = buffer.lastIndexOf("\n "); + buffer.truncate(i + 1); + buffer.append(QByteArray(297, ' ')); + buffer.append("0x"); + // Only check we get no buffer overflow + QImage::fromData(buffer, "xbm"); +} + QTEST_MAIN(tst_QImageReader) #include "tst_qimagereader.moc" diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index 1820499a53..3486130e93 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -33,15 +33,12 @@ osx-10.12 ci [testInputEvents] rhel-7.4 [isActive] -# QTBUG-67768 -ubuntu # QTBUG-69157 android [exposeEventOnShrink_QTBUG54040] # QTBUG-69155 android -opensuse [initialSize] # QTBUG-69159 android diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 17289e0b85..f5bfa683d6 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -324,6 +324,9 @@ void tst_QColor::namehex_data() QTest::newRow("transparent red") << "#66ff0000" << QColor(255, 0, 0, 102); QTest::newRow("invalid red") << "#gg0000" << QColor(); QTest::newRow("invalid transparent") << "#gg00ff00" << QColor(); + // when configured with "-sanitize undefined", this resulted in: + // "runtime error: left shift of negative value -1" + QTest::newRow("oss-fuzz 23968") << "#ÿÿÿÿÿÿÿÿÿ" << QColor(); } void tst_QColor::namehex() diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index bc0baed15c..697dcfa4a4 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -300,6 +300,7 @@ private slots: void fillPolygon(); void drawImageAtPointF(); + void scaledDashes(); private: void fillData(); @@ -5308,6 +5309,36 @@ void tst_QPainter::drawImageAtPointF() paint.end(); } +void tst_QPainter::scaledDashes() +{ + // Test that we do not hit the limit-huge-number-of-dashes path + QRgb fore = qRgb(0, 0, 0xff); + QRgb back = qRgb(0xff, 0xff, 0); + QImage image(5, 32, QImage::Format_RGB32); + image.fill(back); + QPainter p(&image); + QPen pen(QColor(fore), 3, Qt::DotLine); + p.setPen(pen); + p.scale(1, 2); + p.drawLine(2, 0, 2, 16); + p.end(); + + bool foreFound = false; + bool backFound = false; + int i = 0; + while (i < 32 && (!foreFound || !backFound)) { + QRgb pix = image.pixel(3, i); + if (pix == fore) + foreFound = true; + else if (pix == back) + backFound = true; + i++; + } + + QVERIFY(foreFound); + QVERIFY(backFound); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 8090f38a2c..186f71302f 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -515,10 +515,10 @@ void tst_QFont::defaultFamily_data() QTest::addColumn<QStringList>("acceptableFamilies"); QTest::newRow("serif") << QFont::Serif << (QStringList() << "Times New Roman" << "Times" << "Droid Serif" << getPlatformGenericFont("serif").split(",")); - QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << "Droid Sans Mono" << getPlatformGenericFont("monospace").split(",")); + QTest::newRow("monospace") << QFont::Monospace << (QStringList() << "Courier New" << "Monaco" << "Menlo" << "Droid Sans Mono" << getPlatformGenericFont("monospace").split(",")); QTest::newRow("cursive") << QFont::Cursive << (QStringList() << "Comic Sans MS" << "Apple Chancery" << "Roboto" << "Droid Sans" << getPlatformGenericFont("cursive").split(",")); QTest::newRow("fantasy") << QFont::Fantasy << (QStringList() << "Impact" << "Zapfino" << "Roboto" << "Droid Sans" << getPlatformGenericFont("fantasy").split(",")); - QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << "Roboto" << "Droid Sans" << "Segoe UI" << getPlatformGenericFont("sans-serif").split(",")); + QTest::newRow("sans-serif") << QFont::SansSerif << (QStringList() << "Arial" << "Lucida Grande" << "Helvetica" << "Roboto" << "Droid Sans" << "Segoe UI" << getPlatformGenericFont("sans-serif").split(",")); } void tst_QFont::defaultFamily() diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp index 59e93d127f..56df69dde8 100644 --- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp +++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp @@ -198,6 +198,9 @@ private slots: void shouldGenerateDifferentCodeDependingOnActiveLayers(); void shouldUseGlobalVariableRatherThanTemporaries(); void shouldGenerateTemporariesWisely(); + void shouldHandlePortNamesPrefixingOneAnother(); + void shouldHandleNodesWithMultipleOutputPorts(); + void shouldHandleExpressionsInInputNodes(); }; void tst_QShaderGenerator::shouldHaveDefaultState() @@ -1229,6 +1232,196 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely() } } +void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto color1 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color1.addRule(gl4, QShaderNode::Rule("vec4 $output = color1;", + QByteArrayList() << "in vec4 color1;")); + + auto color2 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color2.addRule(gl4, QShaderNode::Rule("vec4 $output = color2;", + QByteArrayList() << "in vec4 color2;")); + + auto addColor = createNode({ + createPort(QShaderNodePort::Output, "color"), + createPort(QShaderNodePort::Input, "color1"), + createPort(QShaderNodePort::Input, "color2"), + }); + addColor.addRule(gl4, QShaderNode::Rule("vec4 $color = $color1 + $color2;")); + + auto shaderOutput = createNode({ + createPort(QShaderNodePort::Input, "input") + }); + + shaderOutput.addRule(gl4, QShaderNode::Rule("shaderOutput = $input;", + QByteArrayList() << "out vec4 shaderOutput;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(color1); + res.addNode(color2); + res.addNode(addColor); + res.addNode(shaderOutput); + + res.addEdge(createEdge(color1.uuid(), "output", addColor.uuid(), "color1")); + res.addEdge(createEdge(color2.uuid(), "output", addColor.uuid(), "color2")); + res.addEdge(createEdge(addColor.uuid(), "color", shaderOutput.uuid(), "input")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "in vec4 color1;" + << "in vec4 color2;" + << "out vec4 shaderOutput;" + << "" + << "void main()" + << "{" + << " shaderOutput = ((color1 + color2));" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + +void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto input = createNode({ + createPort(QShaderNodePort::Output, "output0"), + createPort(QShaderNodePort::Output, "output1") + }); + input.addRule(gl4, QShaderNode::Rule("vec4 $output0 = globalIn0;" + "float $output1 = globalIn1;", + QByteArrayList() << "in vec4 globalIn0;" << "in float globalIn1;")); + + auto function = createNode({ + createPort(QShaderNodePort::Input, "input0"), + createPort(QShaderNodePort::Input, "input1"), + createPort(QShaderNodePort::Output, "output0"), + createPort(QShaderNodePort::Output, "output1") + }); + function.addRule(gl4, QShaderNode::Rule("vec4 $output0 = $input0;" + "float $output1 = $input1;")); + + auto output = createNode({ + createPort(QShaderNodePort::Input, "input0"), + createPort(QShaderNodePort::Input, "input1") + }); + + output.addRule(gl4, QShaderNode::Rule("globalOut0 = $input0;" + "globalOut1 = $input1;", + QByteArrayList() << "out vec4 globalOut0;" << "out float globalOut1;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(input); + res.addNode(function); + res.addNode(output); + + res.addEdge(createEdge(input.uuid(), "output0", function.uuid(), "input0")); + res.addEdge(createEdge(input.uuid(), "output1", function.uuid(), "input1")); + + res.addEdge(createEdge(function.uuid(), "output0", output.uuid(), "input0")); + res.addEdge(createEdge(function.uuid(), "output1", output.uuid(), "input1")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "in vec4 globalIn0;" + << "in float globalIn1;" + << "out vec4 globalOut0;" + << "out float globalOut1;" + << "" + << "void main()" + << "{" + << " globalOut0 = globalIn0;" + << " globalOut1 = globalIn1;" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + +void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto input = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;")); + + auto output = createNode({ + createPort(QShaderNodePort::Input, "input") + }); + + output.addRule(gl4, QShaderNode::Rule("globalOut = $input;", + QByteArrayList() << "out float globalOut;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(input); + res.addNode(output); + + res.addEdge(createEdge(input.uuid(), "output", output.uuid(), "input")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "out float globalOut;" + << "" + << "void main()" + << "{" + << " globalOut = 3 + 4;" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + QTEST_MAIN(tst_QShaderGenerator) #include "tst_qshadergenerator.moc" diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index ce2d38c24f..014a163f58 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -114,6 +114,7 @@ private slots: void shouldSurviveCyclesDuringGraphSerialization(); void shouldDealWithEdgesJumpingOverLayers(); void shouldGenerateDifferentStatementsDependingOnActiveLayers(); + void shouldDealWithBranchesWithoutOutput(); }; void tst_QShaderGraph::shouldHaveEdgeDefaultState() @@ -515,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Note that no edge leads to the unbound input + // Note that no statement has any unbound input const auto expected = QVector<QShaderGraph::Statement>() - << createStatement(input, {}, {0}) - << createStatement(function, {-1, 0, -1}, {2, 3, 4}) - << createStatement(unboundOutput, {-1}, {}) - << createStatement(output, {3}, {}); + << createStatement(input, {}, {0}); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -567,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle - const auto expected = QVector<QShaderGraph::Statement>() - << createStatement(output, {2}, {}); + // The cycle is ignored + const auto expected = QVector<QShaderGraph::Statement>(); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -774,6 +771,50 @@ void tst_QShaderGraph::shouldGenerateDifferentStatementsDependingOnActiveLayers( } } +void tst_QShaderGraph::shouldDealWithBranchesWithoutOutput() +{ + // GIVEN + const auto input = createNode({ + createPort(QShaderNodePort::Output, "input") + }); + const auto output = createNode({ + createPort(QShaderNodePort::Input, "output") + }); + const auto danglingFunction = createNode({ + createPort(QShaderNodePort::Input, "functionInput"), + createPort(QShaderNodePort::Output, "unbound") + }); + const auto function = createNode({ + createPort(QShaderNodePort::Input, "functionInput"), + createPort(QShaderNodePort::Output, "functionOutput") + }); + + const auto graph = [=] { + auto res = QShaderGraph(); + res.addNode(input); + res.addNode(function); + res.addNode(danglingFunction); + res.addNode(output); + res.addEdge(createEdge(input.uuid(), "input", function.uuid(), "functionInput")); + res.addEdge(createEdge(input.uuid(), "input", danglingFunction.uuid(), "functionInput")); + res.addEdge(createEdge(function.uuid(), "functionOutput", output.uuid(), "output")); + return res; + }(); + + // WHEN + const auto statements = graph.createStatements(); + + // THEN + // Note that no edge leads to the unbound input + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(input, {}, {0}) + << createStatement(function, {0}, {1}) + << createStatement(output, {1}, {}) + << createStatement(danglingFunction, {0}, {2}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); +} + QTEST_MAIN(tst_QShaderGraph) #include "tst_qshadergraph.moc" |