1 package org.bouncycastle.asn1; 2 3 import java.io.EOFException; 4 import java.io.IOException; 5 import java.io.InputStream; 6 7 class IndefiniteLengthInputStream 8 extends LimitedInputStream 9 { 10 private int _b1; 11 private int _b2; 12 private boolean _eofReached = false; 13 private boolean _eofOn00 = true; 14 15 IndefiniteLengthInputStream( 16 InputStream in, 17 int limit) 18 throws IOException 19 { 20 super(in, limit); 21 22 _b1 = in.read(); 23 _b2 = in.read(); 24 25 if (_b2 < 0) 26 { 27 // Corrupted stream 28 throw new EOFException(); 29 } 30 31 checkForEof(); 32 } 33 34 void setEofOn00( 35 boolean eofOn00) 36 { 37 _eofOn00 = eofOn00; 38 checkForEof(); 39 } 40 41 private boolean checkForEof() 42 { 43 if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00)) 44 { 45 _eofReached = true; 46 setParentEofDetect(true); 47 } 48 return _eofReached; 49 } 50 51 public int read(byte[] b, int off, int len) 52 throws IOException 53 { 54 // Only use this optimisation if we aren't checking for 00 55 if (_eofOn00 || len < 3) 56 { 57 return super.read(b, off, len); 58 } 59 60 if (_eofReached) 61 { 62 return -1; 63 } 64 65 int numRead = _in.read(b, off + 2, len - 2); 66 67 if (numRead < 0) 68 { 69 // Corrupted stream 70 throw new EOFException(); 71 } 72 73 b[off] = (byte)_b1; 74 b[off + 1] = (byte)_b2; 75 76 _b1 = _in.read(); 77 _b2 = _in.read(); 78 79 if (_b2 < 0) 80 { 81 // Corrupted stream 82 throw new EOFException(); 83 } 84 85 return numRead + 2; 86 } 87 88 public int read() 89 throws IOException 90 { 91 if (checkForEof()) 92 { 93 return -1; 94 } 95 96 int b = _in.read(); 97 98 if (b < 0) 99 { 100 // Corrupted stream 101 throw new EOFException(); 102 } 103 104 int v = _b1; 105 106 _b1 = _b2; 107 _b2 = b; 108 109 return v; 110 } 111 } 112