Commit 9d036bdd8f for openssl.org
commit 9d036bdd8fb794363feb2f3e02dacd675b497935
Author: Pauli <paul.dale@oracle.com>
Date: Fri Sep 4 10:22:41 2026 +1000
params: add directive for dealing with duplicated parameters
The generated param name decoders will, by default, return an error
if a duplicate param name is encountered. Although passing a repeated
parameter is a bug in the caller, this isn't always desirable behaviour.
Add the ability to accept the first occupance and to ignore later ones.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Mon Sep 7 18:14:54 2026
Merged-from: https://github.com/openssl/openssl/pull/32675
diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm
index dd34cee7d8..9e97187c52 100644
--- a/util/perl/OpenSSL/paramnames.pm
+++ b/util/perl/OpenSSL/paramnames.pm
@@ -704,6 +704,7 @@ sub trie_matched {
my $with_count = shift;
my $field = shift;
my $num = shift;
+ my $dup = shift;
my $indent1 = shift;
my $indent2 = shift;
@@ -721,9 +722,13 @@ sub trie_matched {
printf "%sr->%s[r->num_%s++] = (OSSL_PARAM *)p;\n", $indent1, $field, $field;
} else {
printf "%sif (ossl_unlikely(r->%s != NULL)) {\n", $indent1, $field;
- printf "%sERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,\n", $indent2;
- printf "%s \"param %%s is repeated\", s);\n", $indent2;
- printf "%sreturn 0;\n", $indent2;
+ if (defined $dup && $dup eq 'first') {
+ printf "%sbreak;\n", $indent2;
+ } else {
+ printf "%sERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,\n", $indent2;
+ printf "%s \"param %%s is repeated\", s);\n", $indent2;
+ printf "%sreturn 0;\n", $indent2;
+ }
printf "%s}\n", $indent1;
printf "%s++*count;\n", $indent1 if $with_count;
printf "%sr->%s = (OSSL_PARAM *)p;\n", $indent1, $field;
@@ -736,6 +741,7 @@ sub generate_decoder_from_trie {
my $trieref = shift;
my $identmap = shift;
my $concat_num = shift;
+ my $process_dup = shift;
my $ifdefs = shift;
my $idt = " ";
my $indent0 = $idt x ($n + 3);
@@ -749,6 +755,7 @@ sub generate_decoder_from_trie {
$field = $identmap->{$trieref->{'name'}};
my $num = $concat_num->{$field};
+ my $dup = $process_dup->{$field};
output_ifdef($ifdefs->{$field});
printf "%sif (ossl_likely($strcmp(\"$suf\", s + $n) == 0", $indent0;
if (not $case_sensitive) {
@@ -758,7 +765,7 @@ sub generate_decoder_from_trie {
}
print ")) {\n";
printf "%s/* %s */\n", $indent1, $trieref->{'name'};
- trie_matched($with_count, $field, $num, $indent1, $indent2);
+ trie_matched($with_count, $field, $num, $dup, $indent1, $indent2);
printf "%s}\n", $indent0;
# If this is at the top level and it's conditional, we have to
@@ -777,10 +784,11 @@ sub generate_decoder_from_trie {
if ($l eq 'val') {
$field = $identmap->{$trieref->{'val'}};
my $num = $concat_num->{$field};
+ my $dup = $process_dup->{$field};
printf "%sbreak;\n", $indent1;
printf "%scase '\\0':\n", $indent0;
output_ifdef($ifdefs->{$field});
- trie_matched($with_count, $field, $num, $indent1, $indent2);
+ trie_matched($with_count, $field, $num, $dup, $indent1, $indent2);
output_endifdef($ifdefs->{$field});
} else {
printf "%sbreak;\n", $indent1;
@@ -790,7 +798,7 @@ sub generate_decoder_from_trie {
printf " case '%s':", uc $l if ($l =~ /[a-z]/);
}
print "\n";
- generate_decoder_from_trie($with_count, $n + 1, $trieref->{$l}, $identmap, $concat_num, $ifdefs);
+ generate_decoder_from_trie($with_count, $n + 1, $trieref->{$l}, $identmap, $concat_num, $process_dup, $ifdefs);
}
}
if ($need_break) {
@@ -867,6 +875,7 @@ sub output_param_decoder {
my @keys = ();
my %prms = ();
my %concat_num = ();
+ my %process_dup = ();
my %ifdefs = ();
if (!$headers_included) {
@@ -907,6 +916,10 @@ sub output_param_decoder {
} elsif (substr($pnum, 0, 3) eq '#if') {
# Trim the `#if' from the front
$ifdefs{$pident} = substr($pnum, 3);
+ } elsif ($pnum =~ '^duplicate: *(first)') {
+ # This provides a provision for other duplicate resolution methods
+ # even though they aren't implemented yet
+ $process_dup{$pident} = $1;
} elsif (not defined $concat_num{$pident}) {
$concat_num{$pident} = $pnum;
}
@@ -963,7 +976,7 @@ sub output_param_decoder {
print " memset(r, 0, sizeof(*r));\n";
print " if (p != NULL)\n";
print " for (; (s = p->key) != NULL; p++)\n";
- generate_decoder_from_trie($with_count, 0, \%t, \%prms, \%concat_num, \%ifdefs);
+ generate_decoder_from_trie($with_count, 0, \%t, \%prms, \%concat_num, \%process_dup, \%ifdefs);
print " return 1;\n";
print "}\n#endif\n";
print "/* End of machine generated */";