static int ASN1_get_object_without_inf()

in Sources/PackageCollectionsSigningLibc/asn1/a_d2i_fp.c [236:297]


static int ASN1_get_object_without_inf(const unsigned char **pp, long *plength,
                                       int *ptag, int *pclass, long omax)
{
    int i, ret;
    long l;
    const unsigned char *p = *pp;
    int tag, xclass;
    long max = omax;

    if (!max)
        goto err;
    ret = (*p & V_ASN1_CONSTRUCTED);
    xclass = (*p & V_ASN1_PRIVATE);
    i = *p & V_ASN1_PRIMITIVE_TAG;
    if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
        p++;
        if (--max == 0)
            goto err;
        l = 0;
        while (*p & 0x80) {
            l <<= 7L;
            l |= *(p++) & 0x7f;
            if (--max == 0)
                goto err;
            if (l > (INT_MAX >> 7L))
                goto err;
        }
        l <<= 7L;
        l |= *(p++) & 0x7f;
        tag = (int)l;
        if (--max == 0)
            goto err;
    } else {
        tag = i;
        p++;
        if (--max == 0)
            goto err;
    }

    /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
    if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
        goto err;

    *ptag = tag;
    *pclass = xclass;
    if (!asn1_get_length_without_inf(&p, plength, max))
        goto err;

    if (*plength > (omax - (p - *pp))) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
        /*
         * Set this so that even if things are not long enough the values are
         * set correctly
         */
        ret |= 0x80;
    }
    *pp = p;
    return ret;
 err:
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
    return 0x80;
}