From 35bd4c860047e86c527d8494e22411f08744abd3 Mon Sep 17 00:00:00 2001
From: Pompolic <pompolic@special-circumstanc.es>
Date: Tue, 22 Mar 2022 20:54:21 +0100
Subject: [PATCH] (WIP) More log message handling

---
 pdf.c | 73 +++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 56 insertions(+), 17 deletions(-)

diff --git a/pdf.c b/pdf.c
index 07275db..9c0e702 100644
--- a/pdf.c
+++ b/pdf.c
@@ -38,32 +38,50 @@ uint64_t log_messages = 0; // XXX: maybe make it static to log_messages
 uint64_t log_capacity = 0; // XXX: this too
 uint8_t logs_failed = 0;
 
-/*
-typedef struct log_message_S {
-	const char *message,
+
+typedef struct log_entry_S {
+	const char *message;
 	uint8_t severity;
-} log_message;
+} log_entry;
 
-log_message *logs = NULL;
+log_entry **logs = NULL;
 
-*/
+void free_log_messages();
 
 void log_message(const char *message, uint8_t severity)
 {
-	log_message *msg;
+	log_entry *msg;
 
 	if(logs_failed)
 	{
-		return;
+		return; //XXX: maybe fall back on printing to stderr
 	}
 	else if(logs == NULL)
 	{
-		logs = calloc(4096, sizeof(log_message));
+		logs = calloc(4096, sizeof(log_entry));
 	}
 	else if(log_capacity == log_messages)
 	{
-		logs = reallocarray(logs, log_capacity + 4096, sizeof(log_message));
-		log_capacity += 4096
+		uint64_t newcapacity = log_capacity + 4096;
+		/* Overflow check */
+		if(newcapacity < log_capacity)
+		{
+			fprintf(stderr, "Failed to grow log buffer. (capacity > UINT64_MAX)\n");
+			logs_failed = 1;
+			free_log_messages();
+			return;
+		}
+		size_t newsize = newcapacity * sizeof(log_entry);
+		/* Check for overflow */
+		if(newcapacity != 0 && newsize / newcapacity != sizeof(log_entry))
+		{
+			fprintf(stderr, "Failed to grow log buffer. (size * count overflowed)\n");
+			logs_failed = 1;
+			free_log_messages();
+			return;
+		}
+		logs = realloc(logs, newsize);
+		log_capacity += 4096;
 	}
 
 	/* check logs again in case calloc or realloc failed */
@@ -74,7 +92,7 @@ void log_message(const char *message, uint8_t severity)
 		return;
 	}
 
-	msg = malloc(sizeof(log_message);
+	msg = malloc(sizeof(log_message));
 	msg->message = message;
 	msg->severity = severity;
 
@@ -83,11 +101,11 @@ void log_message(const char *message, uint8_t severity)
 
 void print_log_messages()
 {
-	log_message *entry;
+	log_entry *entry;
 
 	for(int i = 0; i < log_messages; i++)
 	{
-		entry = log_messages[i];
+		entry = logs[i];
 		if(log_level <= entry->severity)
 		{
 			fprintf(stderr, "%s\n", entry->message);
@@ -97,7 +115,15 @@ void print_log_messages()
 
 void free_log_messages()
 {
-	//XXX: TODO
+	for(int i = 0; i < log_messages; i++)
+	{
+		if(logs[i])
+		{
+			free(logs[i]);
+		}
+	}
+
+	free(logs);
 }
 extern int errno;  // used in text extraction
 
@@ -5808,14 +5834,27 @@ main(int argc, char *argv[])
 	int fd;
 
 	/* command line handling */
-	if (argc > 3) {
+	if (argc > 4) {
 		fprintf(stderr, "usage: %s file\n", argv[0]);
 		return 1;
 	}
-	if (argc == 3) {
+	if (argc >= 3) {
 	  H_RULE(nat, h_action(h_many1(h_action(h_ch_range('0', '9'), act_digit, NULL)),
 			       act_nat, NULL));
 	  strictness = h_parse(nat, (uint8_t *)argv[2], strlen(argv[2]))->ast->uint;
+	  if(argc == 4) //XXX: consistent indent
+	  {
+		HParseResult *llevel = h_parse(nat, (uint8_t *)argv[3], strlen(argv[3]));
+		if(llevel && llevel->ast)
+		{
+			log_level = llevel->ast->uint;
+		}
+		else
+		{
+			/* Default to max verbosity */
+			log_level = 0;
+		}
+	  }
 	}
 	infile = argv[1];
 
-- 
GitLab