Bug 675983 - Websockets - fail connection on 1st fragment with a continuation op code
authorPatrick McManus <mcmanus@ducksong.com>
Mon, 08 Aug 2011 23:41:22 -0700
changeset 74079 e47729ef75523159ed73b4c2e960229e393ed02d
parent 74054 f1a3fea305ffb0bbc9664ea5329a76988a5f5cd9
child 74080 51c305f11c13320c04d64afcbb30b77b76d2c7bb
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs675983
milestone8.0a1
Bug 675983 - Websockets - fail connection on 1st fragment with a continuation op code
netwerk/protocol/websocket/WebSocketChannel.cpp
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -568,17 +568,17 @@ WebSocketChannel::WebSocketChannel() :
   mTCPClosed(0),
   mOpenBlocked(0),
   mOpenRunning(0),
   mChannelWasOpened(0),
   mMaxMessageSize(16000000),
   mStopOnClose(NS_OK),
   mServerCloseCode(CLOSE_ABNORMAL),
   mScriptCloseCode(0),
-  mFragmentOpcode(0),
+  mFragmentOpcode(kContinuation),
   mFragmentAccumulator(0),
   mBuffered(0),
   mBufferSize(16384),
   mCurrentOut(nsnull),
   mCurrentOutSent(0),
   mCompressor(nsnull),
   mDynamicOutputSize(0),
   mDynamicOutput(nsnull)
@@ -858,24 +858,32 @@ WebSocketChannel::ProcessInput(PRUint8 *
     }
 
     if (!finBit || opcode == kContinuation) {
       // This is part of a fragment response
 
       // Only the first frame has a non zero op code: Make sure we don't see a
       // first frame while some old fragments are open
       if ((mFragmentAccumulator != 0) && (opcode != kContinuation)) {
-        LOG(("WebSocketHeandler:: nested fragments\n"));
+        LOG(("WebSocketChannel:: nested fragments\n"));
         AbortSession(NS_ERROR_ILLEGAL_VALUE);
         return NS_ERROR_ILLEGAL_VALUE;
       }
 
       LOG(("WebSocketChannel:: Accumulating Fragment %lld\n", payloadLength));
 
       if (opcode == kContinuation) {
+
+        // Make sure this continuation fragment isn't the first fragment
+        if (mFragmentOpcode == kContinuation) {
+          LOG(("WebSocketHeandler:: continuation code in first fragment\n"));
+          AbortSession(NS_ERROR_ILLEGAL_VALUE);
+          return NS_ERROR_ILLEGAL_VALUE;
+        }
+
         // For frag > 1 move the data body back on top of the headers
         // so we have contiguous stream of data
         NS_ABORT_IF_FALSE(mFramePtr + framingLength == payload,
                           "payload offset from frameptr wrong");
         ::memmove(mFramePtr, payload, avail);
         payload = mFramePtr;
         if (mBuffered)
           mBuffered -= framingLength;
@@ -885,16 +893,18 @@ WebSocketChannel::ProcessInput(PRUint8 *
 
       if (finBit) {
         LOG(("WebSocketChannel:: Finalizing Fragment\n"));
         payload -= mFragmentAccumulator;
         payloadLength += mFragmentAccumulator;
         avail += mFragmentAccumulator;
         mFragmentAccumulator = 0;
         opcode = mFragmentOpcode;
+        // reset to detect if next message illegally starts with continuation
+        mFragmentOpcode = kContinuation;
       } else {
         opcode = kContinuation;
         mFragmentAccumulator += payloadLength;
       }
     } else if (mFragmentAccumulator != 0 && !(opcode & kControlFrameMask)) {
       // This frame is not part of a fragment sequence but we
       // have an open fragment.. it must be a control code or else
       // we have a problem