commit bceed922d932287e66fe6d4538cbd21cb9208f06
parent 60323e2ceb2b585c6d3865458f39a8811e42b452
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 30 Jun 2026 10:46:09 +0200
check that form_name and version are well-formed
Diffstat:
1 file changed, 49 insertions(+), 0 deletions(-)
diff --git a/src/mhd/mhd_typst.c b/src/mhd/mhd_typst.c
@@ -542,6 +542,37 @@ typst_done_cb (void *cls,
/**
+ * Check that @a id only consists of characters that are safe to
+ * interpolate into a Typst `#import` statement (alphanumerics and
+ * `.`, `-`, `_`). This prevents code/path injection via the form
+ * name or version.
+ *
+ * @param id identifier to validate
+ * @return true if @a id is non-empty and only uses the safe charset
+ */
+static bool
+is_valid_form_identifier (const char *id)
+{
+ if ( (NULL == id) ||
+ ('\0' == id[0]) )
+ return false;
+ for (const char *p = id; '\0' != *p; p++)
+ {
+ char c = *p;
+
+ if (! ( ( ('a' <= c) && ('z' >= c)) ||
+ ( ('A' <= c) && ('Z' >= c)) ||
+ ( ('0' <= c) && ('9' >= c)) ||
+ ('.' == c) ||
+ ('-' == c) ||
+ ('_' == c) ) )
+ return false;
+ }
+ return true;
+}
+
+
+/**
* Setup typst stage to produce one of the PDF inputs.
*
* @param[out] stage initialized stage data
@@ -572,6 +603,24 @@ setup_stage (struct TypstStage *stage,
doc->data);
}
+ if (! is_valid_form_identifier (doc->form_name))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Stage %u: Invalid form name `%s'\n",
+ i,
+ doc->form_name);
+ return false;
+ }
+ if ( (NULL != doc->form_version) &&
+ (! is_valid_form_identifier (doc->form_version)) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Stage %u: Invalid form version `%s'\n",
+ i,
+ doc->form_version);
+ return false;
+ }
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Stage %u: Handling form %s\n",
i,