[PATCH] a68: Fix moids diagnostics buffer overflow [PR122330]
Pietro Monteiro
pietro@sociotechnical.xyz
Sat Oct 25 03:33:45 GMT 2025
Even though there's enough room in the buffer the fortified string
functions will abort because the capacity left in the buffer is less
than SNPRINTF_SIZE.
Fix by passing SNPRINTF_SIZE - len (buffer) to snprintf.
Signed-off-by: Pietro Monteiro <pietro@sociotechnical.xyz>
---
gcc/algol68/a68-moids-diagnostics.cc | 74 ++++++++++++++++------------
1 file changed, 43 insertions(+), 31 deletions(-)
diff --git a/gcc/algol68/a68-moids-diagnostics.cc b/gcc/algol68/a68-moids-diagnostics.cc
index bd9638cb36c..375bd3dfa83 100644
--- a/gcc/algol68/a68-moids-diagnostics.cc
+++ b/gcc/algol68/a68-moids-diagnostics.cc
@@ -32,17 +32,20 @@ const char *
a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, int depth)
{
#define TAIL(z) (&(z)[strlen (z)])
+#define ACTUAL_SNPRINTF_SIZE ((SNPRINTF_SIZE - len))
static BUFFER txt;
+ size_t len;
if (depth == 1)
txt[0] = '\0';
if (IS (p, SERIES_MODE))
{
+ len = strlen (txt);
PACK_T *u = PACK (p);
int N = 0;
if (u == NO_PACK)
{
- if (snprintf (txt, SNPRINTF_SIZE, "empty mode-list") < 0)
+ if (snprintf (txt, ACTUAL_SNPRINTF_SIZE, "empty mode-list") < 0)
gcc_unreachable ();
N++;
}
@@ -56,22 +59,23 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
(void) a68_mode_error_text (n, MOID (u), q, context, deflex, depth + 1);
else if (!a68_is_coercible (MOID (u), q, context, deflex))
{
- size_t len = strlen (txt);
+ len = strlen (txt);
if (len > BUFFER_SIZE / 2)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " etcetera") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " etcetera") < 0)
gcc_unreachable ();
N++;
}
else
{
- if (strlen (txt) > 0)
+ if (len > 0)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " and ") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " and ") < 0)
gcc_unreachable ();
N++;
+ len = strlen (txt);
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, "%s",
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, "%s",
a68_moid_to_string (MOID (u), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
N++;
@@ -82,12 +86,14 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
}
if (depth == 1)
{
+ len = strlen (txt);
if (N == 0)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, "mode") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, "mode") < 0)
gcc_unreachable ();
+ len = strlen (txt);
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " cannot be coerced to %s",
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " cannot be coerced to %s",
a68_moid_to_string (q, MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
}
@@ -95,10 +101,10 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
else if (IS (p, STOWED_MODE) && IS_FLEX (q))
{
PACK_T *u = PACK (p);
-
+ len = strlen (txt);
if (u == NO_PACK)
{
- if (snprintf (txt, SNPRINTF_SIZE, "empty mode-list") < 0)
+ if (snprintf (txt, ACTUAL_SNPRINTF_SIZE, "empty mode-list") < 0)
gcc_unreachable ();
}
else
@@ -107,26 +113,28 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
{
if (!a68_is_coercible (MOID (u), SLICE (SUB (q)), context, deflex))
{
- size_t len = strlen (txt);
+ len = strlen (txt);
if (len > BUFFER_SIZE / 2)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " etcetera") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " etcetera") < 0)
gcc_unreachable ();
}
else
{
- if (strlen (txt) > 0)
+ if (len > 0)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " and ") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " and ") < 0)
gcc_unreachable ();
+ len = strlen (txt);
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, "%s",
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, "%s",
a68_moid_to_string (MOID (u), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
}
}
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " cannot be coerced to %s",
+ len = strlen (txt);
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " cannot be coerced to %s",
a68_moid_to_string (SLICE (SUB (q)), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
}
@@ -134,10 +142,10 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
else if (IS (p, STOWED_MODE) && IS (q, ROW_SYMBOL))
{
PACK_T *u = PACK (p);
-
+ len = strlen (txt);
if (u == NO_PACK)
{
- if (snprintf (txt, SNPRINTF_SIZE, "empty mode-list") < 0)
+ if (snprintf (txt, ACTUAL_SNPRINTF_SIZE, "empty mode-list") < 0)
gcc_unreachable ();
}
else
@@ -146,26 +154,28 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
{
if (!a68_is_coercible (MOID (u), SLICE (q), context, deflex))
{
- size_t len = strlen (txt);
+ len = strlen (txt);
if (len > BUFFER_SIZE / 2)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " etcetera") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " etcetera") < 0)
gcc_unreachable ();
}
else
{
- if (strlen (txt) > 0)
+ if (len > 0)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " and ") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " and ") < 0)
gcc_unreachable ();
+ len = strlen (txt);
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, "%s",
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, "%s",
a68_moid_to_string (MOID (u), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
}
}
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " cannot be coerced to %s",
+ len = strlen (txt);
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " cannot be coerced to %s",
a68_moid_to_string (SLICE (q), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
}
@@ -173,10 +183,10 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
else if (IS (p, STOWED_MODE) && (IS (q, PROC_SYMBOL) || IS (q, STRUCT_SYMBOL)))
{
PACK_T *u = PACK (p), *v = PACK (q);
-
+ len = strlen (txt);
if (u == NO_PACK)
{
- if (snprintf (txt, SNPRINTF_SIZE, "empty mode-list") < 0)
+ if (snprintf (txt, ACTUAL_SNPRINTF_SIZE, "empty mode-list") < 0)
gcc_unreachable ();
}
else
@@ -185,20 +195,21 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
{
if (!a68_is_coercible (MOID (u), MOID (v), context, deflex))
{
- size_t len = strlen (txt);
+ len = strlen (txt);
if (len > BUFFER_SIZE / 2)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " etcetera") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " etcetera") < 0)
gcc_unreachable ();
}
else
{
- if (strlen (txt) > 0)
+ if (len > 0)
{
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, " and ") < 0)
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, " and ") < 0)
gcc_unreachable ();
+ len = strlen (txt);
}
- if (snprintf (TAIL (txt), SNPRINTF_SIZE, "%s cannot be coerced to %s",
+ if (snprintf (TAIL (txt), ACTUAL_SNPRINTF_SIZE, "%s cannot be coerced to %s",
a68_moid_to_string (MOID (u), MOID_ERROR_WIDTH, n),
a68_moid_to_string (MOID (v), MOID_ERROR_WIDTH, n)) < 0)
gcc_unreachable ();
@@ -209,6 +220,7 @@ a68_mode_error_text (NODE_T *n, MOID_T *p, MOID_T *q, int context, int deflex, i
}
return txt;
#undef TAIL
+#undef ACTUAL_SNPRINTF_SIZE
}
/* Cannot coerce error. */
--
2.43.0
More information about the Algol68
mailing list