mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Limit maximum L2CAP frame size and move read buffer to instance variable.
PiperOrigin-RevId: 946782423
This commit is contained in:
committed by
Copybara-Service
parent
e9186fb176
commit
2f3e7beb78
@@ -24,6 +24,7 @@
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCMConnection.h"
|
||||
|
||||
enum { kL2CAPPacketLength = 4 };
|
||||
static const NSUInteger kGNCBLEL2CAPMaxFrameLength = 5 * 1024 * 1024; // 5 MB
|
||||
static const CGFloat kRequestDataConnectionDelayInSeconds = 0.0;
|
||||
static const UInt8 kRequestDataConnectionTimeoutInSeconds = 5;
|
||||
|
||||
@@ -266,6 +267,20 @@ static NSData *PrefixLengthData(NSData *data) {
|
||||
}
|
||||
_expectedDataLength = CFSwapInt32BigToHost(
|
||||
*(int *)([[data subdataWithRange:NSMakeRange(0, kL2CAPPacketLength)] bytes]));
|
||||
if (_expectedDataLength == 0 || _expectedDataLength > kGNCBLEL2CAPMaxFrameLength) {
|
||||
GNCLoggerError(@"[NEARBY] Rejecting L2CAP frame: declared length %lu out of range "
|
||||
@"(max %lu); closing.",
|
||||
(unsigned long)_expectedDataLength,
|
||||
(unsigned long)kGNCBLEL2CAPMaxFrameLength);
|
||||
_expectedDataLength = 0;
|
||||
[_stream close];
|
||||
if (_connectionHandlers.disconnectedHandler) {
|
||||
dispatch_async(_callbackQueue, ^{
|
||||
_connectionHandlers.disconnectedHandler();
|
||||
});
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
NSUInteger realDataLength = data.length - kL2CAPPacketLength;
|
||||
if (realDataLength < _expectedDataLength) {
|
||||
|
||||
@@ -74,6 +74,9 @@ enum { READ_BUFFER_SIZE = 409600 };
|
||||
|
||||
/// Whether the stream is closed.
|
||||
BOOL _closed;
|
||||
|
||||
/// Buffer for reading data from the input stream.
|
||||
uint8_t _readBuffer[READ_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
#pragma mark Public
|
||||
@@ -319,12 +322,11 @@ enum { READ_BUFFER_SIZE = 409600 };
|
||||
/// Receives data from device and invokes |_receivedDataBlock|.
|
||||
- (void)receiveStreamData {
|
||||
dispatch_assert_queue_debug(_streamQueue);
|
||||
uint8_t readBuffer[READ_BUFFER_SIZE];
|
||||
NSInteger bytesRead = [self.inputStream read:readBuffer maxLength:READ_BUFFER_SIZE];
|
||||
NSInteger bytesRead = [self.inputStream read:_readBuffer maxLength:READ_BUFFER_SIZE];
|
||||
|
||||
if (bytesRead > 0) {
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
[data appendBytes:readBuffer length:(NSUInteger)bytesRead];
|
||||
[data appendBytes:_readBuffer length:(NSUInteger)bytesRead];
|
||||
|
||||
if (_verboseLoggingEnabled) {
|
||||
GNCLoggerDebug(@"[NEARBY] Stream data from device of length %@", @(data.length));
|
||||
|
||||
@@ -140,6 +140,32 @@ static const NSTimeInterval kTestTimeout = 1.0;
|
||||
XCTAssertNil(realData);
|
||||
}
|
||||
|
||||
- (void)testExtractRealDataFromData_oversizedData {
|
||||
_connection = [self createConnectionWithIncoming:YES];
|
||||
|
||||
XCTestExpectation *disconnectionExpectation =
|
||||
[self expectationWithDescription:@"disconnection handler"];
|
||||
_connection.connectionHandlers = [GNCMConnectionHandlers
|
||||
payloadHandler:^(NSData *data) {
|
||||
XCTFail(@"Unexpected payload");
|
||||
}
|
||||
disconnectedHandler:^{
|
||||
[disconnectionExpectation fulfill];
|
||||
}];
|
||||
|
||||
// 6 MB frame length
|
||||
uint32_t oversizedLength = 6 * 1024 * 1024;
|
||||
uint32_t lengthBigEndian = CFSwapInt32HostToBig(oversizedLength);
|
||||
NSMutableData *prefixData = [NSMutableData dataWithCapacity:sizeof(uint32_t)];
|
||||
[prefixData appendBytes:&lengthBigEndian length:sizeof(uint32_t)];
|
||||
|
||||
NSData *realData = [_connection extractRealDataFromData:prefixData];
|
||||
XCTAssertNil(realData);
|
||||
XCTAssertEqual(_connection.expectedDataLength, 0);
|
||||
|
||||
[self waitForExpectationsWithTimeout:kTestTimeout handler:nil];
|
||||
}
|
||||
|
||||
- (void)testExtractRealDataFromData_moreThanExpectedData {
|
||||
_connection = [self createConnectionWithIncoming:YES];
|
||||
NSData *testData = [self createDataWithLength:10];
|
||||
|
||||
Reference in New Issue
Block a user