int spdylay_frame_count_unpack_nv_space(size_t *nvlen_ptr, size_t *buflen_ptr, spdylay_buffer *in, size_t len_size) { uint32_t n; size_t buflen = 0; size_t nvlen = 0; size_t off = 0; size_t inlen = spdylay_buffer_length(in); size_t i; spdylay_buffer_reader reader; if(inlen < len_size) { return SPDYLAY_ERR_INVALID_FRAME; } spdylay_buffer_reader_init(&reader, in); /* TODO limit n in a reasonable number */ n = spdylay_frame_get_nv_len(&reader, len_size); off += len_size; for(i = 0; i < n; ++i) { uint32_t len; size_t j; for(j = 0; j < 2; ++j) { if(inlen-off < len_size) { return SPDYLAY_ERR_INVALID_FRAME; } len = spdylay_frame_get_nv_len(&reader, len_size); off += len_size; if(inlen-off < len) { return SPDYLAY_ERR_INVALID_FRAME; } buflen += len+1; off += len; if(j == 0) { spdylay_buffer_reader_advance(&reader, len); } } nvlen += spdylay_buffer_reader_count(&reader, len, '\0'); ++nvlen; } if(inlen == off) { *nvlen_ptr = nvlen; *buflen_ptr = buflen+(nvlen*2+1)*sizeof(char*); return 0; } else { return SPDYLAY_ERR_INVALID_FRAME; } }
ssize_t spdylay_zlib_inflate_hd(spdylay_zlib *inflater, spdylay_buffer* buf, const uint8_t *in, size_t inlen) { int r; inflater->zst.avail_in = inlen; inflater->zst.next_in = (uint8_t*)in; while(1) { if(spdylay_buffer_avail(buf) == 0) { if((r = spdylay_buffer_alloc(buf)) != 0) { return r; } } inflater->zst.avail_out = spdylay_buffer_avail(buf); inflater->zst.next_out = spdylay_buffer_get(buf); r = inflate(&inflater->zst, Z_NO_FLUSH); if(r == Z_STREAM_ERROR || r == Z_STREAM_END || r == Z_DATA_ERROR) { return SPDYLAY_ERR_ZLIB; } else if(r == Z_NEED_DICT) { const uint8_t *hd_dict; size_t hd_dict_length; hd_dict = spdylay_select_hd_dict(&hd_dict_length, inflater->version); assert(hd_dict); if(Z_OK != inflateSetDictionary(&inflater->zst, (uint8_t*)hd_dict, hd_dict_length)) { return SPDYLAY_ERR_ZLIB; } } else { if(r == Z_OK) { size_t adv = spdylay_buffer_avail(buf)-inflater->zst.avail_out; spdylay_buffer_advance(buf, adv); } if(inflater->zst.avail_in == 0 && inflater->zst.avail_out > 0) { break; } } } return spdylay_buffer_length(buf); }