1717#include < json/value.h>
1818#include < json/writer.h>
1919#include < thread>
20+ #include < limits>
2021
2122using namespace drogon ;
2223
@@ -268,14 +269,14 @@ bool WebSocketMessageParser::parse(trantor::MsgBuffer *buffer)
268269{
269270 // According to the rfc6455
270271 gotAll_ = false ;
271- if (buffer->readableBytes () >= 2 )
272+ while (buffer->readableBytes () >= 2 )
272273 {
273274 unsigned char opcode = (*buffer)[0 ] & 0x0f ;
274275 bool isControlFrame = false ;
275276 switch (opcode)
276277 {
277278 case 0 :
278- // continuation frame
279+ LOG_TRACE << " continuation frame" ;
279280 break ;
280281 case 1 :
281282 type_ = WebSocketMessageType::Text;
@@ -327,8 +328,13 @@ bool WebSocketMessageParser::parse(trantor::MsgBuffer *buffer)
327328 {
328329 indexFirstMask = 10 ;
329330 }
330- if (indexFirstMask > 2 && buffer-> readableBytes () >= indexFirstMask )
331+ if (indexFirstMask > 2 )
331332 {
333+ if (buffer->readableBytes () < indexFirstMask)
334+ {
335+ // Not enough data yet, wait for more.
336+ return true ;
337+ }
332338 if (isControlFrame)
333339 {
334340 // rfc6455-5.5
@@ -344,14 +350,17 @@ bool WebSocketMessageParser::parse(trantor::MsgBuffer *buffer)
344350 }
345351 else if (indexFirstMask == 10 )
346352 {
347- length = (unsigned char )(*buffer)[2 ];
348- length = (length << 8 ) + (unsigned char )(*buffer)[3 ];
349- length = (length << 8 ) + (unsigned char )(*buffer)[4 ];
350- length = (length << 8 ) + (unsigned char )(*buffer)[5 ];
351- length = (length << 8 ) + (unsigned char )(*buffer)[6 ];
352- length = (length << 8 ) + (unsigned char )(*buffer)[7 ];
353- length = (length << 8 ) + (unsigned char )(*buffer)[8 ];
354- length = (length << 8 ) + (unsigned char )(*buffer)[9 ];
353+ length = 0 ;
354+ for (int i = 2 ; i <= 9 ; ++i)
355+ {
356+ if (length > ((std::numeric_limits<size_t >::max)() >> 8 ))
357+ {
358+ LOG_ERROR
359+ << " Payload length too large to handle safely" ;
360+ return false ;
361+ }
362+ length = (length << 8 ) + (unsigned char )(*buffer)[i];
363+ }
355364 }
356365 else
357366 {
@@ -380,9 +389,16 @@ bool WebSocketMessageParser::parse(trantor::MsgBuffer *buffer)
380389 {
381390 message_[oldLen + i] = (rawData[i] ^ masks[i % 4 ]);
382391 }
392+ buffer->retrieve (indexFirstMask + 4 + length);
383393 if (isFin)
394+ {
384395 gotAll_ = true ;
385- buffer->retrieve (indexFirstMask + 4 + length);
396+ return true ;
397+ }
398+ }
399+ else
400+ {
401+ // Not enough data yet, wait for more.
386402 return true ;
387403 }
388404 }
@@ -392,9 +408,16 @@ bool WebSocketMessageParser::parse(trantor::MsgBuffer *buffer)
392408 {
393409 auto rawData = buffer->peek () + indexFirstMask;
394410 message_.append (rawData, length);
411+ buffer->retrieve (indexFirstMask + length);
395412 if (isFin)
413+ {
396414 gotAll_ = true ;
397- buffer->retrieve (indexFirstMask + length);
415+ return true ;
416+ }
417+ }
418+ else
419+ {
420+ // Not enough data yet, wait for more.
398421 return true ;
399422 }
400423 }
0 commit comments