History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/jndi/ldap/BerDecoder.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/jndi/ldap/BerDecoder.java+334−0
@@ -0,0 +1,334 @@
1+/*
2+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.jndi.ldap;
27+
28+import java.io.UnsupportedEncodingException;
29+
30+/**
31+ * A BER decoder. Contains methods to parse a BER buffer.
32+ *
33+ * @author Jagane Sundar
34+ * @author Vincent Ryan
35+ */
36+public final class BerDecoder extends Ber {
37+
38+ private int origOffset; // The start point in buf to decode
39+
40+ /**
41+ * Creates a BER decoder that reads bytes from the specified buffer.
42+ */
43+ public BerDecoder(byte buf[], int offset, int bufsize) {
44+
45+ this.buf = buf;
46+ this.bufsize = bufsize;
47+ this.origOffset = offset;
48+
49+ reset();
50+ }
51+
52+ /**
53+ * Resets this decode to start parsing from the initial offset
54+ * (ie., same state as after calling the constructor).
55+ */
56+ public void reset() {
57+ offset = origOffset;
58+ }
59+
60+ /**
61+ * Returns the current parse position.
62+ * It points to the byte that will be parsed next.
63+ * Useful for parsing sequences.
64+ */
65+ public int getParsePosition() {
66+ return offset;
67+ }
68+
69+ /**
70+ * Parses a possibly variable length field.
71+ */
72+ public int parseLength() throws DecodeException {
73+
74+ int lengthbyte = parseByte();
75+
76+ if ((lengthbyte & 0x80) == 0x80) {
77+
78+ lengthbyte &= 0x7f;
79+
80+ if (lengthbyte == 0) {
81+ throw new DecodeException(
82+ "Indefinite length not supported");
83+ }
84+
85+ if (lengthbyte > 4) {
86+ throw new DecodeException("encoding too long");
87+ }
88+
89+ if (bufsize - offset < lengthbyte) {
90+ throw new DecodeException("Insufficient data");
91+ }
92+
93+ int retval = 0;
94+
95+ for( int i = 0; i < lengthbyte; i++) {
96+ retval = (retval << 8) + (buf[offset++] & 0xff);
97+ }
98+ return retval;
99+ } else {
100+ return lengthbyte;
101+ }
102+ }
103+
104+ /**
105+ * Parses the next sequence in this BER buffer.
106+ * @param rlen An array for returning size of the sequence in bytes. If null,
107+ * the size is not returned.
108+ * @return The sequence's tag.
109+ */
110+ public int parseSeq(int rlen[]) throws DecodeException {
111+
112+ int seq = parseByte();
113+ int len = parseLength();
114+ if (rlen != null) {
115+ rlen[0] = len;
116+ }
117+ return seq;
118+ }
119+
120+ /**
121+ * Used to skip bytes. Usually used when trying to recover from parse error.
122+ * Don't need to be public right now?
123+ * @param i The number of bytes to skip
124+ */
125+ void seek(int i) throws DecodeException {
126+ if (offset + i > bufsize || offset + i < 0) {
127+ throw new DecodeException("array index out of bounds");
128+ }
129+ offset += i;
130+ }
131+
132+ /**
133+ * Parses the next byte in this BER buffer.
134+ * @return The byte parsed.
135+ */
136+ public int parseByte() throws DecodeException {
137+ if (bufsize - offset < 1) {
138+ throw new DecodeException("Insufficient data");
139+ }
140+ return buf[offset++] & 0xff;
141+ }
142+
143+
144+ /**
145+ * Returns the next byte in this BER buffer without consuming it.
146+ * @return The next byte.
147+ */
148+ public int peekByte() throws DecodeException {
149+ if (bufsize - offset < 1) {
150+ throw new DecodeException("Insufficient data");
151+ }
152+ return buf[offset] & 0xff;
153+ }
154+
155+ /**
156+ * Parses an ASN_BOOLEAN tagged integer from this BER buffer.
157+ * @return true if the tagged integer is 0; false otherwise.
158+ */
159+ public boolean parseBoolean() throws DecodeException {
160+ return ((parseIntWithTag(ASN_BOOLEAN) == 0x00) ? false : true);
161+ }
162+
163+ /**
164+ * Parses an ASN_ENUMERATED tagged integer from this BER buffer.
165+ * @return The tag of enumeration.
166+ */
167+ public int parseEnumeration() throws DecodeException {
168+ return parseIntWithTag(ASN_ENUMERATED);
169+ }
170+
171+ /**
172+ * Parses an ASN_INTEGER tagged integer from this BER buffer.
173+ * @return The value of the integer.
174+ */
175+ public int parseInt() throws DecodeException {
176+ return parseIntWithTag(ASN_INTEGER);
177+ }
178+
179+ /**
180+ * Parses an integer that's preceded by a tag.
181+ *<blockquote><pre>
182+ * BER integer ::= tag length byte {byte}*
183+ *</pre></blockquote>
184+ */
185+ private int parseIntWithTag(int tag) throws DecodeException {
186+
187+
188+ if (parseByte() != tag) {
189+ throw new DecodeException("Encountered ASN.1 tag " +
190+ Integer.toString(buf[offset - 1] & 0xff) +
191+ " (expected tag " + Integer.toString(tag) + ")");
192+ }
193+
194+ int len = parseLength();
195+
196+ if (len > 4) {
197+ throw new DecodeException("INTEGER too long");
198+ } else if (len > bufsize - offset) {
199+ throw new DecodeException("Insufficient data");
200+ }
201+
202+ byte fb = buf[offset++];
203+ int value = 0;
204+
205+ value = fb & 0x7F;
206+ for( int i = 1 /* first byte already read */ ; i < len; i++) {
207+ value <<= 8;
208+ value |= (buf[offset++] & 0xff);
209+ }
210+
211+ if ((fb & 0x80) == 0x80) {
212+ value = -value;
213+ }
214+
215+ return value;
216+ }
217+
218+ /**
219+ * Parses a string.
220+ */
221+ public String parseString(boolean decodeUTF8) throws DecodeException {
222+ return parseStringWithTag(ASN_SIMPLE_STRING, decodeUTF8, null);
223+ }
224+
225+ /**
226+ * Parses a string of a given tag from this BER buffer.
227+ *<blockquote><pre>
228+ *BER simple string ::= tag length {byte}*
229+ *</pre></blockquote>
230+ * @param rlen An array for holding the relative parsed offset; if null
231+ * offset not set.
232+ * @param decodeUTF8 If true, use UTF-8 when decoding the string; otherwise
233+ * use ISO-Latin-1 (8859_1). Use true for LDAPv3; false for LDAPv2.
234+ * @param tag The tag that precedes the string.
235+ * @return The non-null parsed string.
236+ */
237+ public String parseStringWithTag(int tag, boolean decodeUTF8, int rlen[])
238+ throws DecodeException {
239+
240+ int st;
241+ int origOffset = offset;
242+
243+ if ((st = parseByte()) != tag) {
244+ throw new DecodeException("Encountered ASN.1 tag " +
245+ Integer.toString((byte)st) + " (expected tag " + tag + ")");
246+ }
247+
248+ int len = parseLength();
249+
250+ if (len > bufsize - offset) {
251+ throw new DecodeException("Insufficient data");
252+ }
253+
254+ String retstr;
255+ if (len == 0) {
256+ retstr = "";
257+ } else {
258+ byte[] buf2 = new byte[len];
259+
260+ System.arraycopy(buf, offset, buf2, 0, len);
261+ if (decodeUTF8) {
262+ try {
263+ retstr = new String(buf2, "UTF8");
264+ } catch (UnsupportedEncodingException e) {
265+ throw new DecodeException("UTF8 not available on platform");
266+ }
267+ } else {
268+ try {
269+ retstr = new String(buf2, "8859_1");
270+ } catch (UnsupportedEncodingException e) {
271+ throw new DecodeException("8859_1 not available on platform");
272+ }
273+ }
274+ offset += len;
275+ }
276+
277+ if (rlen != null) {
278+ rlen[0] = offset - origOffset;
279+ }
280+
281+ return retstr;
282+ }
283+
284+ /**
285+ * Parses an octet string of a given type(tag) from this BER buffer.
286+ * <blockquote><pre>
287+ * BER Binary Data of type "tag" ::= tag length {byte}*
288+ *</pre></blockquote>
289+ *
290+ * @param tag The tag to look for.
291+ * @param rlen An array for returning the relative parsed position. If null,
292+ * the relative parsed position is not returned.
293+ * @return A non-null array containing the octet string.
294+ * @throws DecodeException If the next byte in the BER buffer is not
295+ * <tt>tag</tt>, or if length specified in the BER buffer exceeds the
296+ * number of bytes left in the buffer.
297+ */
298+ public byte[] parseOctetString(int tag, int rlen[]) throws DecodeException {
299+
300+ int origOffset = offset;
301+ int st;
302+ if ((st = parseByte()) != tag) {
303+
304+ throw new DecodeException("Encountered ASN.1 tag " +
305+ Integer.toString(st) +
306+ " (expected tag " + Integer.toString(tag) + ")");
307+ }
308+
309+ int len = parseLength();
310+
311+ if (len > bufsize - offset) {
312+ throw new DecodeException("Insufficient data");
313+ }
314+
315+ byte retarr[] = new byte[len];
316+ if (len > 0) {
317+ System.arraycopy(buf, offset, retarr, 0, len);
318+ offset += len;
319+ }
320+
321+ if (rlen != null) {
322+ rlen[0] = offset - origOffset;
323+ }
324+
325+ return retarr;
326+ }
327+
328+ /**
329+ * Returns the number of unparsed bytes in this BER buffer.
330+ */
331+ public int bytesLeft() {
332+ return bufsize - offset;
333+ }
334+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t