Ruiqi Dong created CODEC-337:
--------------------------------

             Summary: Digest ALL reuses System.in, so only the first algorithm 
sees the real input
                 Key: CODEC-337
                 URL: https://issues.apache.org/jira/browse/CODEC-337
             Project: Commons Codec
          Issue Type: Bug
    Affects Versions: 1.22.0
            Reporter: Ruiqi Dong


*Summary*
When Digest is invoked with ALL or * and no explicit input arguments, each 
algorithm reads directly from `System.in`. The first algorithm consumes the 
stream, and all later algorithms hash the empty stream.
 
*Affected code*
File: src/main/java/org/apache/commons/codec/cli/Digest.java
{code:java}
private void run(final String prefix, final MessageDigest messageDigest) throws 
IOException {
    if (inputs == null) {
        println(prefix, DigestUtils.digest(messageDigest, System.in));
        return;
    }
    ...
}

private void run(final String[] digestAlgorithms) throws IOException {
    for (final String messageDigestAlgorithm : digestAlgorithms) {
        if (DigestUtils.isAvailable(messageDigestAlgorithm)) {
            run(messageDigestAlgorithm + " ", messageDigestAlgorithm);
        }
    }
} {code}
*Reproducer*
Add the following test to 
src/test/java/org/apache/commons/codec/cli/DigestTest.java:
{code:java}
@Test
void testAllAlgorithmsUseTheSameStandardInput() throws Exception {
    final InputStream originalIn = System.in;
    final PrintStream originalOut = System.out;
    final ByteArrayOutputStream captured = new ByteArrayOutputStream();
    try {
        System.setIn(new 
ByteArrayInputStream("abc".getBytes(StandardCharsets.UTF_8)));
        System.setOut(new PrintStream(captured, true, 
StandardCharsets.UTF_8.name()));
        Digest.main(new String[] {"ALL"});
    } finally {
        System.setIn(originalIn);
        System.setOut(originalOut);
    }

    final String output = captured.toString(StandardCharsets.UTF_8.name());
    assertTrue(output.contains("MD5 900150983cd24fb0d6963f7d28e17f72"), output);
    assertTrue(output.contains("SHA-1 
a9993e364706816aba3e25717850c26c9cd0d89d"), output);
} {code}
Run:
{code:java}
mvn -q -Dtest=org.apache.commons.codec.cli.DigestTest test {code}
Observed behavior:
{code:java}
MD2 da853b0d3f88d99b30283a69e6ded6bb
MD5 d41d8cd98f00b204e9800998ecf8427e
SHA-1 da39a3ee5e6b4b0d3255bfef95601890afd80709
...
DigestTest.testAllAlgorithmsUseTheSameStandardInput:67
==> expected: <true> but was: <false> {code}
Expected behavior:
Every listed algorithm should hash the same stdin contents.
The CLI output is internally inconsistent for the same invocation. Only the 
first digest is computed over the actual input; the rest are computed over EOF.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to