@@ -27,24 +27,48 @@ @implementation OFASN1BitString @synthesize bitStringValue = _bitStringValue; @synthesize bitStringLength = _bitStringLength; -- (instancetype)init ++ (instancetype)bitStringWithBitStringValue: (OFData *)bitStringValue + bitStringLength: (size_t)bitStringLength +{ + return [[[self alloc] + initWithBitStringValue: bitStringValue + bitStringLength: bitStringLength] autorelease]; +} + +- (instancetype)initWithBitStringValue: (OFData *)bitStringValue + bitStringLength: (size_t)bitStringLength { - OF_INVALID_INIT_METHOD + self = [super init]; + + @try { + if ([bitStringValue count] * [bitStringValue itemSize] != + bitStringLength / 8) + @throw [OFInvalidFormatException exception]; + + _bitStringValue = [bitStringValue copy]; + _bitStringLength = bitStringLength; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; } - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { - self = [super init]; + void *pool = objc_autoreleasePoolPush(); + OFData *bitStringValue; + size_t bitStringLength; @try { - void *pool = objc_autoreleasePoolPush(); unsigned char lastByteBits; size_t count = [DEREncodedContents count]; if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING || constructed) @@ -61,22 +85,30 @@ if (SIZE_MAX / 8 < count - 1 || SIZE_MAX - (count - 1) * 8 < lastByteBits) @throw [OFOutOfRangeException exception]; - _bitStringLength = (count - 1) * 8 + lastByteBits; - _bitStringValue = [[DEREncodedContents + bitStringLength = (count - 1) * 8 + lastByteBits; + bitStringValue = [[DEREncodedContents subdataWithRange: of_range(1, count - 1)] copy]; - - objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } + self = [self initWithBitStringValue: bitStringValue + bitStringLength: bitStringLength]; + + objc_autoreleasePoolPop(pool); + return self; } + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} - (void)dealloc { [_bitStringValue release];