@@ -58,14 +58,20 @@ public class DerInputStream {
5858
5959 // The static part
6060 final byte [] data ;
61- final int start ;
62- final int end ;
61+ final int start ; // inclusive
62+ final int end ; // exclusive
6363 final boolean allowBER ;
6464
6565 // The moving part
6666 int pos ;
6767 int mark ;
6868
69+ /**
70+ * Constructs a DerInputStream by assigning all its fields.
71+ *
72+ * No checking on arguments since all callers are internal.
73+ * {@code data} should never be null even if length is 0.
74+ */
6975 public DerInputStream (byte [] data , int start , int length , boolean allowBER ) {
7076 this .data = data ;
7177 this .start = start ;
@@ -75,10 +81,6 @@ public DerInputStream(byte[] data, int start, int length, boolean allowBER) {
7581 this .mark = start ;
7682 }
7783
78- public DerInputStream (DerValue v ) {
79- this (v .buffer , v .start , v .end - v .start , v .allowBER );
80- }
81-
8284 public DerInputStream (byte [] data ) throws IOException {
8385 this (data , 0 , data .length , true );
8486 }
@@ -87,22 +89,34 @@ public DerInputStream(byte[] data, int offset, int len) throws IOException {
8789 this (data , offset , len , true );
8890 }
8991
92+ /**
93+ * Returns the remaining unread bytes, or, all bytes if none read yet.
94+ */
9095 public byte [] toByteArray () {
9196 return Arrays .copyOfRange (data , pos , end );
9297 }
9398
9499 /**
95- * Reads a DerValue from this stream. After the call, the data pointer is right after
96- * this DerValue so that the next call will read the next DerValue.
100+ * Reads a DerValue from this stream. After the call, the data pointer
101+ * is right after this DerValue so that the next call will read the
102+ * next DerValue.
97103 *
98104 * @return the read DerValue.
99- * @throws IOException if a DerValue cannot be constructed starting from this position
100- * because of byte shortage or encoding error.
105+ * @throws IOException if a DerValue cannot be constructed starting from
106+ * this position because of byte shortage or encoding error.
101107 */
102108 public DerValue getDerValue () throws IOException {
103109 DerValue result = new DerValue (
104110 this .data , this .pos , this .end - this .pos , this .allowBER , true );
105- this .pos = result .end ;
111+ if (result .buffer != this .data ) {
112+ // Indefinite length observed. Unused bytes in data are appended
113+ // to the end of return value by DerIndefLenConverter::convertBytes
114+ // and stay inside result.buffer.
115+ int unused = result .buffer .length - result .end ;
116+ this .pos = this .data .length - unused ;
117+ } else {
118+ this .pos = result .end ;
119+ }
106120 return result ;
107121 }
108122
@@ -204,41 +218,35 @@ public int peekByte() throws IOException {
204218 return data [pos ];
205219 }
206220
207- static int getLength (InputStream in ) throws IOException {
208- return getLength (in .read (), in );
209- }
210-
211221 /**
212222 * Get a length from the input stream, allowing for at most 32 bits of
213223 * encoding to be used. (Not the same as getting a tagged integer!)
214224 *
215- * @param lenByte
216- *
217225 * @return the length or -1 if indefinite length found.
218226 * @exception IOException on parsing error or unsupported lengths.
219227 */
220- static int getLength (int lenByte , InputStream in ) throws IOException {
221- int value , tmp ;
228+ static int getLength (InputStream in ) throws IOException {
229+ int lenByte = in . read () ;
222230 if (lenByte == -1 ) {
223231 throw new IOException ("Short read of DER length" );
224232 }
233+ if (lenByte == 0x80 ) {
234+ return -1 ;
235+ }
225236
237+ int value , tmp ;
226238 String mdName = "DerInputStream.getLength(): " ;
227239 tmp = lenByte ;
228240 if ((tmp & 0x080 ) == 0x00 ) { // short form, 1 byte datum
229241 value = tmp ;
230242 } else { // long form or indefinite
231243 tmp &= 0x07f ;
232244
233- /*
234- * NOTE: tmp == 0 indicates indefinite length encoded data.
235- * tmp > 4 indicates more than 4Gb of data.
236- */
237- if (tmp == 0 )
238- return -1 ;
239- if (tmp < 0 || tmp > 4 )
245+ // tmp > 4 indicates more than 4Gb of data.
246+ if (tmp < 0 || tmp > 4 ) {
240247 throw new IOException (mdName + "lengthTag=" + tmp + ", "
241- + ((tmp < 0 ) ? "incorrect DER encoding." : "too big." ));
248+ + ((tmp < 0 ) ? "incorrect DER encoding." : "too big." ));
249+ }
242250
243251 value = 0x0ff & in .read ();
244252 tmp --;
@@ -276,8 +284,10 @@ static int getDefiniteLength(InputStream in) throws IOException {
276284 /**
277285 * Mark the current position in the buffer, so that
278286 * a later call to <code>reset</code> will return here.
287+ * The {@code readAheadLimit} is useless here because
288+ * all data is available and we can go to anywhere at will.
279289 */
280- public void mark (int value ) { mark = pos ; }
290+ public void mark (int readAheadLimit ) { mark = pos ; }
281291
282292 /**
283293 * Return to the position of the last <code>mark</code>
0 commit comments