Commit acddc9b6d0 for openssl.org
commit acddc9b6d02fbe62c31b62c4aeb49736a52bd6ed
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date: Tue Jul 21 23:06:43 2026 +0200
apps: test dgst -r and -c output formats
Add coverage for the coreutils style output of `openssl dgst -r`,
including the newline escaping done by newline_escape_filename() when
the digested file name contains a newline, and for the colon separated
output of `openssl dgst -c`.
The newline in file name part is skipped where such a file cannot be
created.
Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Daniel Kubec <kubec@openssl.foundation>
Reviewed-by: Ryan Hooper <ryanh@openssl.foundation>
MergeDate: Mon Jul 27 10:19:58 2026
(Merged from https://github.com/openssl/openssl/pull/32035)
diff --git a/test/recipes/20-test_dgst.t b/test/recipes/20-test_dgst.t
index 00af8cfff2..9c1a2b87c7 100644
--- a/test/recipes/20-test_dgst.t
+++ b/test/recipes/20-test_dgst.t
@@ -12,13 +12,14 @@ use warnings;
use File::Spec;
use File::Basename;
+use File::Copy;
use OpenSSL::Test qw/:DEFAULT with srctop_file srctop_dir data_file bldtop_dir/;
use OpenSSL::Test::Utils;
use Cwd qw(abs_path);
setup("test_dgst");
-plan tests => 27;
+plan tests => 29;
sub tsignverify {
my $testtext = shift;
@@ -424,6 +425,57 @@ subtest "signing with xoflen is not supported `dgst` CLI" => sub {
"Generating signature with xoflen should fail");
};
+subtest "Coreutils format output with `dgst` CLI" => sub {
+ my $testdata = srctop_file('test', 'data.bin');
+ my $expected =
+ 'd9fd1d3a7dc90526d2853450dcc63e26a311012d337fa4a192276f9824a046da';
+
+ # A newline in a filename is not possible everywhere, so that part of
+ # the test is conditional on actually being able to create such a file.
+ my $nlfile = "dgst_r_newline\nname.bin";
+ my $have_nl = $^O ne 'MSWin32' && $^O ne 'VMS' && copy($testdata, $nlfile);
+
+ plan tests => $have_nl ? 3 : 2;
+
+ my @rdata = run(app(['openssl', 'dgst', '-sha256', '-r', $testdata]),
+ capture => 1);
+ chomp(@rdata);
+ ok($rdata[0] eq "$expected *$testdata",
+ "-r: Check coreutils style output is as expected ($rdata[0])");
+
+ # Without a file argument the input is stdin, reported as "stdin"
+ my @stdindata = run(app(['openssl', 'dgst', '-sha256', '-r'],
+ stdin => $testdata), capture => 1);
+ chomp(@stdindata);
+ ok($stdindata[0] eq "$expected *stdin",
+ "-r: Check coreutils style output for stdin ($stdindata[0])");
+
+ if ($have_nl) {
+ # A newline in the filename is escaped as "\n" and the whole line
+ # is prefixed with a backslash, the way the '*sum' programs do it.
+ my @nldata = run(app(['openssl', 'dgst', '-sha256', '-r', $nlfile]),
+ capture => 1);
+ chomp(@nldata);
+ ok($nldata[0] eq "\\$expected *dgst_r_newline\\nname.bin",
+ "-r: Check newline in filename is escaped ($nldata[0])");
+ unlink($nlfile);
+ }
+};
+
+subtest "Colon separated output with `dgst` CLI" => sub {
+ plan tests => 1;
+
+ my $testdata = srctop_file('test', 'data.bin');
+ my @cdata = run(app(['openssl', 'dgst', '-sha256', '-c', $testdata]),
+ capture => 1);
+ chomp(@cdata);
+ my $hash = 'd9:fd:1d:3a:7d:c9:05:26:d2:85:34:50:dc:c6:3e:26:'
+ . 'a3:11:01:2d:33:7f:a4:a1:92:27:6f:98:24:a0:46:da';
+ my $expected = qr/SHA2-256\(\Q$testdata\E\)= \Q$hash\E/;
+ ok($cdata[0] =~ $expected,
+ "-c: Check colon separated output is as expected ($cdata[0])");
+};
+
subtest "Listing supported digests with `dgst` CLI" => sub {
plan tests => 3;