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 74077 e47729ef75523159ed73b4c2e960229e393ed02d
parent 74052 f1a3fea305ffb0bbc9664ea5329a76988a5f5cd9
child 74078 51c305f11c13320c04d64afcbb30b77b76d2c7bb
push id20948
push usereakhgari@mozilla.com
push dateTue, 09 Aug 2011 18:44:27 +0000
treeherdermozilla-central@db5a68bc2a0f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs675983
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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