ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/vendor-crypto/openssl/dist/crypto/asn1/a_d2i_fp.c
(Generate patch)

Comparing vendor-crypto/openssl/dist/crypto/asn1/a_d2i_fp.c (file contents):
Revision 11604 by laffer1, Fri Mar 20 00:01:13 2015 UTC vs.
Revision 11605 by laffer1, Sun Jul 8 16:16:48 2018 UTC

# Line 141 | Line 141 | void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in,
141   #endif
142  
143   #define HEADER_SIZE   8
144 + #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
145   static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
146   {
147      BUF_MEM *b;
# Line 217 | Line 218 | static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
218              /* suck in c.slen bytes of data */
219              want = c.slen;
220              if (want > (len - off)) {
221 +                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
222 +
223                  want -= (len - off);
224                  if (want > INT_MAX /* BIO_read takes an int length */  ||
225                      len + want < len) {
226                      ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
227                      goto err;
228                  }
226                if (!BUF_MEM_grow_clean(b, len + want)) {
227                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
228                    goto err;
229                }
229                  while (want > 0) {
230 <                    i = BIO_read(in, &(b->data[len]), want);
231 <                    if (i <= 0) {
232 <                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
233 <                                ASN1_R_NOT_ENOUGH_DATA);
230 >                    /*
231 >                     * Read content in chunks of increasing size
232 >                     * so we can return an error for EOF without
233 >                     * having to allocate the entire content length
234 >                     * in one go.
235 >                     */
236 >                    size_t chunk = want > chunk_max ? chunk_max : want;
237 >
238 >                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
239 >                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
240                          goto err;
241                      }
242 +                    want -= chunk;
243 +                    while (chunk > 0) {
244 +                        i = BIO_read(in, &(b->data[len]), chunk);
245 +                        if (i <= 0) {
246 +                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
247 +                                    ASN1_R_NOT_ENOUGH_DATA);
248 +                            goto err;
249 +                        }
250                      /*
251                       * This can't overflow because |len+want| didn't
252                       * overflow.
253                       */
254 <                    len += i;
255 <                    want -= i;
254 >                        len += i;
255 >                        chunk -= i;
256 >                    }
257 >                    if (chunk_max < INT_MAX/2)
258 >                        chunk_max *= 2;
259                  }
260              }
261              if (off + c.slen < off) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines