Skip to content

Commit 27684a4

Browse files
committed
Restore _pinfo.masked to a boolean state (0 or 1) to keep backward compatibility.
1 parent d015042 commit 27684a4

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

src/AsyncWebSocket.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) {
515515
_pinfo.index = 0;
516516
_pinfo.final = (fdata[0] & 0x80) != 0;
517517
_pinfo.opcode = fdata[0] & 0x0F;
518+
// _pinfo.masked is a boolean: 1 if the frame is masked, 0 otherwise. Do not use as a counter.
518519
_pinfo.masked = ((fdata[1] & 0x80) != 0) ? 1 : 0;
519520
_pinfo.len = fdata[1] & 0x7F;
520521

@@ -539,17 +540,26 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) {
539540
}
540541

541542
if (_pinfo.masked > 0 && _pinfo.masked < 5) {
542-
// Handle fragmented mask data - Safari may split the 4-byte mask across multiple packets
543-
while (_pinfo.masked < 5) {
544-
if (plen == 0) {
545-
//wait for more data
546-
_pstate = 1;
547-
return;
543+
// Handle Safari edge case: close frame with plen 0, mask bit set, but no mask bytes
544+
if (_pinfo.len == 0 && plen == 0) {
545+
// Malformed frame (Safari bug): treat as unmasked for compatibility
546+
_pinfo.masked = 0;
547+
} else {
548+
// Handle fragmented mask data - Safari may split the 4-byte mask across multiple packets
549+
int mask_bytes_read = _pinfo.masked - 1;
550+
while (mask_bytes_read < 4) {
551+
if (plen == 0) {
552+
// wait for more data
553+
_pinfo.masked = mask_bytes_read + 1;
554+
_pstate = 1;
555+
return;
556+
}
557+
_pinfo.mask[mask_bytes_read] = data[0];
558+
data += 1;
559+
plen -= 1;
560+
mask_bytes_read++;
548561
}
549-
_pinfo.mask[_pinfo.masked - 1] = data[0];
550-
data += 1;
551-
plen -= 1;
552-
_pinfo.masked++;
562+
_pinfo.masked = 1; // restore boolean semantics: mask fully read
553563
}
554564
}
555565

0 commit comments

Comments
 (0)