summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKurt Pattyn <pattyn.kurt@gmail.com>2013-09-01 13:53:26 +0200
committerKurt Pattyn <pattyn.kurt@gmail.com>2013-09-01 13:53:26 +0200
commit60357fb995f543202b0dfe09eece6120a62427f4 (patch)
treeda9d259ebb22044623d7ea9320e95ebba2aac9bc /tests
parent63231ee164859fbc468143da07fafc867a2ee301 (diff)
downloadqtwebsockets-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.cpp370
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");