/** * Destroys a multipart/form-data parser. * * @param mpartp */ void htp_mpartp_destroy(htp_mpartp_t ** _mpartp) { if ((_mpartp == NULL) || (*_mpartp == NULL)) return; htp_mpartp_t * mpartp = *_mpartp; if (mpartp->boundary != NULL) { free(mpartp->boundary); } bstr_builder_destroy(mpartp->part_pieces); bstr_builder_destroy(mpartp->boundary_pieces); // Free parts if (mpartp->parts != NULL) { htp_mpart_part_t * part = NULL; list_iterator_reset(mpartp->parts); while ((part = list_iterator_next(mpartp->parts)) != NULL) { htp_mpart_part_destroy(part); } list_destroy(&mpartp->parts); } free(mpartp); *_mpartp = NULL; }
/** * Destroys an existing URLENCODED parser. * * @param urlenp */ void htp_urlenp_destroy(htp_urlenp_t **_urlenp) { if ((_urlenp == NULL)||(*_urlenp == NULL)) return; htp_urlenp_t *urlenp = *_urlenp; if (urlenp->_name != NULL) { bstr_free(&urlenp->_name); } bstr_builder_destroy(urlenp->_bb); if (urlenp->params != NULL) { // Destroy parameters bstr *value = NULL; table_iterator_reset(urlenp->params); while (table_iterator_next(urlenp->params, (void **) & value) != NULL) { bstr_free(&value); } table_destroy(&urlenp->params); } free(urlenp); *_urlenp = NULL; }
TEST(BstrBuilder, Append) { bstr_builder_t *bb = bstr_builder_create(); bstr *str1 = bstr_dup_c("0123456789"); bstr *str2 = bstr_dup_c("abcdefghijklmnopqrstuvwxyz"); EXPECT_EQ(0, bstr_builder_size(bb)); bstr_builder_appendn(bb, str1); bstr_builder_append_c(bb, "#"); bstr_builder_appendn(bb, str2); bstr_builder_append_c(bb, "#"); bstr_builder_append_mem(bb, "!@#$%^&*()", 4); EXPECT_EQ(5, bstr_builder_size(bb)); bstr *result = bstr_builder_to_str(bb); EXPECT_EQ(42, bstr_len(result)); EXPECT_EQ(0, memcmp("0123456789#abcdefghijklmnopqrstuvwxyz#!@#$", bstr_ptr(result),42)); bstr_free(result); bstr_builder_clear(bb); EXPECT_EQ(0, bstr_builder_size(bb)); bstr_builder_destroy(bb); }
TEST(BstrBuilder, CreateDestroy) { bstr_builder_t *bb = bstr_builder_create(); EXPECT_EQ(0, bstr_builder_size(bb)); bstr_builder_append_c(bb, "ABC"); bstr_builder_destroy(bb); }
/** * Destroys an existing URLENCODED parser. * * @param[in] urlenp */ void htp_urlenp_destroy(htp_urlenp_t *urlenp) { if (urlenp == NULL) return; if (urlenp->_name != NULL) { bstr_free(urlenp->_name); } bstr_builder_destroy(urlenp->_bb); if (urlenp->params != NULL) { // Destroy parameters. for (size_t i = 0, n = htp_table_size(urlenp->params); i < n; i++) { bstr *b = htp_table_get_index(urlenp->params, i, NULL); // Parameter name will be freed by the table code. bstr_free(b); } htp_table_destroy(urlenp->params); } free(urlenp); }
/** * Transcode one bstr. * * @param[in] cd * @param[in] input * @param[in] output */ int htp_transcode_bstr(iconv_t cd, bstr *input, bstr **output) { // Reset conversion state for every new string iconv(cd, NULL, 0, NULL, 0); bstr_builder_t *bb = NULL; const size_t buflen = 10; unsigned char *buf = malloc(buflen); if (buf == NULL) { return HTP_ERROR; } const char *inbuf = (const char *)bstr_ptr(input); size_t inleft = bstr_len(input); char *outbuf = (char *)buf; size_t outleft = buflen; int loop = 1; while (loop) { loop = 0; if (iconv(cd, (ICONV_CONST char **)&inbuf, &inleft, (char **)&outbuf, &outleft) == (size_t) - 1) { if (errno == E2BIG) { // Create bstr builder on-demand if (bb == NULL) { bb = bstr_builder_create(); if (bb == NULL) { free(buf); return HTP_ERROR; } } // The output buffer is full bstr_builder_append_mem(bb, buf, buflen - outleft); outbuf = (char *)buf; outleft = buflen; // Continue in the loop, as there's more work to do loop = 1; } else { // Error if (bb != NULL) bstr_builder_destroy(bb); free(buf); return HTP_ERROR; } } } if (bb != NULL) { bstr_builder_append_mem(bb, buf, buflen - outleft); *output = bstr_builder_to_str(bb); bstr_builder_destroy(bb); if (*output == NULL) { free(buf); return HTP_ERROR; } } else { *output = bstr_dup_mem(buf, buflen - outleft); if (*output == NULL) { free(buf); return HTP_ERROR; } } free(buf); return HTP_OK; }