eclipse-ee4j / jaxb-fi

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Decoder.java fails to read initial-vocabulary

Tomas-Kraus opened this issue · comments

The FastInfoset Decoder.java fails to read initial-vocabulary.
All problems are listed below:


1. Wrong Decoding of Number of Items in the sequence:
Current:

private int decodeNumberOfItemsOfSequence() throws IOException {
final int b = read();
if (b < 128)

{ return b; }

else

{ return ((b & 0x0F) << 16) | (read() << 8) | read(); }

}

Should be:

private int decodeNumberOfItemsOfSequence() throws IOException {
final int b = read();
if (b < 128)

{ return b + 1; }

else

{ return (((b & 0x0F) << 16) | (read() << 8) | read()) + 129; }

}

Explanation:

C.21 Encoding of the length of a sequence-of type
C.21.1 This subclause is invoked to encode the length of a sequence-of type that
is encoded with a length field
preceding the items of the sequence-of type.
NOTE – This encoding always starts on the first bit of an octet and ends on the
eighth bit of the same or another octet.
C.21.2 If the value is in the range 1 to 128, then the bit '0' is appended to
the bit stream, and the value, minus the
lower bound of the range, is encoded as an unsigned integer in a field of seven
bits and appended.

  1. Decoding lenght of sequence in the range between 1 and 128 we should do the
    following:
  2. example value in the stream x = 50(read from 7 bits taken from a one call to
    read())
  3. should be decoded as 50 + 1(the lower bound of the range) = 51

C.21.3 If the value is in the range 129 to 2 power 20, the bit '1' and the three
bits '000' (padding) are appended to the bit
stream, and the value, minus the lower bound of the range, is encoded as an
unsigned integer in a field of twenty bits
and appended.

  1. Decoding lenght of sequence in the range between 129 and 2 power 20 we should
    do the following:
  2. example value in the stream x = 200(read from twenty bits taken from the three
    calls to read())
  3. should be decoded as 200 + 129(lower bound of the range) = 329

2. Wrong invocation of the decodeNumberOfItemsOfSequence() method
Example (one of many invocations of decodeNumberOfItemsOfSequence() method in
Decoder.java):
Current:

private void decodeTableItems(StringArray array) throws FastInfosetException,
IOException {
for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++)

{ array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String()); }

}

Should be:

private void decodeTableItems(StringArray array) throws FastInfosetException,
IOException {
int noOfNamespaces = decodeNumberOfItemsOfSequence();
for (int i = 0; i < noOfNamespaces; i++)

{ array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String()); }

}

This bug occurs in every place in Decoder.java where
decodeNumberOfItemsOfSequence() method is invoked.
The fix is about invoking decodeNumberOfItemsOfSequence() only once as described
in the example above.


3. Wrong decoding of integer index on second bit in
decodeIntegerIndexOnSecondBit() method:

Explanation:

C.13.4 If the alternative string-index is present, then the bit '1'
(discriminant) is appended to the bit stream, and
the string-index is encoded as described in C.25
C.16.5 If the optional component prefix-string-index is present, then the bit
'0' (padding) is appended to the bit
stream, and the component is encoded as described in C.25.
C.16.6 If the optional component namespace-name-string-index is present, then
the bit '0' (padding) is appended
to the bit stream, and the component is encoded as described in C.25.
C.16.7 The bit '0' (padding) is appended to the bit stream, and the component
local-name-string-index is
encoded as described in C.25.

  1. The function 'decodeIntegerIndexOnSecondBit()' implements correctly point
    C.13.4, when the octed starts with '1'
  2. but it fails when the octet starts with '0' !

Current:
protected final int decodeIntegerIndexOnSecondBit() throws
FastInfosetException, IOException {
final int b = read();
switch(DecoderStateTables.ISTRING[b])

{ .... }

}
Should be:

protected final int decodeIntegerIndexOnSecondBit() throws
FastInfosetException, IOException {
final int b = read() | 0x80;
switch(DecoderStateTables.ISTRING[b])

{ .... }

}


4. Wrong namespaceName value assignments in
Decoder.decodeTableItems(QualifiedNameArray array, boolean isAttribute).

Current:

String namespaceName = "";
int namespaceNameIndex = -1;
if ((b & EncodingConstants.NAME_SURROGATE_NAME_FLAG) > 0) {
namespaceNameIndex = decodeIntegerIndexOnSecondBit();
namespaceName = _v.prefix.get(prefixIndex);
}

Should be:

String namespaceName = "";
int namespaceNameIndex = -1;
if ((b & EncodingConstants.NAME_SURROGATE_NAME_FLAG) > 0) {
namespaceNameIndex = decodeIntegerIndexOnSecondBit();
namespaceName = _v.namespaceName.get(namespaceNameIndex);
}

The change: 'namespaceName = _v.prefix.get(prefixIndex);' changed to
'namespaceName = _v.namespaceName.get(namespaceNameIndex);'

Environment

Operating System: All
Platform: All

Affected Versions

[current]

@glassfishrobot Commented
Reported by agladkowski

@glassfishrobot Commented
agladkowski said:
Created an attachment (id=3)
Decoder.patch

@glassfishrobot Commented
agladkowski said:
I am attaching Decoder.patch file with fixes for all the listed bugs.

@glassfishrobot Commented
oleksiys said:
fixed.
thanks a lot, Andrzej!

Date: 2009-11-12 10:48:15+0000
Modified:
fi/FastInfoset/src/com/sun/xml/fastinfoset/Decoder.java

Log:
fix issue #29
https://fi.dev.java.net/issues/show_bug.cgi?id=29
"Decoder.java fails to read initial-vocabulary"
fix is provided by Andrzej Gladkowski

@glassfishrobot Commented
File: Decoder.patch
Attached By: agladkowski

@glassfishrobot Commented
Was assigned to oleksiys

@glassfishrobot Commented
This issue was imported from java.net JIRA FI-29

@glassfishrobot Commented
Marked as fixed on Wednesday, November 11th 2009, 6:50:19 pm