if(tag != -1) {
p = *in;
imphack = *p;
- *p = (*p & V_ASN1_CONSTRUCTED) | it->utype;
+ *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype);
}
ptmpval = cf->asn1_d2i(pval, in, len);
* it increases efficiency in some cases.
*/
if(i == (it->tcount - 1)) isopt = 0;
- else isopt = seqtt->flags & ASN1_TFLG_OPTIONAL;
+ else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
/* attempt to read in field, allowing each to be OPTIONAL */
ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
if(!ret) {
cont = *in;
/* If indefinite length constructed find the real end */
if(inf) {
- asn1_collect(NULL, &p, plen, inf, -1, -1);
+ if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err;
len = p - cont;
} else {
len = p - cont + plen;
* internally irrespective of the type. So instead just check
* for UNIVERSAL class and ignore the tag.
*/
- asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL);
- cont = (unsigned char *)buf.data;
+ if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err;
len = buf.length;
+ /* Append a final null to string */
+ if(!BUF_MEM_grow(&buf, len + 1)) {
+ ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ buf.data[len] = 0;
+ cont = (unsigned char *)buf.data;
free_cont = 1;
} else {
cont = p;
if(!*pval) {
typ = ASN1_TYPE_new();
*pval = (ASN1_VALUE *)typ;
- } else typ = (ASN1_TYPE *)pval;
+ } else typ = (ASN1_TYPE *)*pval;
if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL);
pval = (ASN1_VALUE **)&typ->value.ptr;
}
ctx->ptag = ptag;
ctx->hdrlen = p - q;
ctx->valid = 1;
- }
- /* If definite length, length + header can't exceed total
- * amount of data available.
- */
- if(!(i & 1) && ((plen + ctx->hdrlen) > len)) {
- ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
- asn1_tlc_clear(ctx);
- return 0;
+ /* If definite length, length + header can't exceed total
+ * amount of data available.
+ */
+ if(!(i & 1) && ((plen + ctx->hdrlen) > len)) {
+ ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
+ asn1_tlc_clear(ctx);
+ return 0;
+ }
}
}