8260960: Signs of jarsigner signing

Reviewed-by: weijun, rhalade
diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java
index ba8b4c7..fcf3691 100644
--- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java
+++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java
@@ -795,8 +795,12 @@
                     CodeSigner[] signers = je.getCodeSigners();
                     boolean isSigned = (signers != null);
                     anySigned |= isSigned;
-                    hasUnsignedEntry |= !je.isDirectory() && !isSigned
-                                        && !signatureRelated(name);
+
+                    boolean unsignedEntry = !isSigned
+                            && ((!je.isDirectory() && !signatureRelated(name))
+                            // a directory entry but with a suspicious size
+                            || (je.isDirectory() && je.getSize() > 0));
+                    hasUnsignedEntry |= unsignedEntry;
 
                     int inStoreWithAlias = inKeyStore(signers);
 
@@ -818,7 +822,9 @@
                         sb.append(isSigned ? rb.getString("s") : rb.getString("SPACE"))
                                 .append(inManifest ? rb.getString("m") : rb.getString("SPACE"))
                                 .append(inStore ? rb.getString("k") : rb.getString("SPACE"))
-                                .append((inStoreWithAlias & NOT_ALIAS) != 0 ? 'X' : ' ')
+                                .append((inStoreWithAlias & NOT_ALIAS) != 0 ?
+                                 rb.getString("X") : rb.getString("SPACE"))
+                                .append(unsignedEntry ? rb.getString("q") : rb.getString("SPACE"))
                                 .append(rb.getString("SPACE"));
                         sb.append('|');
                     }
@@ -846,10 +852,14 @@
                                     .append(rb
                                             .getString(".Signature.related.entries."))
                                     .append("\n\n");
-                        } else {
+                        } else if (unsignedEntry) {
                             sb.append('\n').append(tab)
                                     .append(rb.getString(".Unsigned.entries."))
                                     .append("\n\n");
+                        } else {
+                            sb.append('\n').append(tab)
+                                    .append(rb.getString(".Directory.entries."))
+                                    .append("\n\n");
                         }
                     }
 
@@ -924,6 +934,11 @@
                     System.out.println(rb.getString(
                         ".X.not.signed.by.specified.alias.es."));
                 }
+
+                if (hasUnsignedEntry) {
+                    System.out.println(rb.getString(
+                            ".q.unsigned.entry"));
+                }
             }
             if (man == null) {
                 System.out.println();
diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java
index 7158e2f..2b74856 100644
--- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java
+++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -133,6 +133,8 @@
         {"s", "s"},
         {"m", "m"},
         {"k", "k"},
+        {"X", "X"},
+        {"q", "?"},
         {".and.d.more.", "(and %d more)"},
         {".s.signature.was.verified.",
                 "  s = signature was verified "},
@@ -142,9 +144,12 @@
                 "  k = at least one certificate was found in keystore"},
         {".X.not.signed.by.specified.alias.es.",
                 "  X = not signed by specified alias(es)"},
+        {".q.unsigned.entry",
+                "  ? = unsigned entry"},
         {"no.manifest.", "no manifest."},
         {".Signature.related.entries.","(Signature related entries)"},
         {".Unsigned.entries.", "(Unsigned entries)"},
+        {".Directory.entries.", "(Directory entries)"},
         {"jar.is.unsigned",
                 "jar is unsigned."},
         {"jar.treated.unsigned",
diff --git a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java
index 6a35cef..69b45ea 100644
--- a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java
+++ b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6802846 8172529 8227758
+ * @bug 6802846 8172529 8227758 8260960
  * @summary jarsigner needs enhanced cert validation(options)
  * @library /test/lib
  * @run main/timeout=240 ConciseJarsigner
@@ -112,23 +112,26 @@
                 .filter(s -> s.contains(year))
                 .count() == 12);
 
-        // 4 groups: MANIFST, unrelated, signed, unsigned
+        // 5 groups: MANIFEST, signature related entries, directory entries,
+        // signed entries, and unsigned entries.
         Asserts.assertTrue(js("-verify a.jar -verbose:summary")
                 .asLines().stream()
                 .filter(s -> s.contains(year))
-                .count() == 4);
+                .count() == 5);
 
-        // still 4 groups, but MANIFEST group has no other file
+        // still 5 groups, but MANIFEST group and directiry entry group
+        // have no other file
         Asserts.assertTrue(js("-verify a.jar -verbose:summary")
                 .asLines().stream()
                 .filter(s -> s.contains("more)"))
                 .count() == 3);
 
-        // 5 groups: MANIFEST, unrelated, signed by a1/a2, signed by a2, unsigned
+        // 6 groups: MANIFEST, signature related entries, directory entries,
+        // signed entries by a1/a2, signed entries by a2, and unsigned entries.
         Asserts.assertTrue(js("-verify a.jar -verbose:summary -certs")
                 .asLines().stream()
                 .filter(s -> s.contains(year))
-                .count() == 5);
+                .count() == 6);
 
         // 2 for MANIFEST, 2*2 for A1/A2, 2 for A3/A4
         Asserts.assertTrue(js("-verify a.jar -verbose -certs")
@@ -148,7 +151,8 @@
                 .filter(s -> s.contains("[certificate"))
                 .count() == 5);
 
-        // still 5 groups, but MANIFEST group has no other file
+        // still 6 groups, but MANIFEST group and directory entry group
+        // have no other file
         Asserts.assertTrue(js("-verify a.jar -verbose:summary -certs")
                 .asLines().stream()
                 .filter(s -> s.contains("more)"))