aboutsummaryrefslogtreecommitdiff
path: root/src/gistatic.c
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2021-08-20 08:02:33 -0300
committerEuAndreh <eu@euandre.org>2021-08-20 08:02:33 -0300
commit97abd351ebd000f2d3c15157f4c2762200a42dca (patch)
tree0377c4c9573fed81b2c41748bdc5373a0f3a7b71 /src/gistatic.c
parentsrc/gistatic.c: Reword comment on date format (diff)
downloadgistatic-97abd351ebd000f2d3c15157f4c2762200a42dca.tar.gz
gistatic-97abd351ebd000f2d3c15157f4c2762200a42dca.tar.xz
src/gistatic.c: Handle overflow of size_t values
Diffstat (limited to 'src/gistatic.c')
-rw-r--r--src/gistatic.c79
1 files changed, 73 insertions, 6 deletions
diff --git a/src/gistatic.c b/src/gistatic.c
index b6040e8..a2c9c14 100644
--- a/src/gistatic.c
+++ b/src/gistatic.c
@@ -518,7 +518,15 @@ static char *strjoin(const char *const s1, const char *const s2) {
return NULL;
}
- const size_t size = strlen(s1) + strlen(s2) + sizeof('\0');
+ const size_t size1 = strnlen(s1, SIZE_MAX);
+ const size_t size2 = strnlen(s2, SIZE_MAX - sizeof('\0'))
+ + sizeof('\0');
+ if (SIZE_MAX - size1 < size2) {
+ errno = EOVERFLOW;
+ logerr("strjoin()", strerror(errno), __LINE__);
+ return NULL;
+ }
+ const size_t size = size1 + size2;
char *const s = malloc(size);
if (!s) {
logerrl("malloc(", size, ")", strerror(errno), __LINE__);
@@ -658,6 +666,39 @@ static void test_formatted_date(void) {
}
#endif
+static size_t max(const size_t size1, const size_t size2) {
+ return size1 > size2 ? size1 : size2;
+}
+
+#ifdef TEST
+static void test_max(void) {
+ test_start("max()");
+ {
+ testing("equal values");
+ assert(max(1, 1) == 1);
+ assert(max(3, 3) == 3);
+ assert(max(0, 0) == 0);
+ assert(max(999, 999) == 999);
+ assert(max(SIZE_MAX, SIZE_MAX) == SIZE_MAX);
+ test_ok();
+ }
+ {
+ testing("first is bigger");
+ assert(max(SIZE_MAX, SIZE_MAX - 1) == SIZE_MAX);
+ assert(max(SIZE_MAX - 1, SIZE_MAX - 2) == SIZE_MAX - 1);
+ assert(max(1, 0) == 1);
+ assert(max(999, 3) == 999);
+ test_ok();
+ }
+ {
+ testing("second is bigger");
+ assert(max(123, 321) == 321);
+ assert(max(1, 999) == 999);
+ test_ok();
+ }
+}
+#endif
+
static char *escape_html(const char *s) {
if (!s) {
return NULL;
@@ -681,10 +722,17 @@ static char *escape_html(const char *s) {
const size_t DQUOT_SIZE = strlen(DQUOT);
const size_t SQUOT_SIZE = strlen(SQUOT);
- const size_t input_size = strlen(s);
+ const size_t BIGGEST = max(AMP_SIZE, max(LT_SIZE, max(GT_SIZE,
+ max(DQUOT_SIZE, SQUOT_SIZE))));
+ const size_t input_size = strnlen(s, SIZE_MAX);
size_t escaped_size = 0;
for (size_t i = 0; i < input_size; i++) {
+ if (SIZE_MAX - escaped_size < BIGGEST) {
+ errno = EOVERFLOW;
+ logerr("escape_html()", strerror(errno), __LINE__);
+ return NULL;
+ }
switch (s[i]) {
case AMPCHAR:
escaped_size += AMP_SIZE;
@@ -867,7 +915,7 @@ static void strtrim(char *const s) {
return;
}
- size_t len = strlen(s);
+ size_t len = strnlen(s, SIZE_MAX);
while (len != 0 && should_trim(s[len - 1])) {
s[len - 1] = '\0';
len--;
@@ -1041,8 +1089,21 @@ static int index_write_header(FILE *const fd, const char *const idx_title) {
}
static char *footer_signature_string(void) {
- const size_t signature_size = strlen(_(MSG_FOOTER_TEMPLATE))
- - strlen("%s") + strlen(PROJECT_HOMEPAGE_LINK) + sizeof('\0');
+ const size_t template_size = strnlen(
+ _(MSG_FOOTER_TEMPLATE),
+ SIZE_MAX
+ ) - strlen("%s");
+ const size_t link_size = strnlen(
+ PROJECT_HOMEPAGE_LINK,
+ SIZE_MAX - sizeof('\0')
+ ) + sizeof('\0');
+ if (SIZE_MAX - template_size < link_size) {
+ errno = EOVERFLOW;
+ logerr("footer_signature_string()", strerror(errno), __LINE__);
+ return NULL;
+ }
+ const size_t signature_size = template_size + link_size;
+
char *const signature_text = malloc(signature_size);
if (!signature_text) {
logerrl("malloc(", signature_size, ")", strerror(errno),
@@ -1050,7 +1111,12 @@ static char *footer_signature_string(void) {
return NULL;
}
- sprintf(signature_text, _(MSG_FOOTER_TEMPLATE), PROJECT_HOMEPAGE_LINK);
+ snprintf(
+ signature_text,
+ signature_size,
+ _(MSG_FOOTER_TEMPLATE),
+ PROJECT_HOMEPAGE_LINK
+ );
return signature_text;
}
@@ -1974,6 +2040,7 @@ static void unit_tests(){
test_remove_suffix();
test_strjoin();
test_formatted_date();
+ test_max();
test_escape_html();
test_should_trim();
test_strtrim();