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;