From 5ab7dd1f573f2ead061ffdd76910057f7001bc0f Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 28 Mar 2025 16:02:44 -0500 Subject: [PATCH] Fixed cmd bugs --- src/dusk/assert/assert.h | 2 +- src/dusk/console/console.c | 43 ++++++++++++++++++++++++----------- src/dusk/console/consolecmd.h | 2 +- src/dusk/console/consolevar.h | 4 ++-- src/dusk/util/string.c | 37 +++++++++++++++++++++++++++++- src/dusk/util/string.h | 29 ++++++++++++++++++++++- src/dusktest/main.c | 5 ++-- 7 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/dusk/assert/assert.h b/src/dusk/assert/assert.h index b7d9cf8..56b8668 100644 --- a/src/dusk/assert/assert.h +++ b/src/dusk/assert/assert.h @@ -123,7 +123,7 @@ void assertMemoryRangeMatchesImpl( assertDeprecatedImpl(__FILE__, __LINE__, message) #define assertStrLenMax(str, len, message) \ - assertTrue(strlen(str) <= len, message) + assertTrue(strlen(str) < len, message) #define assertStrLenMin(str, len, message) \ assertTrue(strlen(str) >= len, message) diff --git a/src/dusk/console/console.c b/src/dusk/console/console.c index 598b182..ce520ec 100644 --- a/src/dusk/console/console.c +++ b/src/dusk/console/console.c @@ -44,13 +44,12 @@ consolevar_t * consoleRegVar( void consolePrint(const char_t *message, ...) { char_t buffer[CONSOLE_LINE_MAX]; + va_list args; va_start(args, message); - size_t len = vsnprintf(buffer, CONSOLE_LINE_MAX, message, args); + int32_t len = stringFormatVA(buffer, CONSOLE_LINE_MAX, message, args); va_end(args); - assertTrue(len < CONSOLE_LINE_MAX, "Message is too long."); - // Move all lines back memoryMove( CONSOLE.line[0], @@ -75,7 +74,7 @@ void consoleExec(const char_t *line) { "Too many commands in the buffer." ); - char_t buffer[CONSOLE_LINE_MAX + 1]; + char_t buffer[CONSOLE_LINE_MAX]; size_t i = 0, j = 0; char_t c; consoleexecstate_t state = CONSOLE_EXEC_STATE_INITIAL; @@ -109,14 +108,19 @@ void consoleExec(const char_t *line) { if(c == '"') { // Can't handle quotes within the command. - consolePrint("Error: Invalid command."); + consolePrint("Invalid command"); while(c != '\0' && c != ';') c = line[++i]; continue; } - - assertTrue(j < CONSOLE_LINE_MAX, "Command is too long."); + buffer[j++] = c; i++; + + if(j >= CONSOLE_LINE_MAX) { + consolePrint("Command too long"); + state = CONSOLE_EXEC_STATE_FULLY_PARSED; + continue; + } break; case CONSOLE_EXEC_STATE_CMD_PARSED: @@ -139,7 +143,6 @@ void consoleExec(const char_t *line) { break; case CONSOLE_EXEC_STATE_FIND_ARG: - if(c == '\0' || c == ';') { state = CONSOLE_EXEC_STATE_CMD_FINISHED; continue; @@ -166,6 +169,12 @@ void consoleExec(const char_t *line) { buffer[j++] = c; i++; + + if(j >= CONSOLE_LINE_MAX) { + consolePrint("Arg too long"); + state = CONSOLE_EXEC_STATE_FULLY_PARSED; + continue; + } break; case CONSOLE_EXEC_STATE_PARSE_ARG_QUOTED: @@ -176,21 +185,29 @@ void consoleExec(const char_t *line) { } if(c == '\0' || c == ';') { - consolePrint("Error: Unterminated quoted argument."); - return; + consolePrint("Unterminated quote"); + state = CONSOLE_EXEC_STATE_FULLY_PARSED; + continue; } if(c == '\\') { c = line[++i]; if(c == '\0' || c == ';') { - consolePrint("Error: Unterminated quoted argument."); - return; + consolePrint("Unterminated quote"); + state = CONSOLE_EXEC_STATE_FULLY_PARSED; + continue; } } buffer[j++] = c; i++; + + if(j >= CONSOLE_LINE_MAX) { + consolePrint("Arg too long"); + state = CONSOLE_EXEC_STATE_FULLY_PARSED; + continue; + } break; case CONSOLE_EXEC_STATE_ARG_PARSED: @@ -233,7 +250,7 @@ void consoleExec(const char_t *line) { } if(exec->cmd == NULL) { - consolePrint("Error: Command '%s' not found.", exec->command); + consolePrint("Command not found", exec->command); exec = NULL; state = CONSOLE_EXEC_STATE_INITIAL; break; diff --git a/src/dusk/console/consolecmd.h b/src/dusk/console/consolecmd.h index 6de2c02..09a3c4f 100644 --- a/src/dusk/console/consolecmd.h +++ b/src/dusk/console/consolecmd.h @@ -21,7 +21,7 @@ typedef struct { typedef void (*consolecmdfunc_t)(const consolecmdexec_t *exec); typedef struct consolecmd_s { - char_t name[CONSOLE_CMD_NAME_MAX + 1]; + char_t name[CONSOLE_CMD_NAME_MAX]; consolecmdfunc_t function; } consolecmd_t; diff --git a/src/dusk/console/consolevar.h b/src/dusk/console/consolevar.h index de8ccdd..af6a9df 100644 --- a/src/dusk/console/consolevar.h +++ b/src/dusk/console/consolevar.h @@ -14,8 +14,8 @@ typedef struct consolevar_s consolevar_t; typedef void (*consolevarchanged_t)(const consolevar_t *var); typedef struct consolevar_s { - char_t name[CONSOLE_VAR_NAME_MAX + 1]; - char_t value[CONSOLE_VAR_VALUE_MAX + 1]; + char_t name[CONSOLE_VAR_NAME_MAX]; + char_t value[CONSOLE_VAR_VALUE_MAX]; consolevarchanged_t events[CONSOLE_VAR_EVENTS_MAX]; uint8_t eventCount; } consolevar_t; diff --git a/src/dusk/util/string.c b/src/dusk/util/string.c index b13a076..301db22 100644 --- a/src/dusk/util/string.c +++ b/src/dusk/util/string.c @@ -7,6 +7,7 @@ #include "string.h" #include "assert/assert.h" +#include "util/memory.h" bool_t stringIsWhitespace(const char_t c) { return isspace(c); @@ -15,8 +16,9 @@ bool_t stringIsWhitespace(const char_t c) { void stringCopy(char_t *dest, const char_t *src, const size_t destSize) { assertNotNull(dest, "dest must not be NULL"); assertNotNull(src, "src must not be NULL"); + assertTrue(destSize > 0, "destSize must be greater than 0"); assertStrLenMax(src, destSize, "src is too long"); - strncpy(dest, src, destSize); + memoryCopy(dest, src, strlen(src) + 1); } int stringCompare(const char_t *str1, const char_t *str2) { @@ -47,4 +49,37 @@ char_t * stringToken(char_t *str, const char_t *delim) { assertNotNull(str, "str must not be NULL"); assertNotNull(delim, "delim must not be NULL"); return strtok(str, delim); +} + +int32_t stringFormat( + char_t *dest, + const size_t destSize, + char_t *format, + ... +) { + assertNotNull(dest, "dest must not be NULL"); + assertNotNull(format, "format must not be NULL"); + assertTrue(destSize > 0, "destSize must be greater than 0"); + + va_list args; + va_start(args, format); + int32_t result = stringFormatVA(dest, destSize, format, args); + va_end(args); + + return result; +} + +int32_t stringFormatVA( + char_t *dest, + const size_t destSize, + char_t *format, + va_list args +) { + assertNotNull(dest, "dest must not be NULL"); + assertNotNull(format, "format must not be NULL"); + assertTrue(destSize > 0, "destSize must be greater than 0"); + int32_t ret = vsnprintf(dest, destSize, format, args); + assertTrue(ret >= 0, "Failed to format string."); + assertTrue(ret < destSize, "Formatted string is too long."); + return ret; } \ No newline at end of file diff --git a/src/dusk/util/string.h b/src/dusk/util/string.h index aa5b51f..9b29a19 100644 --- a/src/dusk/util/string.h +++ b/src/dusk/util/string.h @@ -52,4 +52,31 @@ void stringTrim(char_t *str); * @param delim The delimiter to split by. * @return A pointer to the next token in the string. */ -char_t * stringToken(char_t *str, const char_t *delim); \ No newline at end of file +char_t * stringToken(char_t *str, const char_t *delim); + +/** + * Formats a string. + * + * @param dest The destination string. + * @param destSize The size of the destination string exc. null terminator. + * @param format The format string. + * @param ... The arguments to format. + * @return The number of characters written. + */ +int32_t stringFormat(char_t *dest, const size_t destSize, char_t *format, ...); + +/** + * Formats a string using a va_list. + * + * @param dest The destination string. + * @param destSize The size of the destination string exc. null terminator. + * @param format The format string. + * @param args The va_list of arguments. + * @return The number of characters written. + */ +int32_t stringFormatVA( + char_t *dest, + const size_t destSize, + char_t *format, + va_list args +); \ No newline at end of file diff --git a/src/dusktest/main.c b/src/dusktest/main.c index 9ebeeb6..6cfcaf5 100644 --- a/src/dusktest/main.c +++ b/src/dusktest/main.c @@ -25,9 +25,10 @@ int main() { consoleRegCmd("exit", cmdExit); consoleRegVar("test", "Hello", testChange); - consolePrint(" = Dusk Console = "); + consolePrint("init"); + // consolePrint(" = Dusk Console = "); - char_t buffer[CONSOLE_LINE_MAX]; + char_t buffer[CONSOLE_LINE_MAX * 10]; while(fgets(buffer, sizeof(buffer), stdin)) { consoleExec(buffer); consoleProcess();