Skip to content

Commit

Permalink
Add check for valid range on buffers
Browse files Browse the repository at this point in the history
Protects crashes on reading and writing
of buffer if range is accessed beyond
buffer size.
  • Loading branch information
Nadohs committed Mar 3, 2021
1 parent e70a147 commit 1573951
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 3 deletions.
12 changes: 9 additions & 3 deletions Cassette/CASQueueFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -504,15 +504,21 @@ - (NSUInteger)usedBytes {
* Stores a 32-bit integer @c value in the @c buffer at the given @c offset.
*/
void writeInt(NSMutableData *buffer, NSUInteger offset, uint32_t value) {
[buffer replaceBytesInRange:NSMakeRange(offset, 4) withBytes:&value];
BOOL hasValidRange = buffer.length >= offset + 4;
if (hasValidRange) {
[buffer replaceBytesInRange:NSMakeRange(offset, 4) withBytes:&value];
}
}

/**
* Reads a 32-bit integer value from the @c buffer at @c offset.
*/
NSUInteger readUnsignedInt(NSData *buffer, NSUInteger offset) {
uint32_t value;
[buffer getBytes:&value range:NSMakeRange(offset, 4)];
uint32_t value = 0;
BOOL hasValidRange = buffer.length >= offset + 4;
if (hasValidRange) {
[buffer getBytes:&value range:NSMakeRange(offset, 4)];
}
return value;
}

Expand Down
27 changes: 27 additions & 0 deletions CassetteTests/CASQueueFileTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

#import "CASQueueFile.h"

@interface CASQueueFile (ExposeMethods)
void writeInt(NSMutableData *buffer, NSUInteger offset, uint32_t value);
NSUInteger readUnsignedInt(NSData *buffer, NSUInteger offset);
@end

@interface CASQueueFileTests : XCTestCase

@property (nonatomic, nullable, strong) CASQueueFile *queueFile;
Expand Down Expand Up @@ -221,4 +226,26 @@ - (void)testRingReadingElementsMaintainsCorrectness {
return dataArray;
}

- (void)testReadInt {
NSUInteger value = readUnsignedInt([[NSData alloc] init], 12);
XCTAssert(value == 0, "range outside of buffer should return 0 value");
const unsigned char bytes[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
NSData *validBuffer = [NSData dataWithBytes:bytes length:sizeof(bytes)];
value = readUnsignedInt(validBuffer, 12);
XCTAssert(value == 269422093, "should be valid value in range");
}

- (void)testWriteInt {
const unsigned char bytes[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
NSMutableData *buffer = [NSMutableData dataWithBytes:bytes length:sizeof(bytes)];
NSUInteger value;
value = readUnsignedInt([[NSMutableData alloc] init], 1);
XCTAssert(value == 0, @"invalid value written and read.");
value = readUnsignedInt(buffer, 1);
XCTAssert(value == 0, @"invalid value written and read.");
writeInt(buffer, 1, 84148994);
value = readUnsignedInt(buffer, 1);
XCTAssert(value == 84148994, @"invalid value written and read.");
}

@end

0 comments on commit 1573951

Please sign in to comment.