Commit 9ca2185a2b for openssl.org
commit 9ca2185a2b099a17e94e2cac815aba714625e858
Author: Bob Beck <beck@openssl.org>
Date: Sun Aug 16 17:56:09 2026 -0700
Pass the ecparam corpus in a file rather than as arguments
The recipe passed all 102 valid parameter files as arguments, but a test
can be given at most 100 before test_get_argument() runs off the end of
its bookkeeping array. The address sanitizer build caught it; on a
normal build it silently wrote past the end.
Write the file names to a list file and pass that instead, so the corpus
can grow without bound. The globbing and the sm2 filtering stay in the
recipe.
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Tue Sep 1 14:17:23 2026
Merged-from: https://github.com/openssl/openssl/pull/32404
diff --git a/test/ecparam_test.c b/test/ecparam_test.c
index 462b2d2ce9..5accee6177 100644
--- a/test/ecparam_test.c
+++ b/test/ecparam_test.c
@@ -27,7 +27,11 @@
*
* Invoked as:
*
- * ecparam_test valid|noncanon|invalid <file>...
+ * ecparam_test valid|noncanon|invalid <listfile>
+ *
+ * where the list file holds one file name per line. The list is passed
+ * this way because the corpus has more files in it than a test can be
+ * given arguments.
*
* Valid and non-canonically encoded parameters must load and check.
* Invalid ones must not. Only the canonically encoded valid files are
@@ -41,12 +45,55 @@ typedef enum {
static corpus_kind corpus;
static int expect_check; /* Whether loading and checking should succeed */
+static char **files;
static int num_files;
-/* The files start at argument 1; argument 0 names the corpus. */
static const char *corpus_file(int idx)
{
- return test_get_argument(idx + 1);
+ return files[idx];
+}
+
+/* Read the corpus file names, one per line. */
+static int read_file_list(const char *path)
+{
+ BIO *bio = BIO_new_file(path, "r");
+ char line[512];
+ int n = 0, allocated = 0;
+
+ if (bio == NULL)
+ return 0;
+
+ while (BIO_gets(bio, line, sizeof(line)) > 0) {
+ size_t len = strlen(line);
+
+ while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
+ line[--len] = '\0';
+ if (len == 0)
+ continue;
+
+ if (n == allocated) {
+ char **tmp;
+
+ allocated = allocated == 0 ? 64 : allocated * 2;
+ tmp = OPENSSL_realloc(files, allocated * sizeof(*files));
+ if (tmp == NULL)
+ goto err;
+ files = tmp;
+ }
+
+ if ((files[n] = OPENSSL_strdup(line)) == NULL)
+ goto err;
+ n++;
+ }
+
+ BIO_free(bio);
+ num_files = n;
+ return n > 0;
+
+err:
+ num_files = n;
+ BIO_free(bio);
+ return 0;
}
/*
@@ -231,10 +278,9 @@ err:
int setup_tests(void)
{
const char *kind;
- size_t argc = test_get_argument_count();
- if (!TEST_size_t_gt(argc, 1)) {
- TEST_error("usage: ecparam_test valid|noncanon|invalid <file>...");
+ if (!TEST_size_t_eq(test_get_argument_count(), 2)) {
+ TEST_error("usage: ecparam_test valid|noncanon|invalid <listfile>");
return 0;
}
@@ -251,7 +297,11 @@ int setup_tests(void)
}
expect_check = corpus != CORPUS_INVALID;
- num_files = (int)argc - 1;
+
+ if (!TEST_true(read_file_list(test_get_argument(1)))) {
+ TEST_error("cannot read corpus list %s", test_get_argument(1));
+ return 0;
+ }
ADD_ALL_TESTS(test_ecparam_check, num_files);
ADD_ALL_TESTS(test_ecparam_check_named, num_files);
@@ -262,3 +312,12 @@ int setup_tests(void)
return 1;
}
+
+void cleanup_tests(void)
+{
+ int i;
+
+ for (i = 0; i < num_files; i++)
+ OPENSSL_free(files[i]);
+ OPENSSL_free(files);
+}
diff --git a/test/recipes/15-test_ecparam.t b/test/recipes/15-test_ecparam.t
index 20e664873d..2ac8b7c6ea 100644
--- a/test/recipes/15-test_ecparam.t
+++ b/test/recipes/15-test_ecparam.t
@@ -31,11 +31,23 @@ if (disabled("sm2")) {
# pkeyparam applications themselves are covered by 20-test_app_ecparam.t.
plan tests => 3;
-ok(run(test(["ecparam_test", "valid", @valid])),
+# The file names are written to a list file and that is passed instead:
+# there are more of them than a test can be given arguments.
+sub corpus_list {
+ my $name = shift;
+
+ open(my $fh, '>', $name) or die "Cannot write $name: $!";
+ print $fh "$_\n" foreach (@_);
+ close($fh);
+ return $name;
+}
+
+ok(run(test(["ecparam_test", "valid", corpus_list("valid.lst", @valid)])),
"Load and check valid parameters");
-ok(run(test(["ecparam_test", "noncanon", @noncanon])),
+ok(run(test(["ecparam_test", "noncanon",
+ corpus_list("noncanon.lst", @noncanon)])),
"Load and check non-canonically encoded parameters");
-ok(run(test(["ecparam_test", "invalid", @invalid])),
+ok(run(test(["ecparam_test", "invalid", corpus_list("invalid.lst", @invalid)])),
"Reject invalid parameters");