diff --git a/libclamav/htmlnorm.c b/libclamav/htmlnorm.c
index 704ffdb95d..cf22c9d025 100644
--- a/libclamav/htmlnorm.c
+++ b/libclamav/htmlnorm.c
@@ -52,6 +52,8 @@
#include "clamav_rust.h"
#include "scanners.h"
+extern bool fail_realloc;
+
#define HTML_STR_LENGTH 1024
#define MAX_TAG_CONTENTS_LENGTH HTML_STR_LENGTH
@@ -370,51 +372,91 @@ void html_tag_arg_add(tag_arguments_t *tags,
const char *tag, char *value)
{
int len, i;
- tags->count++;
- tags->tag = (unsigned char **)cli_max_realloc_or_free(tags->tag,
- tags->count * sizeof(char *));
- if (!tags->tag) {
+ int tagCnt = tags->count;
+ int valueCnt = tags->count;
+ int contentCnt = 0;
+ unsigned char ** tmp = NULL;
+
+ static int cnt = 0;
+ cnt++;
+
+#if 0
+ if (cnt > 2) {
+ fail_realloc = true;
+ }
+#endif
+ tmp = (unsigned char **) cli_max_realloc(tags->tag, (tagCnt+1) * sizeof(char *));
+ if (!tmp) {
goto done;
}
- tags->value = (unsigned char **)cli_max_realloc_or_free(tags->value,
- tags->count * sizeof(char *));
- if (!tags->value) {
+ tags->tag = tmp;
+ tagCnt++;
+
+#if 0
+ if (cnt > 2) {
+ fail_realloc = true;
+ }
+#endif
+ tmp = (unsigned char **)cli_max_realloc(tags->value, (valueCnt+1) * sizeof(char *));
+ if (!tmp) {
goto done;
}
+ tags->value = tmp;
+ valueCnt++;
+
if (tags->scanContents) {
- tags->contents = (unsigned char **)cli_max_realloc_or_free(tags->contents,
- tags->count * sizeof(*tags->contents));
- if (!tags->contents) {
+ contentCnt = tags->count;
+#if 0
+ if (cnt > 2) {
+ fail_realloc = true;
+ }
+#endif
+ tmp = (unsigned char **)cli_max_realloc(tags->contents, (contentCnt+1) * sizeof(*tags->contents));
+ if (!tmp) {
goto done;
}
- tags->contents[tags->count - 1] = NULL;
+ tags->contents = tmp;
+ tags->contents[contentCnt] = NULL;
+ contentCnt++;
}
- tags->tag[tags->count - 1] = (unsigned char *)cli_safer_strdup(tag);
+
+ tags->tag[tags->count] = (unsigned char *)cli_safer_strdup(tag);
if (value) {
if (*value == '"') {
- tags->value[tags->count - 1] = (unsigned char *)cli_safer_strdup(value + 1);
+ if (cnt > 2) {
+ fail_realloc = true;
+ }
+ tags->value[tags->count] = (unsigned char *)cli_safer_strdup(value + 1);
+ if (NULL == tags->value[tags->count]) {
+ goto done;
+ }
len = strlen((const char *)value + 1);
if (len > 0) {
- tags->value[tags->count - 1][len - 1] = '\0';
+ tags->value[tags->count][len - 1] = '\0';
}
} else {
- tags->value[tags->count - 1] = (unsigned char *)cli_safer_strdup(value);
+ tags->value[tags->count] = (unsigned char *)cli_safer_strdup(value);
}
} else {
- tags->value[tags->count - 1] = NULL;
+ tags->value[tags->count] = NULL;
}
+
+ tags->count++;
return;
done:
/* Bad error - can't do 100% recovery */
- tags->count--;
- for (i = 0; i < tags->count; i++) {
+ for (i = 0; i < tagCnt; i++) {
if (tags->tag) {
free(tags->tag[i]);
}
+ }
+ for (i = 0; i < valueCnt; i++) {
if (tags->value) {
free(tags->value[i]);
}
+ }
+ for (i = 0; i < contentCnt; i++) {
if (tags->contents) {
if (tags->contents[i])
free(tags->contents[i]);
@@ -658,12 +700,22 @@ bool html_insert_form_data(const char * const value, form_data_t *tags) {
* Do NOT use cli_max_realloc_or_free because all the previously malloc'd tag
* values will be leaked when tag is free'd in the case where realloc fails.
*/
+ static int runCnt = 1;
+ runCnt++;
+#if 0
+ if (runCnt > 3) {
+ fail_realloc = true;
+ }
+#endif
tmp = cli_max_realloc(tags->urls, cnt * sizeof(unsigned char *));
if (!tmp) {
goto done;
}
tags->urls = tmp;
+ if (runCnt > 2) {
+ fail_realloc = true;
+ }
tags->urls[tags->count] = cli_safer_strdup(value);
if (tags->urls[tags->count]) {
tags->count = cnt;
diff --git a/libclamav/others_common.c b/libclamav/others_common.c
index 60d0179d2d..2ed958d596 100644
--- a/libclamav/others_common.c
+++ b/libclamav/others_common.c
@@ -63,6 +63,8 @@
#include "entconv.h"
#include "clamav_rust.h"
+bool fail_realloc = false;
+
#define MSGBUFSIZ 8192
static bool rand_seeded = false;
@@ -314,7 +316,12 @@ void *cli_max_realloc(void *ptr, size_t size)
return NULL;
}
+ if (fail_realloc){
+ alloc = NULL;
+ } else {
alloc = realloc(ptr, size);
+ }
+ fail_realloc = false;
if (!alloc) {
perror("realloc_problem");
@@ -337,6 +344,21 @@ void *cli_max_realloc_or_free(void *ptr, size_t size)
alloc = realloc(ptr, size);
+#if 0
+ if (fail_realloc) {
+ fprintf(stderr, "%s::%d::Forcing realloc to actually fail\n", __FUNCTION__, __LINE__);
+ fprintf(stderr, "%s::%d::ptr = %p\n", __FUNCTION__, __LINE__, ptr);
+ fprintf(stderr, "%s::%d::alloc = %p\n", __FUNCTION__, __LINE__, alloc);
+ free(alloc);
+ if (alloc != ptr){
+ ptr = NULL;
+ }
+ alloc = NULL;
+ }
+ fail_realloc = false;
+
+#endif
+
if (!alloc) {
perror("realloc_problem");
cli_errmsg("cli_max_realloc_or_free(): Can't re-allocate memory to %zu bytes.\n", size);
@@ -361,6 +383,11 @@ char *cli_safer_strdup(const char *s)
return NULL;
}
+ if (fail_realloc){
+ fail_realloc = false;
+ return NULL;
+ }
+
alloc = strdup(s);
if (!alloc) {