Skip to content

Commit 63a52d8

Browse files
Fix WebSocket frame length byte order for 16-bit length case
It must be interpreted as big-endian (network byte order).
1 parent ec371c0 commit 63a52d8

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

FlyingFox/Sources/WebSocket/WSFrameEncoder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ struct WSFrameEncoder {
138138
case 0...125:
139139
return try await (Int(length0), hasMask ? decodeMask(from: bytes) : nil)
140140
case 126:
141-
let length = try await UInt16(bytes.take()) |
142-
UInt16(bytes.take()) << 8
141+
let length = try await UInt16(bytes.take()) << 8 |
142+
UInt16(bytes.take())
143143
return try await (Int(length), hasMask ? decodeMask(from: bytes) : nil)
144144
default:
145145
var length = try await UInt64(bytes.take())

FlyingFox/Tests/WebSocket/WSFrameEncoderTests.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ struct WSFrameEncoderTests {
238238
try await WSFrameEncoder.decodeLength(0x7D) == 125
239239
)
240240
#expect(
241-
try await WSFrameEncoder.decodeLength(0x7E, 0x00, 0xFF) == 0xFF00
241+
try await WSFrameEncoder.decodeLength(0x7E, 0x00, 0xFF) == 0x00FF
242242
)
243243
#expect(
244-
try await WSFrameEncoder.decodeLength(0x7E, 0xFF, 0x00) == 0x00FF
244+
try await WSFrameEncoder.decodeLength(0x7E, 0xFF, 0x00) == 0xFF00
245245
)
246246
#expect(
247247
try await WSFrameEncoder.decodeLength(0x7E, 0xFF, 0xFF) == 0xFFFF
@@ -371,6 +371,15 @@ struct WSFrameEncoderTests {
371371
frame = WSFrame.close(mask: .mock)
372372
try await socket.writeFrame(frame)
373373
}
374+
375+
@Test
376+
func roundtripLength() async throws {
377+
for length in 0..<256 {
378+
let encoded = WSFrameEncoder.encodeLength(length, hasMask: false)
379+
let decoded = try await WSFrameEncoder.decodeLengthMask(encoded)
380+
#expect(length == decoded.length)
381+
}
382+
}
374383
}
375384

376385
private extension WSFrameEncoder {

FlyingFox/XCTests/WebSocket/WSFrameEncoderTests.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,11 @@ final class WSFrameEncoderTests: XCTestCase {
209209
125
210210
)
211211
await AsyncAssertEqual(
212-
try await WSFrameEncoder.decodeLength(0x7E, 0x00, 0xFF),
212+
try await WSFrameEncoder.decodeLength(0x7E, 0xFF, 0x00),
213213
0xFF00
214214
)
215215
await AsyncAssertEqual(
216-
try await WSFrameEncoder.decodeLength(0x7E, 0xFF, 0x00),
216+
try await WSFrameEncoder.decodeLength(0x7E, 0x00, 0xFF),
217217
0x00FF
218218
)
219219
await AsyncAssertEqual(
@@ -346,6 +346,14 @@ final class WSFrameEncoderTests: XCTestCase {
346346
frame = WSFrame.close(mask: .mock)
347347
try await socket.writeFrame(frame)
348348
}
349+
350+
func testRoundtripLength() async throws {
351+
for length in 0..<256 {
352+
let encoded = WSFrameEncoder.encodeLength(length, hasMask: false)
353+
let decoded = try await WSFrameEncoder.decodeLengthMask(encoded)
354+
XCTAssertEqual(length, decoded.length)
355+
}
356+
}
349357
}
350358

351359
private extension WSFrameEncoder {

0 commit comments

Comments
 (0)