+ unsigned long offset = item->Length;
+ if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
+ // The previous bit string must have no unused bits.
+ if (item->Length & 0x7) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ // If this is a bit string, the length is bits, not bytes.
+ offset = item->Length >> 3;
+ }
+ if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
+ // Protect against overflow during the bytes-to-bits conversion.
+ if (len >= (ULONG_MAX >> 3) + 1) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ unsigned long len_in_bits = (len << 3) - state->bit_string_unused_bits;
+ // Protect against overflow when computing the total length in bits.
+ if (UINT_MAX - item->Length < len_in_bits) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ item->Length += len_in_bits;
+ } else {
+ if (UINT_MAX - item->Length < len) {
+ PORT_SetError (SEC_ERROR_BAD_DER);
+ state->top->status = decodeError;
+ return 0;
+ }
+ item->Length += len;
+ }
+ PORT_Memcpy (item->Data + offset, buf, len);