From 590c650aebac98c7f8d7bb2c34ad0f726e5c1639 Mon Sep 17 00:00:00 2001 From: "ctalkobt@ctalkobt.net" Date: Sun, 8 Jun 2025 06:19:48 -0400 Subject: [PATCH 1/5] Correctly handle 0 length strings in conio --- include/mega65/conio.h | 1 - src/conio.c | 24 ++++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/mega65/conio.h b/include/mega65/conio.h index 9259aa0..ec5473b 100644 --- a/include/mega65/conio.h +++ b/include/mega65/conio.h @@ -946,7 +946,6 @@ void cputcxy(unsigned char x, unsigned char y, unsigned char c); * @param y The Y coordinate where character will be printed * @param count The number of characters to output. Must be larger than zero. * @param c The screen code of the characters to print - * @warning Undefined behavior if `count` is zero. */ void cputncxy( unsigned char x, unsigned char y, unsigned char count, unsigned char c); diff --git a/src/conio.c b/src/conio.c index 84da7b6..06741bb 100644 --- a/src/conio.c +++ b/src/conio.c @@ -571,11 +571,13 @@ void cputs(const unsigned char* s) void cputsxy(unsigned char x, unsigned char y, const unsigned char* s) { const unsigned char len = (unsigned char)strlen((const char*)s); - const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; - lcopy((unsigned long)s, SCREEN_RAM_BASE + offset, len); - lfill(COLOR_RAM_BASE + offset, g_curTextColor, len); - g_curY = y + ((x + len) / g_curScreenW); - g_curX = (x + len) % g_curScreenW; + if (len > 0) { + const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; + lcopy((unsigned long)s, SCREEN_RAM_BASE + offset, len); + lfill(COLOR_RAM_BASE + offset, g_curTextColor, len); + g_curY = y + ((x + len) / g_curScreenW); + g_curX = (x + len) % g_curScreenW; + } } void cputcxy(unsigned char x, unsigned char y, unsigned char c) @@ -590,11 +592,13 @@ void cputcxy(unsigned char x, unsigned char y, unsigned char c) void cputncxy( unsigned char x, unsigned char y, unsigned char count, unsigned char c) { - const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; - lfill(SCREEN_RAM_BASE + offset, c, count); - lfill(COLOR_RAM_BASE + offset, g_curTextColor, count); - g_curY = y + ((x + count) / g_curScreenW); - g_curX = (x + count) % g_curScreenW; + if (count > 0) { + const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; + lfill(SCREEN_RAM_BASE + offset, c, count); + lfill(COLOR_RAM_BASE + offset, g_curTextColor, count); + g_curY = y + ((x + count) / g_curScreenW); + g_curX = (x + count) % g_curScreenW; + } } void fillrect(const RECT* rc, unsigned char ch, unsigned char col) From 34993508d9382616c6a61d70b22132b89c51d461 Mon Sep 17 00:00:00 2001 From: "ctalkobt@ctalkobt.net" Date: Sun, 8 Jun 2025 06:39:02 -0400 Subject: [PATCH 2/5] Fix issue where we should still update the current x,y even for 0-length strings. --- src/conio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conio.c b/src/conio.c index 06741bb..38c607d 100644 --- a/src/conio.c +++ b/src/conio.c @@ -575,9 +575,9 @@ void cputsxy(unsigned char x, unsigned char y, const unsigned char* s) const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; lcopy((unsigned long)s, SCREEN_RAM_BASE + offset, len); lfill(COLOR_RAM_BASE + offset, g_curTextColor, len); - g_curY = y + ((x + len) / g_curScreenW); - g_curX = (x + len) % g_curScreenW; } + g_curY = y + ((x + len) / g_curScreenW); + g_curX = (x + len) % g_curScreenW; } void cputcxy(unsigned char x, unsigned char y, unsigned char c) From 021410353285e666bda5438141b956a508595ff4 Mon Sep 17 00:00:00 2001 From: "ctalkobt@ctalkobt.net" Date: Sun, 8 Jun 2025 06:40:32 -0400 Subject: [PATCH 3/5] Fix issue where we should still update the current x,y even for 0-length strings. --- src/conio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conio.c b/src/conio.c index 38c607d..d239031 100644 --- a/src/conio.c +++ b/src/conio.c @@ -596,9 +596,9 @@ void cputncxy( const unsigned int offset = (y * (unsigned int)g_curScreenW) + x; lfill(SCREEN_RAM_BASE + offset, c, count); lfill(COLOR_RAM_BASE + offset, g_curTextColor, count); - g_curY = y + ((x + count) / g_curScreenW); - g_curX = (x + count) % g_curScreenW; } + g_curY = y + ((x + count) / g_curScreenW); + g_curX = (x + count) % g_curScreenW; } void fillrect(const RECT* rc, unsigned char ch, unsigned char col) From a28c1607566161d88e47a8ffa931a0f165d2c4e9 Mon Sep 17 00:00:00 2001 From: "ctalkobt@ctalkobt.net" Date: Sun, 8 Jun 2025 08:43:32 -0400 Subject: [PATCH 4/5] Remove now redundant check for length=0 on cputsxy invocation. --- src/conio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/conio.c b/src/conio.c index d239031..2ed080b 100644 --- a/src/conio.c +++ b/src/conio.c @@ -718,8 +718,7 @@ unsigned char cinput( } while (1) { - if (strlen(buffer) != 0) - cputsxy(sx, sy, buffer); + cputsxy(sx, sy, buffer); blink(1); cputc(224); blink(0); From 7091d6fe5a654a7e829b543c34d23028bfc038a3 Mon Sep 17 00:00:00 2001 From: "ctalkobt@ctalkobt.net" Date: Sun, 8 Jun 2025 08:49:03 -0400 Subject: [PATCH 5/5] cputsxy documentation cleanup. --- include/mega65/conio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mega65/conio.h b/include/mega65/conio.h index ec5473b..9e2a080 100644 --- a/include/mega65/conio.h +++ b/include/mega65/conio.h @@ -914,7 +914,8 @@ void fastcall cputs(const unsigned char* s); * @param y The Y coordinate where string will be printed * @param s An array of screen codes to print. Must have non-zero length. * @remarks This function works with screen codes only. To output ordinary - * @warning Undefined behavior if `s` has zero length. + * ASCII/PETSCII strings, use the "pcputsxy" macro. No pointer check is + * performed. If s is null or invalid, behavior is undefined. */ void cputsxy(unsigned char x, unsigned char y, const unsigned char* s);