source: josm/trunk/src/org/tukaani/xz/index/IndexHash.java@ 15731

Last change on this file since 15731 was 13350, checked in by stoecker, 7 years ago

see #15816 - add XZ support

File size: 3.6 KB
Line 
1/*
2 * IndexHash
3 *
4 * Author: Lasse Collin <lasse.collin@tukaani.org>
5 *
6 * This file has been put into the public domain.
7 * You can do whatever you want with this file.
8 */
9
10package org.tukaani.xz.index;
11
12import java.io.InputStream;
13import java.io.DataInputStream;
14import java.io.IOException;
15import java.nio.ByteBuffer;
16import java.util.Arrays;
17import java.util.zip.CheckedInputStream;
18import org.tukaani.xz.common.DecoderUtil;
19import org.tukaani.xz.XZIOException;
20import org.tukaani.xz.CorruptedInputException;
21
22public class IndexHash extends IndexBase {
23 private org.tukaani.xz.check.Check hash;
24
25 public IndexHash() {
26 super(new CorruptedInputException());
27
28 try {
29 hash = new org.tukaani.xz.check.SHA256();
30 } catch (java.security.NoSuchAlgorithmException e) {
31 hash = new org.tukaani.xz.check.CRC32();
32 }
33 }
34
35 public void add(long unpaddedSize, long uncompressedSize)
36 throws XZIOException {
37 super.add(unpaddedSize, uncompressedSize);
38
39 ByteBuffer buf = ByteBuffer.allocate(2 * 8);
40 buf.putLong(unpaddedSize);
41 buf.putLong(uncompressedSize);
42 hash.update(buf.array());
43 }
44
45 public void validate(InputStream in) throws IOException {
46 // Index Indicator (0x00) has already been read by BlockInputStream
47 // so add 0x00 to the CRC32 here.
48 java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
49 crc32.update('\0');
50 CheckedInputStream inChecked = new CheckedInputStream(in, crc32);
51
52 // Get and validate the Number of Records field.
53 // If Block Header Size was corrupt and became Index Indicator,
54 // this error would actually be about corrupt Block Header.
55 // This is why the error message mentions both possibilities.
56 long storedRecordCount = DecoderUtil.decodeVLI(inChecked);
57 if (storedRecordCount != recordCount)
58 throw new CorruptedInputException(
59 "XZ Block Header or the start of XZ Index is corrupt");
60
61 // Decode and hash the Index field and compare it to
62 // the hash value calculated from the decoded Blocks.
63 IndexHash stored = new IndexHash();
64 for (long i = 0; i < recordCount; ++i) {
65 long unpaddedSize = DecoderUtil.decodeVLI(inChecked);
66 long uncompressedSize = DecoderUtil.decodeVLI(inChecked);
67
68 try {
69 stored.add(unpaddedSize, uncompressedSize);
70 } catch (XZIOException e) {
71 throw new CorruptedInputException("XZ Index is corrupt");
72 }
73
74 if (stored.blocksSum > blocksSum
75 || stored.uncompressedSum > uncompressedSum
76 || stored.indexListSize > indexListSize)
77 throw new CorruptedInputException("XZ Index is corrupt");
78 }
79
80 if (stored.blocksSum != blocksSum
81 || stored.uncompressedSum != uncompressedSum
82 || stored.indexListSize != indexListSize
83 || !Arrays.equals(stored.hash.finish(), hash.finish()))
84 throw new CorruptedInputException("XZ Index is corrupt");
85
86 // Index Padding
87 DataInputStream inData = new DataInputStream(inChecked);
88 for (int i = getIndexPaddingSize(); i > 0; --i)
89 if (inData.readUnsignedByte() != 0x00)
90 throw new CorruptedInputException("XZ Index is corrupt");
91
92 // CRC32
93 long value = crc32.getValue();
94 for (int i = 0; i < 4; ++i)
95 if (((value >>> (i * 8)) & 0xFF) != inData.readUnsignedByte())
96 throw new CorruptedInputException("XZ Index is corrupt");
97 }
98}
Note: See TracBrowser for help on using the repository browser.