src/share/classes/org/openjdk/jigsaw/ModuleFile.java

Print this page




 201                     } else {
 202                         throw new IllegalArgumentException("Unknown type: " + type);
 203                     }
 204                 } while (parser.skipToNextStartSection());
 205 
 206                 if (parser.event() != END_FILE)
 207                     throw new IOException("Expected END_FILE");
 208             } finally {
 209                 close();
 210             }
 211         }
 212 
 213         public byte[] getModuleInfoBytes() {
 214             return moduleInfoBytes.clone();
 215         }
 216 
 217         public byte[] getHash() {
 218             return fileHeader.getHash();
 219         }
 220 




 221         public List<byte[]> getCalculatedHashes() {
 222             List<byte[]> hashes = new ArrayList<>();
 223             hashes.add(parser.getHeaderHash());
 224             for (Entry<SectionType,byte[]> entry : parser.getHashes().entrySet()) {
 225                 if (entry.getKey() != SIGNATURE)
 226                     hashes.add(entry.getValue());
 227             }
 228             hashes.add(getHash());
 229 
 230             return hashes;
 231         }
 232 
 233         public boolean hasSignature() {
 234             return moduleSignatureBytes != null;
 235         }
 236 
 237         public SignatureType getSignatureType() {
 238             return moduleSignatureType;
 239         }
 240 


 540     private static short readHashLength(DataInputStream in) throws IOException {
 541         final short hashLength = in.readShort();
 542         ensureNonNegativity(hashLength, "hashLength");
 543 
 544         return hashLength;
 545     }
 546 
 547     private static byte[] readHashBytes(DataInputStream in, short hashLength)
 548         throws IOException
 549     {
 550         final byte[] hash = new byte[hashLength];
 551         in.readFully(hash);
 552 
 553         return hash;
 554     }
 555 
 556     private static byte[] readHash(DataInputStream in) throws IOException {
 557         return readHashBytes(in, readHashLength(in));
 558     }
 559 
 560     private static byte[] readFileHash(DigestInputStream dis)
 561         throws IOException
 562     {
 563         DataInputStream in = new DataInputStream(dis);

 564 
 565         final short hashLength = readHashLength(in);
 566 
 567         // Turn digest computation off before reading the file hash
 568         dis.on(false);
 569         byte[] hash = readHashBytes(in, hashLength);

 570         // Turn digest computation on again afterwards.
 571         dis.on(true);

 572 
 573         return hash;
 574     }
 575 
 576     /**
 577      * <p> A module-file header </p>
 578      */
 579     public final static class ModuleFileHeader {
 580         public static final int LENGTH_WITHOUT_HASH = 30;
 581         public static final int LENGTH =
 582             LENGTH_WITHOUT_HASH + HashType.SHA256.length();
 583 
 584         // Fields are specified as unsigned. Treat signed values as bugs.
 585         private final int magic;                // MAGIC
 586         private final FileConstants.Type type;  // Type.MODULE_FILE
 587         private final short major;              // ModuleFile.MAJOR_VERSION
 588         private final short minor;              // ModuleFile.MINOR_VERSION
 589         private final long csize;               // Size of rest of file, compressed
 590         private final long usize;               // Space required for uncompressed contents
 591                                                 //   (upper private final ound; need not be exact)
 592         private final HashType hashType;        // One of ModuleFile.HashType
 593                                                 //   (applies final o all hashes in this file)
 594         private final byte[] hash;              // Hash of entire file (except this hash
 595                                                 // and the Signature section, if present)

 596 


 597         public HashType getHashType() {
 598             return hashType;
 599         }
 600         
 601         public byte[] getHash() {
 602             return hash.clone();
 603         }
 604 
 605         private byte[] getHashNoClone() {
 606             return hash;
 607         }
 608 
 609         public long getCSize() {
 610             return csize;
 611         }
 612 
 613         public long getUSize() {
 614             return usize;
 615         }
 616 
 617         public ModuleFileHeader(long csize, long usize,
 618                                 HashType hashType, byte[] hash) {








 619             ensureNonNegativity(csize, "csize");
 620             ensureNonNegativity(usize, "usize");
 621 
 622             magic = FileConstants.MAGIC;
 623             type = FileConstants.Type.MODULE_FILE;
 624             major = MAJOR_VERSION;
 625             minor = MINOR_VERSION;
 626 
 627             this.csize = csize;
 628             this.usize = usize;
 629             this.hashType = hashType;
 630             this.hash = hash.clone();








 631         }

 632 














































 633         public void write(final DataOutput out) throws IOException {
 634             out.writeInt(magic);
 635             out.writeShort(type.value());
 636             out.writeShort(major);
 637             out.writeShort(minor);
 638             out.writeLong(csize);
 639             out.writeLong(usize);
 640             out.writeShort(hashType.value());
 641             writeHash(out, hash);


 642         }
 643 
 644         public static ModuleFileHeader read(final DigestInputStream dis)
 645                 throws IOException
 646         {
 647             DataInputStream in = new DataInputStream(dis);
 648 
 649             final int magic = in.readInt();
 650             ensureMatch(magic, FileConstants.MAGIC,
 651                         "FileConstants.MAGIC");
 652 
 653             final short type = in.readShort();
 654             ensureMatch(type, FileConstants.Type.MODULE_FILE.value(),
 655                        "Type.MODULE_FILE");
 656 
 657             final short major = in.readShort();
 658             ensureMatch(major, MAJOR_VERSION,
 659                         "ModuleFile.MAJOR_VERSION");
 660 
 661             final short minor = in.readShort();
 662             ensureMatch(minor, MINOR_VERSION,
 663                         "ModuleFile.MINOR_VERSION");
 664 
 665             final long csize = in.readLong();
 666             final long usize = in.readLong();
 667             final short hashTypeValue = in.readShort();

 668             HashType hashType = null;
 669             try {
 670                 hashType = HashType.valueOf(hashTypeValue);
 671             } catch (IllegalArgumentException x) {
 672                 throw new IOException("Invalid hash type: " + hashTypeValue);
 673             }
 674             final byte[] hash = readFileHash(dis);
 675 
 676             return new ModuleFileHeader(csize, usize, hashType, hash);




 677         }
 678 
 679         @Override
 680         public String toString() {
 681             return "MODULE{csize=" + csize +
 682                    ", hash=" + hashHexString(hash) + "}";
 683         }
 684     }
 685 
 686     /**
 687      * <p> A module-file section header </p>
 688      */
 689     public final static class SectionHeader {
 690         public static final int LENGTH_WITHOUT_HASH = 12;
 691         public static final int LENGTH =
 692             LENGTH_WITHOUT_HASH + HashType.SHA256.length();
 693 
 694         // Fields are specified as unsigned. Treat signed values as bugs.
 695         private final SectionType type;
 696         private final Compressor compressor;




 201                     } else {
 202                         throw new IllegalArgumentException("Unknown type: " + type);
 203                     }
 204                 } while (parser.skipToNextStartSection());
 205 
 206                 if (parser.event() != END_FILE)
 207                     throw new IOException("Expected END_FILE");
 208             } finally {
 209                 close();
 210             }
 211         }
 212 
 213         public byte[] getModuleInfoBytes() {
 214             return moduleInfoBytes.clone();
 215         }
 216 
 217         public byte[] getHash() {
 218             return fileHeader.getHash();
 219         }
 220 
 221         public ModuleArchitecture getArchitecture() {
 222             return fileHeader.getArchitecture();
 223         }
 224 
 225         public List<byte[]> getCalculatedHashes() {
 226             List<byte[]> hashes = new ArrayList<>();
 227             hashes.add(parser.getHeaderHash());
 228             for (Entry<SectionType,byte[]> entry : parser.getHashes().entrySet()) {
 229                 if (entry.getKey() != SIGNATURE)
 230                     hashes.add(entry.getValue());
 231             }
 232             hashes.add(getHash());
 233 
 234             return hashes;
 235         }
 236 
 237         public boolean hasSignature() {
 238             return moduleSignatureBytes != null;
 239         }
 240 
 241         public SignatureType getSignatureType() {
 242             return moduleSignatureType;
 243         }
 244 


 544     private static short readHashLength(DataInputStream in) throws IOException {
 545         final short hashLength = in.readShort();
 546         ensureNonNegativity(hashLength, "hashLength");
 547 
 548         return hashLength;
 549     }
 550 
 551     private static byte[] readHashBytes(DataInputStream in, short hashLength)
 552         throws IOException
 553     {
 554         final byte[] hash = new byte[hashLength];
 555         in.readFully(hash);
 556 
 557         return hash;
 558     }
 559 
 560     private static byte[] readHash(DataInputStream in) throws IOException {
 561         return readHashBytes(in, readHashLength(in));
 562     }
 563 
 564     private static byte[] readFileHash(InputStream in)
 565         throws IOException
 566     {
 567         boolean digestStream = in instanceof DigestInputStream ? true : false;
 568         DataInputStream din = new DataInputStream(in);
 569 
 570         final short hashLength = readHashLength(din);
 571 
 572         // Turn digest computation off before reading the file hash
 573         if (digestStream)
 574             ((DigestInputStream)in).on(false);
 575         byte[] hash = readHashBytes(din, hashLength);
 576         // Turn digest computation on again afterwards.
 577         if (digestStream)
 578             ((DigestInputStream)in).on(true);
 579 
 580         return hash;
 581     }
 582 
 583     /**
 584      * <p> A module-file header </p>
 585      */
 586     public final static class ModuleFileHeader {
 587         private static final int LENGTH_WITHOUT_VARIABLE_FIELDS = 34;


 588 
 589         // Fields are specified as unsigned. Treat signed values as bugs.
 590         private final int magic;                // MAGIC
 591         private final FileConstants.Type type;  // Type.MODULE_FILE
 592         private final short major;              // ModuleFile.MAJOR_VERSION
 593         private final short minor;              // ModuleFile.MINOR_VERSION
 594         private final long csize;               // Size of rest of file, compressed
 595         private final long usize;               // Space required for uncompressed contents
 596                                                 //   (upper private final ound; need not be exact)
 597         private final HashType hashType;        // One of ModuleFile.HashType
 598                                                 //   (applies final o all hashes in this file)
 599         private final byte[] hash;              // Hash of entire file (except this hash
 600                                                 // and the Signature section, if present)
 601         private final ModuleArchitecture modArch;// os/arch, Java-modified UTF-8 pair
 602 
 603         private final int length;
 604 
 605         public HashType getHashType() {
 606             return hashType;
 607         }
 608 
 609         public byte[] getHash() {
 610             return hash.clone();
 611         }
 612 
 613         private byte[] getHashNoClone() {
 614             return hash;
 615         }
 616 
 617         public long getCSize() {
 618             return csize;
 619         }
 620 
 621         public long getUSize() {
 622             return usize;
 623         }
 624 
 625         public ModuleArchitecture getArchitecture() {
 626             return modArch;
 627         }
 628 
 629         public int getLength() {
 630             return length;
 631         }
 632 
 633         private ModuleFileHeader(long csize, long usize, HashType hashType,
 634                                  byte[] hash, ModuleArchitecture modArch) {
 635             ensureNonNegativity(csize, "csize");
 636             ensureNonNegativity(usize, "usize");
 637 
 638             magic = FileConstants.MAGIC;
 639             type = FileConstants.Type.MODULE_FILE;
 640             major = MAJOR_VERSION;
 641             minor = MINOR_VERSION;
 642 
 643             this.csize = csize;
 644             this.usize = usize;
 645             this.hashType = hashType;
 646             this.hash = hash.clone();
 647             this.modArch = modArch;
 648             try {
 649                 length = LENGTH_WITHOUT_VARIABLE_FIELDS
 650                          + hash.length
 651                          + modArch.os().getBytes("UTF-8").length
 652                          + modArch.arch().getBytes("UTF-8").length;
 653             } catch (UnsupportedEncodingException x) {
 654                 throw new InternalError(x);
 655             }
 656         }
 657 
 658         public static Builder newBuilder() {
 659             return new Builder();
 660         }
 661 
 662         public static class Builder {
 663             private long csize;
 664             private long usize;
 665             private ModuleArchitecture architecture = ModuleArchitecture.ANY;
 666             private HashType hashType;
 667             private byte[] hash;
 668 
 669             private Builder() {}
 670 
 671             public Builder setHashType(HashType hashType) {
 672                 this.hashType = hashType;
 673                 return this;
 674             }
 675 
 676             public Builder setHash(byte[] hash) {
 677                 this.hash = hash.clone();
 678                 return this;
 679             }
 680 
 681             public Builder setCSize(long csize) {
 682                 this.csize = csize;
 683                 return this;
 684             }
 685 
 686             public Builder setUSize(long usize) {
 687                 this.usize = usize;
 688                 return this;
 689             }
 690 
 691             public Builder setArchitecture(ModuleArchitecture architecture) {
 692                 this.architecture = architecture;
 693                 return this;
 694             }
 695 
 696             public ModuleFileHeader build() {
 697                 ensureNonNegativity(csize, "csize");
 698                 ensureNonNegativity(usize, "usize");
 699                 return new ModuleFileHeader(csize, usize, hashType, hash,
 700                                             architecture);
 701             }
 702         }
 703 
 704         public void write(final DataOutput out) throws IOException {
 705             out.writeInt(magic);
 706             out.writeShort(type.value());
 707             out.writeShort(major);
 708             out.writeShort(minor);
 709             out.writeLong(csize);
 710             out.writeLong(usize);
 711             out.writeShort(hashType.value());
 712             writeHash(out, hash);
 713             out.writeUTF(modArch.os());
 714             out.writeUTF(modArch.arch());
 715         }
 716 
 717         public static ModuleFileHeader read(final InputStream in)
 718             throws IOException
 719         {
 720             DataInputStream din = new DataInputStream(in);
 721 
 722             final int magic = din.readInt();
 723             ensureMatch(magic, FileConstants.MAGIC,
 724                         "FileConstants.MAGIC");
 725 
 726             final short type = din.readShort();
 727             ensureMatch(type, FileConstants.Type.MODULE_FILE.value(),
 728                        "Type.MODULE_FILE");
 729 
 730             final short major = din.readShort();
 731             ensureMatch(major, MAJOR_VERSION,
 732                         "ModuleFile.MAJOR_VERSION");
 733 
 734             final short minor = din.readShort();
 735             ensureMatch(minor, MINOR_VERSION,
 736                         "ModuleFile.MINOR_VERSION");
 737 
 738             final long csize = din.readLong();
 739             final long usize = din.readLong();
 740 
 741             final short hashTypeValue = din.readShort();
 742             HashType hashType = null;
 743             try {
 744                 hashType = HashType.valueOf(hashTypeValue);
 745             } catch (IllegalArgumentException x) {
 746                 throw new IOException("Invalid hash type: " + hashTypeValue);
 747             }
 748             final byte[] hash = readFileHash(in);
 749 
 750             final String os = din.readUTF();
 751             final String arch = din.readUTF();
 752             final ModuleArchitecture architecture = ModuleArchitecture.create(os, arch);
 753 
 754             return new ModuleFileHeader(csize, usize, hashType, hash, architecture);
 755         }
 756 
 757         @Override
 758         public String toString() {
 759             return "MODULE{csize=" + csize +
 760                    ", hash=" + hashHexString(hash) + "}";
 761         }
 762     }
 763 
 764     /**
 765      * <p> A module-file section header </p>
 766      */
 767     public final static class SectionHeader {
 768         public static final int LENGTH_WITHOUT_HASH = 12;
 769         public static final int LENGTH =
 770             LENGTH_WITHOUT_HASH + HashType.SHA256.length();
 771 
 772         // Fields are specified as unsigned. Treat signed values as bugs.
 773         private final SectionType type;
 774         private final Compressor compressor;