Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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];
Comment on lines +507 to +509
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need proper error handling if we're going to do this, otherwise consumers will not know why their data is not what they expect.

Copy link
Collaborator Author

@Nadohs Nadohs Mar 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not have enough information from JIRA to understand what core cause is on this.

I have changes locally for adding proper error handling mostly done, but it will alter most of the public API calls to have error properties, would we be ok with that change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not have information from JIRA, but we only have a few places where we adjust the buffer and its size.

In other words, the symptom is we are writing a value outside of the range of a buffer. The root issue is why are we providing a bad buffer in the first place?

I think there is an issue in our file expansion code.

re: error handling -- I think that's fine. It could pollute our internal code though, so we may just want to use try-catches internally.

}
}

/**
* 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