diff options
author | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-09-01 13:53:26 +0200 |
---|---|---|
committer | Kurt Pattyn <pattyn.kurt@gmail.com> | 2013-09-01 13:53:26 +0200 |
commit | 60357fb995f543202b0dfe09eece6120a62427f4 (patch) | |
tree | da9d259ebb22044623d7ea9320e95ebba2aac9bc /tests | |
parent | 63231ee164859fbc468143da07fafc867a2ee301 (diff) | |
download | qtwebsockets-60357fb995f543202b0dfe09eece6120a62427f4.tar.gz |
Added tests for valid and invalid close codes
Added tests for invalid UTF8 sequences in close frames
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tst_dataprocessor.cpp | 370 |
1 files changed, 284 insertions, 86 deletions
diff --git a/tests/tst_dataprocessor.cpp b/tests/tst_dataprocessor.cpp index 3f89dc3..89685c9 100644 --- a/tests/tst_dataprocessor.cpp +++ b/tests/tst_dataprocessor.cpp @@ -15,11 +15,14 @@ Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode) //TODO: test on masking correctness //TODO: test for valid fields //TODO: test for valid opcodes +//DONE: test for valid close codes +//TODO: test close frame with no close code and reason //TODO: test valid frame sequences //unhappy flow //DONE: test invalid UTF8 sequences +//DONE: test invalid UTF8 sequences in control/close frames //TODO: test invalid masks //DONE: test for invalid fields //DONE: test for invalid opcodes @@ -29,12 +32,9 @@ Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode) //DONE: test continuation frames for incomplete payload //TODO: besides spying on errors, we should also check if the frame and message signals are not emitted (or partially emitted) +//DONE: test close frame with payload length 1 (is either 0, if no close code, or at least 2, close code + optional reason) //TODO: test invalid frame sequences -/* -Control frames are only checked in qwebsocket_p! These checks should probably be moved to -/TODO: test invalid UTF8 sequences in control/close frames -*/ const quint8 FIN = 0x80; const quint8 RSV1 = 0x40; @@ -106,6 +106,7 @@ private Q_SLOTS: This test does not test sequences of frames, only single frames are tested */ void invalidControlFrame(); + void invalidCloseFrame(); /*! \brief Tests the DataProcess for the correct handling of incomplete size fields for large and big payloads. @@ -129,6 +130,8 @@ private Q_SLOTS: */ void invalidPayload(); + void invalidPayloadInCloseFrame(); + /*! Tests the DataProcessor for the correct handling of the minimum size representation requirement of RFC 6455 (see paragraph 5.2) */ @@ -137,9 +140,11 @@ private Q_SLOTS: void invalidHeader_data(); void incompleteSizeField_data(); void incompletePayload_data(); - void invalidPayload_data(); + void invalidPayload_data(bool isControlFrame = false); + void invalidPayloadInCloseFrame_data(); void minimumSizeRequirement_data(); void invalidControlFrame_data(); + void invalidCloseFrame_data(); void frameTooBig_data(); void nonCharacterCodes_data(); @@ -149,7 +154,7 @@ private Q_SLOTS: private: //helper function that constructs a new row of test data for invalid UTF8 sequences - void invalidUTF8(const char *dataTag, const char *utf8Sequence); + void invalidUTF8(const char *dataTag, const char *utf8Sequence, bool isCloseFrame); //helper function that constructs a new row of test data for invalid leading field values void invalidField(const char *dataTag, quint8 invalidFieldValue); //helper functions that construct a new row of test data for size fields that do not adhere to the minimum size requirement @@ -163,6 +168,7 @@ private: void nonCharacterSequence(const char *sequence); void doTest(); + void doCloseFrameTest(); QString opCodeToString(quint8 opCode); }; @@ -230,6 +236,24 @@ void tst_DataProcessor::goodControlFrames_data() { QTest::newRow(QString("Text frame with containing ASCII character '0x%1'").arg(QByteArray(1, char(i)).toHex().constData()).toStdString().data()) << QString(1, char(i)) << QWebSocketProtocol::CC_NORMAL; } + QTest::newRow("Close frame with close code NORMAL") << QString(1, 'a') << QWebSocketProtocol::CC_NORMAL; + QTest::newRow("Close frame with close code BAD OPERATION") << QString(1, 'a') << QWebSocketProtocol::CC_BAD_OPERATION; + QTest::newRow("Close frame with close code DATATYPE NOT SUPPORTED") << QString(1, 'a') << QWebSocketProtocol::CC_DATATYPE_NOT_SUPPORTED; + QTest::newRow("Close frame with close code GOING AWAY") << QString(1, 'a') << QWebSocketProtocol::CC_GOING_AWAY; + QTest::newRow("Close frame with close code MISSING EXTENSION") << QString(1, 'a') << QWebSocketProtocol::CC_MISSING_EXTENSION; + QTest::newRow("Close frame with close code POLICY VIOLATED") << QString(1, 'a') << QWebSocketProtocol::CC_POLICY_VIOLATED; + QTest::newRow("Close frame with close code PROTOCOL ERROR") << QString(1, 'a') << QWebSocketProtocol::CC_PROTOCOL_ERROR; + QTest::newRow("Close frame with close code TOO MUCH DATA") << QString(1, 'a') << QWebSocketProtocol::CC_TOO_MUCH_DATA; + QTest::newRow("Close frame with close code WRONG DATATYPE") << QString(1, 'a') << QWebSocketProtocol::CC_WRONG_DATATYPE; + QTest::newRow("Close frame with close code 3000") << QString(1, 'a') << QWebSocketProtocol::CloseCode(3000); + QTest::newRow("Close frame with close code 3999") << QString(1, 'a') << QWebSocketProtocol::CloseCode(3999); + QTest::newRow("Close frame with close code 4000") << QString(1, 'a') << QWebSocketProtocol::CloseCode(4000); + QTest::newRow("Close frame with close code 4999") << QString(1, 'a') << QWebSocketProtocol::CloseCode(4999); + + //Not allowed per RFC 6455 (see para 7.4.1) + //QTest::newRow("Close frame with close code ABNORMAL DISCONNECTION") << QString(1, 'a') << QWebSocketProtocol::CC_ABNORMAL_DISCONNECTION; + //QTest::newRow("Close frame with close code MISSING STATUS CODE") << QString(1, 'a') << QWebSocketProtocol::CC_MISSING_STATUS_CODE; + //QTest::newRow("Close frame with close code HANDSHAKE FAILED") << QString(1, 'a') << QWebSocketProtocol::CC_TLS_HANDSHAKE_FAILED; } void tst_DataProcessor::goodBinaryFrames() @@ -478,6 +502,11 @@ void tst_DataProcessor::invalidControlFrame() doTest(); } +void tst_DataProcessor::invalidCloseFrame() +{ + doCloseFrameTest(); +} + void tst_DataProcessor::minimumSizeRequirement() { doTest(); @@ -488,6 +517,42 @@ void tst_DataProcessor::invalidPayload() doTest(); } +void tst_DataProcessor::invalidPayloadInCloseFrame() +{ + QFETCH(quint8, firstByte); + QFETCH(quint8, secondByte); + QFETCH(QByteArray, payload); + QFETCH(bool, isContinuationFrame); + QFETCH(QWebSocketProtocol::CloseCode, expectedCloseCode); + + Q_UNUSED(isContinuationFrame) + + QByteArray data; + QBuffer buffer; + DataProcessor dataProcessor; + QSignalSpy spy(&dataProcessor, SIGNAL(closeReceived(QWebSocketProtocol::CloseCode,QString))); + QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString))); + QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray))); + QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool))); + QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool))); + + data.append(firstByte).append(secondByte); + data.append(payload); + buffer.setData(data); + buffer.open(QIODevice::ReadWrite); + dataProcessor.process(&buffer); + QCOMPARE(spy.count(), 1); + QCOMPARE(textMessageSpy.count(), 0); + QCOMPARE(binaryMessageSpy.count(), 0); + QCOMPARE(textFrameSpy.count(), 0); + QCOMPARE(binaryFrameSpy.count(), 0); + QVariantList arguments = spy.takeFirst(); + QCOMPARE(arguments.at(0).value<QWebSocketProtocol::CloseCode>(), expectedCloseCode); + buffer.close(); + spy.clear(); + data.clear(); +} + void tst_DataProcessor::incompletePayload() { doTest(); @@ -524,6 +589,35 @@ void tst_DataProcessor::doTest() buffer.open(QIODevice::ReadWrite); dataProcessor.process(&buffer); QCOMPARE(spy.count(), 1); +void tst_DataProcessor::doCloseFrameTest() +{ + QFETCH(quint8, firstByte); + QFETCH(quint8, secondByte); + QFETCH(QByteArray, payload); + QFETCH(bool, isContinuationFrame); + QFETCH(QWebSocketProtocol::CloseCode, expectedCloseCode); + + Q_UNUSED(isContinuationFrame) + + QByteArray data; + QBuffer buffer; + DataProcessor dataProcessor; + QSignalSpy spy(&dataProcessor, SIGNAL(closeReceived(QWebSocketProtocol::CloseCode,QString))); + QSignalSpy textMessageSpy(&dataProcessor, SIGNAL(textMessageReceived(QString))); + QSignalSpy binaryMessageSpy(&dataProcessor, SIGNAL(binaryMessageReceived(QByteArray))); + QSignalSpy textFrameSpy(&dataProcessor, SIGNAL(textFrameReceived(QString, bool))); + QSignalSpy binaryFrameSpy(&dataProcessor, SIGNAL(binaryFrameReceived(QByteArray,bool))); + + data.append(firstByte).append(secondByte); + data.append(payload); + buffer.setData(data); + buffer.open(QIODevice::ReadWrite); + dataProcessor.process(&buffer); + QCOMPARE(spy.count(), 1); + QCOMPARE(textMessageSpy.count(), 0); + QCOMPARE(binaryMessageSpy.count(), 0); + QCOMPARE(textFrameSpy.count(), 0); + QCOMPARE(binaryFrameSpy.count(), 0); QVariantList arguments = spy.takeFirst(); QCOMPARE(arguments.at(0).value<QWebSocketProtocol::CloseCode>(), expectedCloseCode); buffer.close(); @@ -676,9 +770,23 @@ void tst_DataProcessor::minimumSize64Bit(quint64 sizeInBytes) << QWebSocketProtocol::CC_PROTOCOL_ERROR; } -void tst_DataProcessor::invalidUTF8(const char *dataTag, const char *utf8Sequence) +void tst_DataProcessor::invalidUTF8(const char *dataTag, const char *utf8Sequence, bool isCloseFrame) { QByteArray payload = QByteArray::fromHex(utf8Sequence); + + if (isCloseFrame) + { + quint16 closeCode = qToBigEndian<quint16>(QWebSocketProtocol::CC_NORMAL); + const char *wireRepresentation = static_cast<const char *>(static_cast<const void *>(&closeCode)); + QTest::newRow(QString("Close frame with invalid UTF8-sequence: %1").arg(dataTag).toStdString().data()) + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) + << quint8(payload.length() + 2) + << QByteArray(wireRepresentation, 2).append(payload) + << false + << QWebSocketProtocol::CC_WRONG_DATATYPE; + } + else + { QTest::newRow(QString("Text frame with invalid UTF8-sequence: %1").arg(dataTag).toStdString().data()) << quint8(FIN | QWebSocketProtocol::OC_TEXT) << quint8(payload.length()) @@ -693,6 +801,7 @@ void tst_DataProcessor::invalidUTF8(const char *dataTag, const char *utf8Sequenc << true << QWebSocketProtocol::CC_WRONG_DATATYPE; } +} void tst_DataProcessor::invalidField(const char *dataTag, quint8 invalidFieldValue) { @@ -717,11 +826,6 @@ void tst_DataProcessor::incompleteFrame(quint8 controlCode, quint64 indicatedSiz QString frameType = opCodeToString(controlCode); QByteArray firstFrame; -// if (controlCode == QWebSocketProtocol::OC_CONTINUE) -// { -// firstFrame.append(quint8(QWebSocketProtocol::OC_TEXT)).append(char(0)).append(QByteArray()); -// } - if (indicatedSize < 126) { QTest::newRow(frameType.append(QString(" frame with payload size %1, but only %2 bytes of data").arg(indicatedSize).arg(actualPayloadSize)).toStdString().data()) @@ -830,11 +934,14 @@ void tst_DataProcessor::invalidHeader_data() invalidField("Invalid OpCode D", QWebSocketProtocol::OC_RESERVED_D); invalidField("Invalid OpCode E", QWebSocketProtocol::OC_RESERVED_E); invalidField("Invalid OpCode F", QWebSocketProtocol::OC_RESERVED_F); +} - //invalidField("Continuation Frame without previous data frame", QWebSocketProtocol::OC_CONTINUE); +void tst_DataProcessor::invalidPayloadInCloseFrame_data() +{ + invalidPayload_data(true); } -void tst_DataProcessor::invalidPayload_data() +void tst_DataProcessor::invalidPayload_data(bool isControlFrame) { QTest::addColumn<quint8>("firstByte"); QTest::addColumn<quint8>("secondByte"); @@ -843,108 +950,108 @@ void tst_DataProcessor::invalidPayload_data() QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode"); //6.3: invalid UTF-8 sequence - invalidUTF8("case 6.3.1", "cebae1bdb9cf83cebcceb5eda080656469746564"); + invalidUTF8("case 6.3.1", "cebae1bdb9cf83cebcceb5eda080656469746564", isControlFrame); //6.4.: fail fast tests; invalid UTF-8 in middle of string - invalidUTF8("case 6.4.1", "cebae1bdb9cf83cebcceb5f4908080656469746564"); - invalidUTF8("case 6.4.4", "cebae1bdb9cf83cebcceb5eda080656469746564"); + invalidUTF8("case 6.4.1", "cebae1bdb9cf83cebcceb5f4908080656469746564", isControlFrame); + invalidUTF8("case 6.4.4", "cebae1bdb9cf83cebcceb5eda080656469746564", isControlFrame); //6.6: All prefixes of a valid UTF-8 string that contains multi-byte code points - invalidUTF8("case 6.6.1", "ce"); - invalidUTF8("case 6.6.3", "cebae1"); - invalidUTF8("case 6.6.4", "cebae1bd"); - invalidUTF8("case 6.6.6", "cebae1bdb9cf"); - invalidUTF8("case 6.6.8", "cebae1bdb9cf83ce"); - invalidUTF8("case 6.6.10", "cebae1bdb9cf83cebcce"); + invalidUTF8("case 6.6.1", "ce", isControlFrame); + invalidUTF8("case 6.6.3", "cebae1", isControlFrame); + invalidUTF8("case 6.6.4", "cebae1bd", isControlFrame); + invalidUTF8("case 6.6.6", "cebae1bdb9cf", isControlFrame); + invalidUTF8("case 6.6.8", "cebae1bdb9cf83ce", isControlFrame); + invalidUTF8("case 6.6.10", "cebae1bdb9cf83cebcce", isControlFrame); //6.8: First possible sequence length 5/6 (invalid codepoints) - invalidUTF8("case 6.8.1", "f888808080"); - invalidUTF8("case 6.8.2", "fc8480808080"); + invalidUTF8("case 6.8.1", "f888808080", isControlFrame); + invalidUTF8("case 6.8.2", "fc8480808080", isControlFrame); //6.10: Last possible sequence length 4/5/6 (invalid codepoints) - invalidUTF8("case 6.10.1", "f7bfbfbf"); - invalidUTF8("case 6.10.2", "fbbfbfbfbf"); - invalidUTF8("case 6.10.3", "fdbfbfbfbfbf"); + invalidUTF8("case 6.10.1", "f7bfbfbf", isControlFrame); + invalidUTF8("case 6.10.2", "fbbfbfbfbf", isControlFrame); + invalidUTF8("case 6.10.3", "fdbfbfbfbfbf", isControlFrame); //5.11: boundary conditions - invalidUTF8("case 6.11.5", "f4908080"); + invalidUTF8("case 6.11.5", "f4908080", isControlFrame); //6.12: unexpected continuation bytes - invalidUTF8("case 6.12.1", "80"); - invalidUTF8("case 6.12.2", "bf"); - invalidUTF8("case 6.12.3", "80bf"); - invalidUTF8("case 6.12.4", "80bf80"); - invalidUTF8("case 6.12.5", "80bf80bf"); - invalidUTF8("case 6.12.6", "80bf80bf80"); - invalidUTF8("case 6.12.7", "80bf80bf80bf"); - invalidUTF8("case 6.12.8", "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe"); + invalidUTF8("case 6.12.1", "80", isControlFrame); + invalidUTF8("case 6.12.2", "bf", isControlFrame); + invalidUTF8("case 6.12.3", "80bf", isControlFrame); + invalidUTF8("case 6.12.4", "80bf80", isControlFrame); + invalidUTF8("case 6.12.5", "80bf80bf", isControlFrame); + invalidUTF8("case 6.12.6", "80bf80bf80", isControlFrame); + invalidUTF8("case 6.12.7", "80bf80bf80bf", isControlFrame); + invalidUTF8("case 6.12.8", "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe", isControlFrame); //6.13: lonely start characters - invalidUTF8("case 6.13.1", "c020c120c220c320c420c520c620c720c820c920ca20cb20cc20cd20ce20cf20d020d120d220d320d420d520d620d720d820d920da20db20dc20dd20de20"); - invalidUTF8("case 6.13.2", "e020e120e220e320e420e520e620e720e820e920ea20eb20ec20ed20ee20"); - invalidUTF8("case 6.13.3", "f020f120f220f320f420f520f620"); - invalidUTF8("case 6.13.4", "f820f920fa20"); - invalidUTF8("case 6.13.5", "fc20"); + invalidUTF8("case 6.13.1", "c020c120c220c320c420c520c620c720c820c920ca20cb20cc20cd20ce20cf20d020d120d220d320d420d520d620d720d820d920da20db20dc20dd20de20", isControlFrame); + invalidUTF8("case 6.13.2", "e020e120e220e320e420e520e620e720e820e920ea20eb20ec20ed20ee20", isControlFrame); + invalidUTF8("case 6.13.3", "f020f120f220f320f420f520f620", isControlFrame); + invalidUTF8("case 6.13.4", "f820f920fa20", isControlFrame); + invalidUTF8("case 6.13.5", "fc20", isControlFrame); //6.14: sequences with last continuation byte missing - invalidUTF8("case 6.14.1", "c0"); - invalidUTF8("case 6.14.2", "e080"); - invalidUTF8("case 6.14.3", "f08080"); - invalidUTF8("case 6.14.4", "f8808080"); - invalidUTF8("case 6.14.5", "fc80808080"); - invalidUTF8("case 6.14.6", "df"); - invalidUTF8("case 6.14.7", "efbf"); - invalidUTF8("case 6.14.8", "f7bfbf"); - invalidUTF8("case 6.14.9", "fbbfbfbf"); - invalidUTF8("case 6.14.10", "fdbfbfbfbf"); + invalidUTF8("case 6.14.1", "c0", isControlFrame); + invalidUTF8("case 6.14.2", "e080", isControlFrame); + invalidUTF8("case 6.14.3", "f08080", isControlFrame); + invalidUTF8("case 6.14.4", "f8808080", isControlFrame); + invalidUTF8("case 6.14.5", "fc80808080", isControlFrame); + invalidUTF8("case 6.14.6", "df", isControlFrame); + invalidUTF8("case 6.14.7", "efbf", isControlFrame); + invalidUTF8("case 6.14.8", "f7bfbf", isControlFrame); + invalidUTF8("case 6.14.9", "fbbfbfbf", isControlFrame); + invalidUTF8("case 6.14.10", "fdbfbfbfbf", isControlFrame); //6.15: concatenation of incomplete sequences - invalidUTF8("case 6.15.1", "c0e080f08080f8808080fc80808080dfefbff7bfbffbbfbfbffdbfbfbfbf"); + invalidUTF8("case 6.15.1", "c0e080f08080f8808080fc80808080dfefbff7bfbffbbfbfbffdbfbfbfbf", isControlFrame); //6.16: impossible bytes - invalidUTF8("case 6.16.1", "fe"); - invalidUTF8("case 6.16.2", "ff"); - invalidUTF8("case 6.16.3", "fefeffff"); + invalidUTF8("case 6.16.1", "fe", isControlFrame); + invalidUTF8("case 6.16.2", "ff", isControlFrame); + invalidUTF8("case 6.16.3", "fefeffff", isControlFrame); //6.17: overlong ASCII characters - invalidUTF8("case 6.17.1", "c0af"); - invalidUTF8("case 6.17.2", "e080af"); - invalidUTF8("case 6.17.3", "f08080af"); - invalidUTF8("case 6.17.4", "f8808080af"); - invalidUTF8("case 6.17.5", "fc80808080af"); + invalidUTF8("case 6.17.1", "c0af", isControlFrame); + invalidUTF8("case 6.17.2", "e080af", isControlFrame); + invalidUTF8("case 6.17.3", "f08080af", isControlFrame); + invalidUTF8("case 6.17.4", "f8808080af", isControlFrame); + invalidUTF8("case 6.17.5", "fc80808080af", isControlFrame); //6.18: maximum overlong sequences - invalidUTF8("case 6.18.1", "c1bf"); - invalidUTF8("case 6.18.2", "e09fbf"); - invalidUTF8("case 6.18.3", "f08fbfbf"); - invalidUTF8("case 6.18.4", "f887bfbfbf"); - invalidUTF8("case 6.18.5", "fc83bfbfbfbf"); + invalidUTF8("case 6.18.1", "c1bf", isControlFrame); + invalidUTF8("case 6.18.2", "e09fbf", isControlFrame); + invalidUTF8("case 6.18.3", "f08fbfbf", isControlFrame); + invalidUTF8("case 6.18.4", "f887bfbfbf", isControlFrame); + invalidUTF8("case 6.18.5", "fc83bfbfbfbf", isControlFrame); //6.19: overlong presentation of the NUL character - invalidUTF8("case 6.19.1", "c080"); - invalidUTF8("case 6.19.2", "e08080"); - invalidUTF8("case 6.19.3", "f0808080"); - invalidUTF8("case 6.19.4", "f880808080"); - invalidUTF8("case 6.19.5", "fc8080808080"); + invalidUTF8("case 6.19.1", "c080", isControlFrame); + invalidUTF8("case 6.19.2", "e08080", isControlFrame); + invalidUTF8("case 6.19.3", "f0808080", isControlFrame); + invalidUTF8("case 6.19.4", "f880808080", isControlFrame); + invalidUTF8("case 6.19.5", "fc8080808080", isControlFrame); //6.20: Single UTF-16 surrogates - invalidUTF8("case 6.20.1", "eda080"); - invalidUTF8("case 6.20.2", "edadbf"); - invalidUTF8("case 6.20.3", "edae80"); - invalidUTF8("case 6.20.4", "edafbf"); - invalidUTF8("case 6.20.5", "edb080"); - invalidUTF8("case 6.20.6", "edbe80"); - invalidUTF8("case 6.20.7", "edbfbf"); + invalidUTF8("case 6.20.1", "eda080", isControlFrame); + invalidUTF8("case 6.20.2", "edadbf", isControlFrame); + invalidUTF8("case 6.20.3", "edae80", isControlFrame); + invalidUTF8("case 6.20.4", "edafbf", isControlFrame); + invalidUTF8("case 6.20.5", "edb080", isControlFrame); + invalidUTF8("case 6.20.6", "edbe80", isControlFrame); + invalidUTF8("case 6.20.7", "edbfbf", isControlFrame); //6.21: Paired UTF-16 surrogates - invalidUTF8("case 6.21.1", "eda080edb080"); - invalidUTF8("case 6.21.2", "eda080edbfbf"); - invalidUTF8("case 6.21.3", "edadbfedb080"); - invalidUTF8("case 6.21.4", "edadbfedbfbf"); - invalidUTF8("case 6.21.5", "edae80edb080"); - invalidUTF8("case 6.21.6", "edae80edbfbf"); - invalidUTF8("case 6.21.7", "edafbfedb080"); - invalidUTF8("case 6.21.8", "edafbfedbfbf"); + invalidUTF8("case 6.21.1", "eda080edb080", isControlFrame); + invalidUTF8("case 6.21.2", "eda080edbfbf", isControlFrame); + invalidUTF8("case 6.21.3", "edadbfedb080", isControlFrame); + invalidUTF8("case 6.21.4", "edadbfedbfbf", isControlFrame); + invalidUTF8("case 6.21.5", "edae80edb080", isControlFrame); + invalidUTF8("case 6.21.6", "edae80edbfbf", isControlFrame); + invalidUTF8("case 6.21.7", "edafbfedb080", isControlFrame); + invalidUTF8("case 6.21.8", "edafbfedbfbf", isControlFrame); } void tst_DataProcessor::minimumSizeRequirement_data() @@ -982,6 +1089,7 @@ void tst_DataProcessor::invalidControlFrame_data() QTest::addColumn<bool>("isContinuationFrame"); QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode"); + QTest::newRow("Close control frame with payload size 126") << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << quint8(126) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; QTest::newRow("Ping control frame with payload size 126") @@ -997,6 +1105,96 @@ void tst_DataProcessor::invalidControlFrame_data() << quint8(QWebSocketProtocol::OC_PONG) << quint8(32) << QByteArray() << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; } +void tst_DataProcessor::invalidCloseFrame_data() +{ + QTest::addColumn<quint8>("firstByte"); + QTest::addColumn<quint8>("secondByte"); + QTest::addColumn<QByteArray>("payload"); + QTest::addColumn<bool>("isContinuationFrame"); + QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode"); + + QTest::newRow("Close control frame with payload size 1") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << quint8(1) << QByteArray(1, 'a') << false << QWebSocketProtocol::CC_PROTOCOL_ERROR; + QTest::newRow("Close control frame close code ABNORMAL DISCONNECTION") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CC_ABNORMAL_DISCONNECTION; + QTest::newRow("Close control frame close code MISSING STATUS CODE") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CC_MISSING_STATUS_CODE; + QTest::newRow("Close control frame close code 1004") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CC_RESERVED_1004; + QTest::newRow("Close control frame close code TLS HANDSHAKE FAILED") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CC_TLS_HANDSHAKE_FAILED; + QTest::newRow("Close control frame close code 0") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(0); + QTest::newRow("Close control frame close code 999") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(999); + QTest::newRow("Close control frame close code 1012") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(1012); + QTest::newRow("Close control frame close code 1013") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(1013); + QTest::newRow("Close control frame close code 1014") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(1014); + QTest::newRow("Close control frame close code 1014") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(1016); + QTest::newRow("Close control frame close code 1100") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(1100); + QTest::newRow("Close control frame close code 2000") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(2000); + QTest::newRow("Close control frame close code 2999") + << quint8(FIN | QWebSocketProtocol::OC_CLOSE) << + quint8(2) << + QByteArray() << + false << + QWebSocketProtocol::CloseCode(2999); +} + void tst_DataProcessor::incompleteSizeField_data() { QTest::addColumn<quint8>("firstByte"); |