8038043: Xerces Update: XInclude update
Reviewed-by: joehw
This commit is contained in:
parent
4932677ba4
commit
efeaca8cda
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
package com.sun.org.apache.xerces.internal.impl;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
|
||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||
import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl;
|
||||
@ -45,6 +46,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
|
||||
import com.sun.xml.internal.stream.XMLBufferListener;
|
||||
import com.sun.xml.internal.stream.XMLEntityStorage;
|
||||
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
||||
import java.io.CharConversionException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import javax.xml.XMLConstants;
|
||||
@ -3075,6 +3077,20 @@ public class XMLDocumentFragmentScannerImpl
|
||||
|
||||
}//switch
|
||||
}
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
}
|
||||
catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
}
|
||||
// premature end of file
|
||||
catch (EOFException e) {
|
||||
endOfFileHook(e);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -22,6 +22,8 @@
|
||||
package com.sun.org.apache.xerces.internal.impl;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
|
||||
import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
|
||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||
import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
|
||||
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLChar;
|
||||
@ -38,6 +40,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
|
||||
import com.sun.xml.internal.stream.Entity;
|
||||
import com.sun.xml.internal.stream.StaxXMLInputSource;
|
||||
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
||||
import java.io.CharConversionException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
@ -758,7 +761,19 @@ public class XMLDocumentScannerImpl
|
||||
return XMLEvent.START_DOCUMENT;
|
||||
|
||||
}
|
||||
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
} catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
}
|
||||
// premature end of file
|
||||
catch (EOFException e) {
|
||||
reportFatalError("PrematureEOF", null);
|
||||
@ -980,6 +995,19 @@ public class XMLDocumentScannerImpl
|
||||
*/
|
||||
}
|
||||
}
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
} catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
}
|
||||
// premature end of file
|
||||
catch (EOFException e) {
|
||||
reportFatalError("PrematureEOF", null);
|
||||
@ -1152,7 +1180,19 @@ public class XMLDocumentScannerImpl
|
||||
}
|
||||
} while (complete || again);
|
||||
}
|
||||
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return false;
|
||||
} catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return false;
|
||||
}
|
||||
// premature end of file
|
||||
catch (EOFException e) {
|
||||
e.printStackTrace();
|
||||
@ -1416,7 +1456,18 @@ public class XMLDocumentScannerImpl
|
||||
}
|
||||
default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
|
||||
}//switch
|
||||
|
||||
// encoding errors
|
||||
} catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
} catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
return -1;
|
||||
} catch (EOFException e) {
|
||||
// NOTE: This is the only place we're allowed to reach
|
||||
// the real end of the document stream. Unless the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -20,9 +20,11 @@
|
||||
|
||||
package com.sun.org.apache.xerces.internal.impl;
|
||||
|
||||
import java.io.CharConversionException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException;
|
||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||
import com.sun.org.apache.xerces.internal.util.SymbolTable;
|
||||
import com.sun.org.apache.xerces.internal.xni.XMLString;
|
||||
@ -196,7 +198,21 @@ public class XMLVersionDetector {
|
||||
return Constants.XML_VERSION_1_0;
|
||||
// premature end of file
|
||||
}
|
||||
catch (EOFException e) {
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException e) {
|
||||
fErrorReporter.reportError(e.getDomain(), e.getKey(),
|
||||
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
scanner.detectingVersion = false;
|
||||
return Constants.XML_VERSION_1_0;
|
||||
} catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure",
|
||||
null,
|
||||
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
scanner.detectingVersion = false;
|
||||
return Constants.XML_VERSION_1_0;
|
||||
} catch (EOFException e) {
|
||||
fErrorReporter.reportError(
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"PrematureEOF",
|
||||
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.sun.org.apache.xerces.internal.impl.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Reader for the ISO-8859-1 encoding.</p>
|
||||
*
|
||||
* @xerces.internal
|
||||
*
|
||||
* @author Michael Glavassevich, IBM
|
||||
*
|
||||
* @version $Id: Latin1Reader.java 718095 2008-11-16 20:00:14Z mrglavas $
|
||||
*/
|
||||
public final class Latin1Reader
|
||||
extends Reader {
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
/**
|
||||
* Default byte buffer size (2048).
|
||||
*/
|
||||
public static final int DEFAULT_BUFFER_SIZE = 2048;
|
||||
|
||||
//
|
||||
// Data
|
||||
//
|
||||
/**
|
||||
* Input stream.
|
||||
*/
|
||||
protected final InputStream fInputStream;
|
||||
|
||||
/**
|
||||
* Byte buffer.
|
||||
*/
|
||||
protected final byte[] fBuffer;
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
/**
|
||||
* Constructs an ISO-8859-1 reader from the specified input stream using the
|
||||
* default buffer size.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
*/
|
||||
public Latin1Reader(InputStream inputStream) {
|
||||
this(inputStream, DEFAULT_BUFFER_SIZE);
|
||||
} // <init>(InputStream)
|
||||
|
||||
/**
|
||||
* Constructs an ISO-8859-1 reader from the specified input stream and
|
||||
* buffer size.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param size The initial buffer size.
|
||||
*/
|
||||
public Latin1Reader(InputStream inputStream, int size) {
|
||||
this(inputStream, new byte[size]);
|
||||
} // <init>(InputStream, int)
|
||||
|
||||
/**
|
||||
* Constructs an ISO-8859-1 reader from the specified input stream and
|
||||
* buffer.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param buffer The byte buffer.
|
||||
*/
|
||||
public Latin1Reader(InputStream inputStream, byte[] buffer) {
|
||||
fInputStream = inputStream;
|
||||
fBuffer = buffer;
|
||||
} // <init>(InputStream, byte[])
|
||||
|
||||
//
|
||||
// Reader methods
|
||||
//
|
||||
/**
|
||||
* Read a single character. This method will block until a character is
|
||||
* available, an I/O error occurs, or the end of the stream is reached.
|
||||
*
|
||||
* <p>
|
||||
* Subclasses that intend to support efficient single-character input should
|
||||
* override this method.
|
||||
*
|
||||
* @return The character read, as an integer in the range 0 to 255
|
||||
* (<tt>0x00-0xff</tt>), or -1 if the end of the stream has been reached
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
return fInputStream.read();
|
||||
} // read():int
|
||||
|
||||
/**
|
||||
* Read characters into a portion of an array. This method will block until
|
||||
* some input is available, an I/O error occurs, or the end of the stream is
|
||||
* reached.
|
||||
*
|
||||
* @param ch Destination buffer
|
||||
* @param offset Offset at which to start storing characters
|
||||
* @param length Maximum number of characters to read
|
||||
*
|
||||
* @return The number of characters read, or -1 if the end of the stream has
|
||||
* been reached
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public int read(char ch[], int offset, int length) throws IOException {
|
||||
if (length > fBuffer.length) {
|
||||
length = fBuffer.length;
|
||||
}
|
||||
int count = fInputStream.read(fBuffer, 0, length);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ch[offset + i] = (char) (fBuffer[i] & 0xff);
|
||||
}
|
||||
return count;
|
||||
} // read(char[],int,int)
|
||||
|
||||
/**
|
||||
* Skip characters. This method will block until some characters are
|
||||
* available, an I/O error occurs, or the end of the stream is reached.
|
||||
*
|
||||
* @param n The number of characters to skip
|
||||
*
|
||||
* @return The number of characters actually skipped
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public long skip(long n) throws IOException {
|
||||
return fInputStream.skip(n);
|
||||
} // skip(long):long
|
||||
|
||||
/**
|
||||
* Tell whether this stream is ready to be read.
|
||||
*
|
||||
* @return True if the next read() is guaranteed not to block for input,
|
||||
* false otherwise. Note that returning false does not guarantee that the
|
||||
* next read will block.
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public boolean ready() throws IOException {
|
||||
return false;
|
||||
} // ready()
|
||||
|
||||
/**
|
||||
* Tell whether this stream supports the mark() operation.
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return fInputStream.markSupported();
|
||||
} // markSupported()
|
||||
|
||||
/**
|
||||
* Mark the present position in the stream. Subsequent calls to reset() will
|
||||
* attempt to reposition the stream to this point. Not all character-input
|
||||
* streams support the mark() operation.
|
||||
*
|
||||
* @param readAheadLimit Limit on the number of characters that may be read
|
||||
* while still preserving the mark. After reading this many characters,
|
||||
* attempting to reset the stream may fail.
|
||||
*
|
||||
* @exception IOException If the stream does not support mark(), or if some
|
||||
* other I/O error occurs
|
||||
*/
|
||||
public void mark(int readAheadLimit) throws IOException {
|
||||
fInputStream.mark(readAheadLimit);
|
||||
} // mark(int)
|
||||
|
||||
/**
|
||||
* Reset the stream. If the stream has been marked, then attempt to
|
||||
* reposition it at the mark. If the stream has not been marked, then
|
||||
* attempt to reset it in some way appropriate to the particular stream, for
|
||||
* example by repositioning it to its starting point. Not all
|
||||
* character-input streams support the reset() operation, and some support
|
||||
* reset() without supporting mark().
|
||||
*
|
||||
* @exception IOException If the stream has not been marked, or if the mark
|
||||
* has been invalidated, or if the stream does not support reset(), or if
|
||||
* some other I/O error occurs
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
fInputStream.reset();
|
||||
} // reset()
|
||||
|
||||
/**
|
||||
* Close the stream. Once a stream has been closed, further read(), ready(),
|
||||
* mark(), or reset() invocations will throw an IOException. Closing a
|
||||
* previously-closed stream, however, has no effect.
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
fInputStream.close();
|
||||
} // close()
|
||||
|
||||
} // class Latin1Reader
|
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.sun.org.apache.xerces.internal.impl.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||
import com.sun.org.apache.xerces.internal.util.MessageFormatter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A UTF-16 reader. Can also be used for UCS-2 (i.e. ISO-10646-UCS-2).</p>
|
||||
*
|
||||
* @xerces.internal
|
||||
*
|
||||
* @author Michael Glavassevich, IBM
|
||||
*
|
||||
* @version $Id: UTF16Reader.java 718095 2008-11-16 20:00:14Z mrglavas $
|
||||
*/
|
||||
public final class UTF16Reader
|
||||
extends Reader {
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
/**
|
||||
* Default byte buffer size (4096).
|
||||
*/
|
||||
public static final int DEFAULT_BUFFER_SIZE = 4096;
|
||||
|
||||
//
|
||||
// Data
|
||||
//
|
||||
/**
|
||||
* Input stream.
|
||||
*/
|
||||
protected final InputStream fInputStream;
|
||||
|
||||
/**
|
||||
* Byte buffer.
|
||||
*/
|
||||
protected final byte[] fBuffer;
|
||||
|
||||
/**
|
||||
* Endianness.
|
||||
*/
|
||||
protected final boolean fIsBigEndian;
|
||||
|
||||
// message formatter; used to produce localized exception messages
|
||||
private final MessageFormatter fFormatter;
|
||||
|
||||
// Locale to use for messages
|
||||
private final Locale fLocale;
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
/**
|
||||
* Constructs a UTF-16 reader from the specified input stream using the
|
||||
* default buffer size. Primarily for testing.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param isBigEndian The byte order.
|
||||
*/
|
||||
public UTF16Reader(InputStream inputStream, boolean isBigEndian) {
|
||||
this(inputStream, DEFAULT_BUFFER_SIZE, isBigEndian,
|
||||
new XMLMessageFormatter(), Locale.getDefault());
|
||||
} // <init>(InputStream, boolean)
|
||||
|
||||
/**
|
||||
* Constructs a UTF-16 reader from the specified input stream using the
|
||||
* default buffer size and the given MessageFormatter.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param isBigEndian The byte order.
|
||||
*/
|
||||
public UTF16Reader(InputStream inputStream, boolean isBigEndian,
|
||||
MessageFormatter messageFormatter, Locale locale) {
|
||||
this(inputStream, DEFAULT_BUFFER_SIZE, isBigEndian, messageFormatter, locale);
|
||||
} // <init>(InputStream, boolean, MessageFormatter, Locale)
|
||||
|
||||
/**
|
||||
* Constructs a UTF-16 reader from the specified input stream and buffer
|
||||
* size and given MessageFormatter.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param size The initial buffer size.
|
||||
* @param isBigEndian The byte order.
|
||||
* @param messageFormatter Given MessageFormatter
|
||||
* @param locale Locale to use for messages
|
||||
*/
|
||||
public UTF16Reader(InputStream inputStream, int size, boolean isBigEndian,
|
||||
MessageFormatter messageFormatter, Locale locale) {
|
||||
this(inputStream, new byte[size], isBigEndian, messageFormatter, locale);
|
||||
} // <init>(InputStream, int, boolean, MessageFormatter, Locale)
|
||||
|
||||
/**
|
||||
* Constructs a UTF-16 reader from the specified input stream, buffer and
|
||||
* MessageFormatter.
|
||||
*
|
||||
* @param inputStream The input stream.
|
||||
* @param buffer The byte buffer.
|
||||
* @param isBigEndian The byte order.
|
||||
* @param messageFormatter Given MessageFormatter
|
||||
* @param locale Locale to use for messages
|
||||
*/
|
||||
public UTF16Reader(InputStream inputStream, byte[] buffer, boolean isBigEndian,
|
||||
MessageFormatter messageFormatter, Locale locale) {
|
||||
fInputStream = inputStream;
|
||||
fBuffer = buffer;
|
||||
fIsBigEndian = isBigEndian;
|
||||
fFormatter = messageFormatter;
|
||||
fLocale = locale;
|
||||
} // <init>(InputStream, byte[], boolean, MessageFormatter, Locale)
|
||||
|
||||
//
|
||||
// Reader methods
|
||||
//
|
||||
/**
|
||||
* Read a single character. This method will block until a character is
|
||||
* available, an I/O error occurs, or the end of the stream is reached.
|
||||
*
|
||||
* <p>
|
||||
* Subclasses that intend to support efficient single-character input should
|
||||
* override this method.
|
||||
*
|
||||
* @return The character read, as an integer in the range 0 to 65535
|
||||
* (<tt>0x00-0xffff</tt>), or -1 if the end of the stream has been reached
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
final int b0 = fInputStream.read();
|
||||
if (b0 == -1) {
|
||||
return -1;
|
||||
}
|
||||
final int b1 = fInputStream.read();
|
||||
if (b1 == -1) {
|
||||
expectedTwoBytes();
|
||||
}
|
||||
// UTF-16BE
|
||||
if (fIsBigEndian) {
|
||||
return (b0 << 8) | b1;
|
||||
}
|
||||
// UTF-16LE
|
||||
return (b1 << 8) | b0;
|
||||
} // read():int
|
||||
|
||||
/**
|
||||
* Read characters into a portion of an array. This method will block until
|
||||
* some input is available, an I/O error occurs, or the end of the stream is
|
||||
* reached.
|
||||
*
|
||||
* @param ch Destination buffer
|
||||
* @param offset Offset at which to start storing characters
|
||||
* @param length Maximum number of characters to read
|
||||
*
|
||||
* @return The number of characters read, or -1 if the end of the stream has
|
||||
* been reached
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public int read(char ch[], int offset, int length) throws IOException {
|
||||
int byteLength = length << 1;
|
||||
if (byteLength > fBuffer.length) {
|
||||
byteLength = fBuffer.length;
|
||||
}
|
||||
int byteCount = fInputStream.read(fBuffer, 0, byteLength);
|
||||
if (byteCount == -1) {
|
||||
return -1;
|
||||
}
|
||||
// If an odd number of bytes were read, we still need to read one more.
|
||||
if ((byteCount & 1) != 0) {
|
||||
int b = fInputStream.read();
|
||||
if (b == -1) {
|
||||
expectedTwoBytes();
|
||||
}
|
||||
fBuffer[byteCount++] = (byte) b;
|
||||
}
|
||||
final int charCount = byteCount >> 1;
|
||||
if (fIsBigEndian) {
|
||||
processBE(ch, offset, charCount);
|
||||
} else {
|
||||
processLE(ch, offset, charCount);
|
||||
}
|
||||
return charCount;
|
||||
} // read(char[],int,int)
|
||||
|
||||
/**
|
||||
* Skip characters. This method will block until some characters are
|
||||
* available, an I/O error occurs, or the end of the stream is reached.
|
||||
*
|
||||
* @param n The number of characters to skip
|
||||
*
|
||||
* @return The number of characters actually skipped
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public long skip(long n) throws IOException {
|
||||
long bytesSkipped = fInputStream.skip(n << 1);
|
||||
if ((bytesSkipped & 1) != 0) {
|
||||
int b = fInputStream.read();
|
||||
if (b == -1) {
|
||||
expectedTwoBytes();
|
||||
}
|
||||
++bytesSkipped;
|
||||
}
|
||||
return bytesSkipped >> 1;
|
||||
} // skip(long):long
|
||||
|
||||
/**
|
||||
* Tell whether this stream is ready to be read.
|
||||
*
|
||||
* @return True if the next read() is guaranteed not to block for input,
|
||||
* false otherwise. Note that returning false does not guarantee that the
|
||||
* next read will block.
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public boolean ready() throws IOException {
|
||||
return false;
|
||||
} // ready()
|
||||
|
||||
/**
|
||||
* Tell whether this stream supports the mark() operation.
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
} // markSupported()
|
||||
|
||||
/**
|
||||
* Mark the present position in the stream. Subsequent calls to reset() will
|
||||
* attempt to reposition the stream to this point. Not all character-input
|
||||
* streams support the mark() operation.
|
||||
*
|
||||
* @param readAheadLimit Limit on the number of characters that may be read
|
||||
* while still preserving the mark. After reading this many characters,
|
||||
* attempting to reset the stream may fail.
|
||||
*
|
||||
* @exception IOException If the stream does not support mark(), or if some
|
||||
* other I/O error occurs
|
||||
*/
|
||||
public void mark(int readAheadLimit) throws IOException {
|
||||
throw new IOException(fFormatter.formatMessage(fLocale, "OperationNotSupported", new Object[]{"mark()", "UTF-16"}));
|
||||
} // mark(int)
|
||||
|
||||
/**
|
||||
* Reset the stream. If the stream has been marked, then attempt to
|
||||
* reposition it at the mark. If the stream has not been marked, then
|
||||
* attempt to reset it in some way appropriate to the particular stream, for
|
||||
* example by repositioning it to its starting point. Not all
|
||||
* character-input streams support the reset() operation, and some support
|
||||
* reset() without supporting mark().
|
||||
*
|
||||
* @exception IOException If the stream has not been marked, or if the mark
|
||||
* has been invalidated, or if the stream does not support reset(), or if
|
||||
* some other I/O error occurs
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
} // reset()
|
||||
|
||||
/**
|
||||
* Close the stream. Once a stream has been closed, further read(), ready(),
|
||||
* mark(), or reset() invocations will throw an IOException. Closing a
|
||||
* previously-closed stream, however, has no effect.
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
fInputStream.close();
|
||||
} // close()
|
||||
|
||||
//
|
||||
// Private methods
|
||||
//
|
||||
/**
|
||||
* Decodes UTF-16BE *
|
||||
*/
|
||||
private void processBE(final char ch[], int offset, final int count) {
|
||||
int curPos = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final int b0 = fBuffer[curPos++] & 0xff;
|
||||
final int b1 = fBuffer[curPos++] & 0xff;
|
||||
ch[offset++] = (char) ((b0 << 8) | b1);
|
||||
}
|
||||
} // processBE(char[],int,int)
|
||||
|
||||
/**
|
||||
* Decodes UTF-16LE *
|
||||
*/
|
||||
private void processLE(final char ch[], int offset, final int count) {
|
||||
int curPos = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final int b0 = fBuffer[curPos++] & 0xff;
|
||||
final int b1 = fBuffer[curPos++] & 0xff;
|
||||
ch[offset++] = (char) ((b1 << 8) | b0);
|
||||
}
|
||||
} // processLE(char[],int,int)
|
||||
|
||||
/**
|
||||
* Throws an exception for expected byte.
|
||||
*/
|
||||
private void expectedTwoBytes()
|
||||
throws MalformedByteSequenceException {
|
||||
throw new MalformedByteSequenceException(fFormatter,
|
||||
fLocale,
|
||||
XMLMessageFormatter.XML_DOMAIN,
|
||||
"ExpectedByte",
|
||||
new Object[]{"2", "2"});
|
||||
} // expectedTwoBytes()
|
||||
|
||||
} // class UTF16Reader
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -46,6 +46,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
|
||||
import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
|
||||
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
|
||||
import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
|
||||
import java.io.CharConversionException;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import javax.xml.XMLConstants;
|
||||
@ -1143,7 +1144,7 @@ public abstract class AbstractSAXParser
|
||||
// wrap XNI exceptions as SAX exceptions
|
||||
catch (XMLParseException e) {
|
||||
Exception ex = e.getException();
|
||||
if (ex == null) {
|
||||
if (ex == null || ex instanceof CharConversionException) {
|
||||
// must be a parser exception; mine it for locator info and throw
|
||||
// a SAXParseException
|
||||
LocatorImpl locatorImpl = new LocatorImpl(){
|
||||
@ -1163,7 +1164,9 @@ public abstract class AbstractSAXParser
|
||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||
locatorImpl.setLineNumber(e.getLineNumber());
|
||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
||||
throw new SAXParseException(e.getMessage(), locatorImpl);
|
||||
throw (ex == null) ?
|
||||
new SAXParseException(e.getMessage(), locatorImpl) :
|
||||
new SAXParseException(e.getMessage(), locatorImpl, ex);
|
||||
}
|
||||
if (ex instanceof SAXException) {
|
||||
// why did we create an XMLParseException?
|
||||
@ -1216,7 +1219,7 @@ public abstract class AbstractSAXParser
|
||||
// wrap XNI exceptions as SAX exceptions
|
||||
catch (XMLParseException e) {
|
||||
Exception ex = e.getException();
|
||||
if (ex == null) {
|
||||
if (ex == null || ex instanceof CharConversionException) {
|
||||
// must be a parser exception; mine it for locator info and throw
|
||||
// a SAXParseException
|
||||
LocatorImpl locatorImpl = new LocatorImpl() {
|
||||
@ -1236,7 +1239,9 @@ public abstract class AbstractSAXParser
|
||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||
locatorImpl.setLineNumber(e.getLineNumber());
|
||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
||||
throw new SAXParseException(e.getMessage(), locatorImpl);
|
||||
throw (ex == null) ?
|
||||
new SAXParseException(e.getMessage(), locatorImpl) :
|
||||
new SAXParseException(e.getMessage(), locatorImpl, ex);
|
||||
}
|
||||
if (ex instanceof SAXException) {
|
||||
// why did we create an XMLParseException?
|
||||
|
@ -40,6 +40,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
|
||||
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
|
||||
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
|
||||
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
|
||||
import java.io.CharConversionException;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
@ -184,7 +185,7 @@ public class DOMParser
|
||||
// wrap XNI exceptions as SAX exceptions
|
||||
catch (XMLParseException e) {
|
||||
Exception ex = e.getException();
|
||||
if (ex == null) {
|
||||
if (ex == null || ex instanceof CharConversionException) {
|
||||
// must be a parser exception; mine it for locator info and throw
|
||||
// a SAXParseException
|
||||
LocatorImpl locatorImpl = new LocatorImpl();
|
||||
@ -192,7 +193,9 @@ public class DOMParser
|
||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||
locatorImpl.setLineNumber(e.getLineNumber());
|
||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
||||
throw new SAXParseException(e.getMessage(), locatorImpl);
|
||||
throw (ex == null) ?
|
||||
new SAXParseException(e.getMessage(), locatorImpl) :
|
||||
new SAXParseException(e.getMessage(), locatorImpl, ex);
|
||||
}
|
||||
if (ex instanceof SAXException) {
|
||||
// why did we create an XMLParseException?
|
||||
@ -246,7 +249,7 @@ public class DOMParser
|
||||
// wrap XNI exceptions as SAX exceptions
|
||||
catch (XMLParseException e) {
|
||||
Exception ex = e.getException();
|
||||
if (ex == null) {
|
||||
if (ex == null || ex instanceof CharConversionException) {
|
||||
// must be a parser exception; mine it for locator info and throw
|
||||
// a SAXParseException
|
||||
LocatorImpl locatorImpl = new LocatorImpl();
|
||||
@ -254,7 +257,9 @@ public class DOMParser
|
||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||
locatorImpl.setLineNumber(e.getLineNumber());
|
||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
||||
throw new SAXParseException(e.getMessage(), locatorImpl);
|
||||
throw (ex == null) ?
|
||||
new SAXParseException(e.getMessage(), locatorImpl) :
|
||||
new SAXParseException(e.getMessage(), locatorImpl, ex);
|
||||
}
|
||||
if (ex instanceof SAXException) {
|
||||
// why did we create an XMLParseException?
|
||||
|
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.sun.org.apache.xerces.internal.util;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
|
||||
|
||||
/**
|
||||
* <p>A light wrapper around an <code>XMLLocator</code>.</p>
|
||||
*
|
||||
* @author Michael Glavassevich, IBM
|
||||
*
|
||||
* @version $Id: XMLLocatorWrapper.java 533423 2007-04-28 20:47:15Z mrglavas $
|
||||
*/
|
||||
public final class XMLLocatorWrapper implements XMLLocator {
|
||||
|
||||
private XMLLocator fLocator = null;
|
||||
|
||||
public XMLLocatorWrapper() {}
|
||||
|
||||
public void setLocator(XMLLocator locator) {
|
||||
fLocator = locator;
|
||||
}
|
||||
|
||||
public XMLLocator getLocator() {
|
||||
return fLocator;
|
||||
}
|
||||
|
||||
/*
|
||||
* XMLLocator methods
|
||||
*/
|
||||
|
||||
public String getPublicId() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getPublicId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLiteralSystemId() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getLiteralSystemId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getBaseSystemId() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getBaseSystemId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getExpandedSystemId() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getExpandedSystemId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getLineNumber();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getColumnNumber() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getColumnNumber();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getCharacterOffset() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getCharacterOffset();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getEncoding();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getXMLVersion() {
|
||||
if (fLocator != null) {
|
||||
return fLocator.getXMLVersion();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -36,9 +36,9 @@ import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
|
||||
import com.sun.org.apache.xerces.internal.util.URI;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLChar;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLLocatorWrapper;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
|
||||
import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
|
||||
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
|
||||
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
|
||||
import com.sun.org.apache.xerces.internal.xni.Augmentations;
|
||||
@ -157,8 +157,8 @@ public class XIncludeHandler
|
||||
public final static String CURRENT_BASE_URI = "currentBaseURI";
|
||||
|
||||
// used for adding [base URI] attributes
|
||||
public final static String XINCLUDE_BASE = "base".intern();
|
||||
public final static QName XML_BASE_QNAME =
|
||||
private final static String XINCLUDE_BASE = "base".intern();
|
||||
private final static QName XML_BASE_QNAME =
|
||||
new QName(
|
||||
XMLSymbols.PREFIX_XML,
|
||||
XINCLUDE_BASE,
|
||||
@ -166,15 +166,15 @@ public class XIncludeHandler
|
||||
NamespaceContext.XML_URI);
|
||||
|
||||
// used for adding [language] attributes
|
||||
public final static String XINCLUDE_LANG = "lang".intern();
|
||||
public final static QName XML_LANG_QNAME =
|
||||
private final static String XINCLUDE_LANG = "lang".intern();
|
||||
private final static QName XML_LANG_QNAME =
|
||||
new QName(
|
||||
XMLSymbols.PREFIX_XML,
|
||||
XINCLUDE_LANG,
|
||||
(XMLSymbols.PREFIX_XML + ":" + XINCLUDE_LANG).intern(),
|
||||
NamespaceContext.XML_URI);
|
||||
|
||||
public final static QName NEW_NS_ATTR_QNAME =
|
||||
private final static QName NEW_NS_ATTR_QNAME =
|
||||
new QName(
|
||||
XMLSymbols.PREFIX_XMLNS,
|
||||
"",
|
||||
@ -217,6 +217,10 @@ public class XIncludeHandler
|
||||
protected static final String XINCLUDE_FIXUP_LANGUAGE =
|
||||
Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
|
||||
|
||||
/** Property identifier: JAXP schema language. */
|
||||
protected static final String JAXP_SCHEMA_LANGUAGE =
|
||||
Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
|
||||
|
||||
/** Property identifier: symbol table. */
|
||||
protected static final String SYMBOL_TABLE =
|
||||
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
|
||||
@ -234,7 +238,7 @@ public class XIncludeHandler
|
||||
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
|
||||
|
||||
/** property identifier: buffer size. */
|
||||
public static final String BUFFER_SIZE =
|
||||
protected static final String BUFFER_SIZE =
|
||||
Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY;
|
||||
|
||||
protected static final String PARSER_SETTINGS =
|
||||
@ -292,6 +296,7 @@ public class XIncludeHandler
|
||||
protected XPointerProcessor fXPtrProcessor = null;
|
||||
|
||||
protected XMLLocator fDocLocation;
|
||||
protected XMLLocatorWrapper fXIncludeLocator = new XMLLocatorWrapper();
|
||||
protected XIncludeMessageFormatter fXIncludeMessageFormatter = new XIncludeMessageFormatter();
|
||||
protected XIncludeNamespaceSupport fNamespaceContext;
|
||||
protected SymbolTable fSymbolTable;
|
||||
@ -305,17 +310,19 @@ public class XIncludeHandler
|
||||
protected XIncludeTextReader fXInclude11TextReader;
|
||||
|
||||
// these are needed for XML Base processing
|
||||
protected XMLResourceIdentifier fCurrentBaseURI;
|
||||
protected IntStack fBaseURIScope;
|
||||
protected Stack<String> fBaseURI;
|
||||
protected Stack<String> fLiteralSystemID;
|
||||
protected Stack<String> fExpandedSystemID;
|
||||
protected final XMLResourceIdentifier fCurrentBaseURI;
|
||||
protected final IntStack fBaseURIScope;
|
||||
protected final Stack<String> fBaseURI;
|
||||
protected final Stack<String> fLiteralSystemID;
|
||||
protected final Stack<String> fExpandedSystemID;
|
||||
|
||||
// these are needed for Language Fixup
|
||||
protected IntStack fLanguageScope;
|
||||
protected Stack<String> fLanguageStack;
|
||||
protected final IntStack fLanguageScope;
|
||||
protected final Stack<String> fLanguageStack;
|
||||
protected String fCurrentLanguage;
|
||||
|
||||
protected String fHrefFromParent;
|
||||
|
||||
// used for passing features on to child XIncludeHandler objects
|
||||
protected ParserConfigurationSettings fSettings;
|
||||
|
||||
@ -361,6 +368,9 @@ public class XIncludeHandler
|
||||
// track whether a DTD is being parsed
|
||||
private boolean fInDTD;
|
||||
|
||||
// tracks whether content has been reported on the child pipeline
|
||||
boolean fHasIncludeReportedContent;
|
||||
|
||||
// track whether the root element of the result infoset has been processed
|
||||
private boolean fSeenRootElement;
|
||||
|
||||
@ -593,15 +603,21 @@ public class XIncludeHandler
|
||||
copyFeatures(componentManager, fSettings);
|
||||
|
||||
// We don't want a schema validator on the new pipeline,
|
||||
// so if it was enabled, we set the feature to false. If
|
||||
// the validation feature was also enabled we turn on
|
||||
// dynamic validation, so that DTD validation is performed
|
||||
// on the included documents only if they have a DOCTYPE.
|
||||
// This is consistent with the behaviour on the main pipeline.
|
||||
// so if it was enabled, we set the feature to false.
|
||||
try {
|
||||
if (componentManager.getFeature(SCHEMA_VALIDATION)) {
|
||||
fSettings.setFeature(SCHEMA_VALIDATION, false);
|
||||
if (componentManager.getFeature(VALIDATION)) {
|
||||
// If the value of the JAXP 1.2 schema language property
|
||||
// is http://www.w3.org/2001/XMLSchema we're only validating
|
||||
// against XML schema so we disable validation on the new pipeline.
|
||||
if (Constants.NS_XMLSCHEMA.equals(componentManager.getProperty(JAXP_SCHEMA_LANGUAGE))) {
|
||||
fSettings.setFeature(VALIDATION, false);
|
||||
}
|
||||
// If the validation feature was also enabled we turn on
|
||||
// dynamic validation, so that DTD validation is performed
|
||||
// on the included documents only if they have a DOCTYPE.
|
||||
// This is consistent with the behaviour on the main pipeline.
|
||||
else if (componentManager.getFeature(VALIDATION)) {
|
||||
fSettings.setFeature(DYNAMIC_VALIDATION, true);
|
||||
}
|
||||
}
|
||||
@ -776,7 +792,15 @@ public class XIncludeHandler
|
||||
|
||||
@Override
|
||||
public void setDocumentHandler(XMLDocumentHandler handler) {
|
||||
fDocumentHandler = handler;
|
||||
if (fDocumentHandler != handler) {
|
||||
fDocumentHandler = handler;
|
||||
if (fXIncludeChildConfig != null) {
|
||||
fXIncludeChildConfig.setDocumentHandler(handler);
|
||||
}
|
||||
if (fXPointerChildConfig != null) {
|
||||
fXPointerChildConfig.setDocumentHandler(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -806,36 +830,39 @@ public class XIncludeHandler
|
||||
// otherwise, the locator from the root document would always be used
|
||||
fErrorReporter.setDocumentLocator(locator);
|
||||
|
||||
if (!isRootDocument()
|
||||
&& fParentXIncludeHandler.searchForRecursiveIncludes(locator)) {
|
||||
reportFatalError(
|
||||
"RecursiveInclude",
|
||||
new Object[] { locator.getExpandedSystemId()});
|
||||
}
|
||||
|
||||
if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
|
||||
reportFatalError("IncompatibleNamespaceContext");
|
||||
}
|
||||
fNamespaceContext = (XIncludeNamespaceSupport)namespaceContext;
|
||||
fDocLocation = locator;
|
||||
fXIncludeLocator.setLocator(fDocLocation);
|
||||
|
||||
// initialize the current base URI
|
||||
fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
|
||||
fCurrentBaseURI.setExpandedSystemId(locator.getExpandedSystemId());
|
||||
fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
|
||||
setupCurrentBaseURI(locator);
|
||||
saveBaseURI();
|
||||
if (augs == null) {
|
||||
augs = new AugmentationsImpl();
|
||||
}
|
||||
augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
|
||||
|
||||
// abort here if we detect a recursive include
|
||||
if (!isRootDocument()) {
|
||||
fParentXIncludeHandler.fHasIncludeReportedContent = true;
|
||||
if (fParentXIncludeHandler.searchForRecursiveIncludes(
|
||||
fCurrentBaseURI.getExpandedSystemId())) {
|
||||
reportFatalError(
|
||||
"RecursiveInclude",
|
||||
new Object[] { fCurrentBaseURI.getExpandedSystemId()});
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the current language
|
||||
fCurrentLanguage = XMLSymbols.EMPTY_STRING;
|
||||
saveLanguage(fCurrentLanguage);
|
||||
|
||||
if (isRootDocument() && fDocumentHandler != null) {
|
||||
fDocumentHandler.startDocument(
|
||||
locator,
|
||||
fXIncludeLocator,
|
||||
encoding,
|
||||
namespaceContext,
|
||||
augs);
|
||||
@ -1671,7 +1698,7 @@ public class XIncludeHandler
|
||||
catch (IOException | CatalogException e) {
|
||||
reportResourceError(
|
||||
"XMLResourceError",
|
||||
new Object[] { href, e.getMessage()});
|
||||
new Object[] { href, e.getMessage()}, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1750,6 +1777,8 @@ public class XIncludeHandler
|
||||
// ???
|
||||
|
||||
newHandler.setParent(this);
|
||||
newHandler.setHref(href);
|
||||
newHandler.setXIncludeLocator(fXIncludeLocator);
|
||||
newHandler.setDocumentHandler(this.getDocumentHandler());
|
||||
fXPointerChildConfig = fChildConfig;
|
||||
} else {
|
||||
@ -1758,7 +1787,8 @@ public class XIncludeHandler
|
||||
Constants.XERCES_PROPERTY_PREFIX
|
||||
+ Constants.XINCLUDE_HANDLER_PROPERTY);
|
||||
|
||||
newHandler.setParent(this);
|
||||
newHandler.setParent(this);
|
||||
newHandler.setHref(href);
|
||||
newHandler.setDocumentHandler(this.getDocumentHandler());
|
||||
fXIncludeChildConfig = fChildConfig;
|
||||
}
|
||||
@ -1766,7 +1796,7 @@ public class XIncludeHandler
|
||||
|
||||
// If an xpointer attribute is present
|
||||
if (xpointer != null ) {
|
||||
fChildConfig = fXPointerChildConfig ;
|
||||
fChildConfig = fXPointerChildConfig;
|
||||
|
||||
// Parse the XPointer expression
|
||||
try {
|
||||
@ -1790,10 +1820,12 @@ public class XIncludeHandler
|
||||
fNeedCopyFeatures = false;
|
||||
|
||||
try {
|
||||
fHasIncludeReportedContent = false;
|
||||
fNamespaceContext.pushScope();
|
||||
|
||||
fChildConfig.parse(includedSource);
|
||||
// necessary to make sure proper location is reported in errors
|
||||
// necessary to make sure proper location is reported to the application and in errors
|
||||
fXIncludeLocator.setLocator(fDocLocation);
|
||||
if (fErrorReporter != null) {
|
||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||
}
|
||||
@ -1811,23 +1843,32 @@ public class XIncludeHandler
|
||||
}
|
||||
}
|
||||
catch (XNIException e) {
|
||||
// necessary to make sure proper location is reported in errors
|
||||
// necessary to make sure proper location is reported to the application and in errors
|
||||
fXIncludeLocator.setLocator(fDocLocation);
|
||||
if (fErrorReporter != null) {
|
||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||
}
|
||||
reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
|
||||
}
|
||||
catch (IOException e) {
|
||||
// necessary to make sure proper location is reported in errors
|
||||
// necessary to make sure proper location is reported to the application and in errors
|
||||
fXIncludeLocator.setLocator(fDocLocation);
|
||||
if (fErrorReporter != null) {
|
||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||
}
|
||||
// An IOException indicates that we had trouble reading the file, not
|
||||
// that it was an invalid XML file. So we send a resource error, not a
|
||||
// fatal error.
|
||||
// If the start document event has been seen on the child pipeline it
|
||||
// means the resource was successfully opened and we started reporting
|
||||
// document events. If an IOException is thrown after the start document
|
||||
// event we had a failure midstream and cannot recover.
|
||||
if (fHasIncludeReportedContent) {
|
||||
throw new XNIException(e);
|
||||
}
|
||||
// In other circumstances an IOException indicates that we had trouble
|
||||
// accessing or opening the file, not that it was an invalid XML file. So we
|
||||
// send a resource error, not a fatal error.
|
||||
reportResourceError(
|
||||
"XMLResourceError",
|
||||
new Object[] { href, e.getMessage()});
|
||||
new Object[] { href, e.getMessage()}, e);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -1841,6 +1882,8 @@ public class XIncludeHandler
|
||||
XIncludeTextReader textReader = null;
|
||||
|
||||
try {
|
||||
fHasIncludeReportedContent = false;
|
||||
|
||||
// Setup the appropriate text reader.
|
||||
if (!fIsXML11) {
|
||||
if (fXInclude10TextReader == null) {
|
||||
@ -1866,16 +1909,22 @@ public class XIncludeHandler
|
||||
// encoding errors
|
||||
catch (MalformedByteSequenceException ex) {
|
||||
fErrorReporter.reportError(ex.getDomain(), ex.getKey(),
|
||||
ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, ex);
|
||||
}
|
||||
catch (CharConversionException e) {
|
||||
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
|
||||
"CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
"CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
// If a characters event has already been sent down the pipeline it
|
||||
// means the resource was successfully opened and that this IOException
|
||||
// is from a failure midstream from which we cannot recover.
|
||||
if (fHasIncludeReportedContent) {
|
||||
throw new XNIException(e);
|
||||
}
|
||||
reportResourceError(
|
||||
"TextResourceError",
|
||||
new Object[] { href, e.getMessage()});
|
||||
new Object[] { href, e.getMessage()}, e);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -1886,7 +1935,7 @@ public class XIncludeHandler
|
||||
catch (IOException e) {
|
||||
reportResourceError(
|
||||
"TextResourceError",
|
||||
new Object[] { href, e.getMessage()});
|
||||
new Object[] { href, e.getMessage()}, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1977,37 +2026,51 @@ public class XIncludeHandler
|
||||
return parentLanguage != null && parentLanguage.equalsIgnoreCase(fCurrentLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file indicated by the given XMLLocator has already been included
|
||||
* in the current stack.
|
||||
* @param includedSource the source to check for inclusion
|
||||
* @return true if the source has already been included
|
||||
*/
|
||||
protected boolean searchForRecursiveIncludes(XMLLocator includedSource) {
|
||||
String includedSystemId = includedSource.getExpandedSystemId();
|
||||
private void setupCurrentBaseURI(XMLLocator locator) {
|
||||
fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
|
||||
if (locator.getLiteralSystemId() != null) {
|
||||
fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
|
||||
}
|
||||
else {
|
||||
fCurrentBaseURI.setLiteralSystemId(fHrefFromParent);
|
||||
}
|
||||
|
||||
if (includedSystemId == null) {
|
||||
String expandedSystemId = locator.getExpandedSystemId();
|
||||
if (expandedSystemId == null) {
|
||||
// attempt to expand it ourselves
|
||||
try {
|
||||
includedSystemId =
|
||||
expandedSystemId =
|
||||
XMLEntityManager.expandSystemId(
|
||||
includedSource.getLiteralSystemId(),
|
||||
includedSource.getBaseSystemId(),
|
||||
fCurrentBaseURI.getLiteralSystemId(),
|
||||
fCurrentBaseURI.getBaseSystemId(),
|
||||
false);
|
||||
if (expandedSystemId == null) {
|
||||
expandedSystemId = fCurrentBaseURI.getLiteralSystemId();
|
||||
}
|
||||
}
|
||||
catch (MalformedURIException e) {
|
||||
reportFatalError("ExpandedSystemId");
|
||||
}
|
||||
}
|
||||
fCurrentBaseURI.setExpandedSystemId(expandedSystemId);
|
||||
}
|
||||
|
||||
if (includedSystemId.equals(fCurrentBaseURI.getExpandedSystemId())) {
|
||||
/**
|
||||
* Checks if the file indicated by the given system id has already been
|
||||
* included in the current stack.
|
||||
* @param includedSysId the system id to check for inclusion
|
||||
* @return true if the source has already been included
|
||||
*/
|
||||
protected boolean searchForRecursiveIncludes(String includedSysId) {
|
||||
if (includedSysId.equals(fCurrentBaseURI.getExpandedSystemId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fParentXIncludeHandler == null) {
|
||||
else if (fParentXIncludeHandler == null) {
|
||||
return false;
|
||||
}
|
||||
return fParentXIncludeHandler.searchForRecursiveIncludes(
|
||||
includedSource);
|
||||
else {
|
||||
return fParentXIncludeHandler.searchForRecursiveIncludes(includedSysId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2045,7 +2108,7 @@ public class XIncludeHandler
|
||||
* unparsed entities are processed as described in the spec, sections 4.5.1 and 4.5.2
|
||||
* </ul>
|
||||
* @param attributes
|
||||
* @return
|
||||
* @return the processed XMLAttributes
|
||||
*/
|
||||
protected XMLAttributes processAttributes(XMLAttributes attributes) {
|
||||
if (isTopLevelIncludedItem()) {
|
||||
@ -2198,7 +2261,7 @@ public class XIncludeHandler
|
||||
return relativeURI;
|
||||
}
|
||||
else {
|
||||
if (relativeURI.equals("")) {
|
||||
if (relativeURI.length() == 0) {
|
||||
relativeURI = fCurrentBaseURI.getLiteralSystemId();
|
||||
}
|
||||
|
||||
@ -2207,7 +2270,7 @@ public class XIncludeHandler
|
||||
fParentRelativeURI =
|
||||
fParentXIncludeHandler.getRelativeBaseURI();
|
||||
}
|
||||
if (fParentRelativeURI.equals("")) {
|
||||
if (fParentRelativeURI.length() == 0) {
|
||||
return relativeURI;
|
||||
}
|
||||
|
||||
@ -2420,7 +2483,7 @@ public class XIncludeHandler
|
||||
* as an ancestor of the current item.
|
||||
*
|
||||
* @param depth
|
||||
* @return
|
||||
* @return true if an include was seen at the given depth, false otherwise
|
||||
*/
|
||||
protected boolean getSawInclude(int depth) {
|
||||
if (depth >= fSawInclude.length) {
|
||||
@ -2430,11 +2493,15 @@ public class XIncludeHandler
|
||||
}
|
||||
|
||||
protected void reportResourceError(String key) {
|
||||
this.reportFatalError(key, null);
|
||||
this.reportResourceError(key, null);
|
||||
}
|
||||
|
||||
protected void reportResourceError(String key, Object[] args) {
|
||||
this.reportError(key, args, XMLErrorReporter.SEVERITY_WARNING);
|
||||
this.reportResourceError(key, args, null);
|
||||
}
|
||||
|
||||
protected void reportResourceError(String key, Object[] args, Exception exception) {
|
||||
this.reportError(key, args, XMLErrorReporter.SEVERITY_WARNING, exception);
|
||||
}
|
||||
|
||||
protected void reportFatalError(String key) {
|
||||
@ -2442,16 +2509,21 @@ public class XIncludeHandler
|
||||
}
|
||||
|
||||
protected void reportFatalError(String key, Object[] args) {
|
||||
this.reportError(key, args, XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
||||
this.reportFatalError(key, args, null);
|
||||
}
|
||||
|
||||
private void reportError(String key, Object[] args, short severity) {
|
||||
protected void reportFatalError(String key, Object[] args, Exception exception) {
|
||||
this.reportError(key, args, XMLErrorReporter.SEVERITY_FATAL_ERROR, exception);
|
||||
}
|
||||
|
||||
private void reportError(String key, Object[] args, short severity, Exception exception) {
|
||||
if (fErrorReporter != null) {
|
||||
fErrorReporter.reportError(
|
||||
XIncludeMessageFormatter.XINCLUDE_DOMAIN,
|
||||
key,
|
||||
args,
|
||||
severity);
|
||||
severity,
|
||||
exception);
|
||||
}
|
||||
// we won't worry about when error reporter is null, since there should always be
|
||||
// at least the default error reporter
|
||||
@ -2465,6 +2537,14 @@ public class XIncludeHandler
|
||||
fParentXIncludeHandler = parent;
|
||||
}
|
||||
|
||||
protected void setHref(String href) {
|
||||
fHrefFromParent = href;
|
||||
}
|
||||
|
||||
protected void setXIncludeLocator(XMLLocatorWrapper locator) {
|
||||
fXIncludeLocator = locator;
|
||||
}
|
||||
|
||||
// used to know whether to pass declarations to the document handler
|
||||
protected boolean isRootDocument() {
|
||||
return fParentXIncludeHandler == null;
|
||||
@ -2849,7 +2929,7 @@ public class XIncludeHandler
|
||||
/**
|
||||
* Saves the given language on the top of the stack.
|
||||
*
|
||||
* @param lanaguage the language to push onto the stack.
|
||||
* @param language the language to push onto the stack.
|
||||
*/
|
||||
protected void saveLanguage(String language) {
|
||||
fLanguageScope.push(fDepth);
|
||||
@ -3013,7 +3093,7 @@ public class XIncludeHandler
|
||||
// the second hex character if a character needs to be escaped
|
||||
private static final char gAfterEscaping2[] = new char[128];
|
||||
private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
// initialize the above 3 arrays
|
||||
static {
|
||||
char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
|
||||
@ -3104,7 +3184,7 @@ public class XIncludeHandler
|
||||
// for each byte
|
||||
for (i = 0; i < len; i++) {
|
||||
b = bytes[i];
|
||||
// for non-ascii character: make it positive, then escape
|
||||
// for non-ASCII character: make it positive, then escape
|
||||
if (b < 0) {
|
||||
ch = b + 256;
|
||||
buffer.append('%');
|
||||
@ -3123,7 +3203,7 @@ public class XIncludeHandler
|
||||
}
|
||||
|
||||
// If escaping happened, create a new string;
|
||||
// otherwise, return the orginal one.
|
||||
// otherwise, return the original one.
|
||||
if (buffer.length() != len) {
|
||||
return buffer.toString();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -23,6 +23,8 @@ package com.sun.org.apache.xerces.internal.xinclude;
|
||||
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
|
||||
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
|
||||
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
|
||||
import com.sun.org.apache.xerces.internal.impl.io.Latin1Reader;
|
||||
import com.sun.org.apache.xerces.internal.impl.io.UTF16Reader;
|
||||
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
|
||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||
import com.sun.org.apache.xerces.internal.util.EncodingMap;
|
||||
@ -67,7 +69,7 @@ import java.util.Map;
|
||||
public class XIncludeTextReader {
|
||||
|
||||
private Reader fReader;
|
||||
private XIncludeHandler fHandler;
|
||||
private final XIncludeHandler fHandler;
|
||||
private XMLInputSource fSource;
|
||||
private XMLErrorReporter fErrorReporter;
|
||||
private XMLString fTempString = new XMLString();
|
||||
@ -149,12 +151,12 @@ public class XIncludeTextReader {
|
||||
stream = new BufferedInputStream(urlCon.getInputStream());
|
||||
|
||||
// content type will be string like "text/xml; charset=UTF-8" or "text/xml"
|
||||
String rawContentType = urlCon.getContentType();
|
||||
final String rawContentType = urlCon.getContentType();
|
||||
|
||||
// text/xml and application/xml offer only one optional parameter
|
||||
int index = (rawContentType != null) ? rawContentType.indexOf(';') : -1;
|
||||
final int index = (rawContentType != null) ? rawContentType.indexOf(';') : -1;
|
||||
|
||||
String contentType = null;
|
||||
final String contentType;
|
||||
String charset = null;
|
||||
if (index != -1) {
|
||||
// this should be something like "text/xml"
|
||||
@ -181,14 +183,16 @@ public class XIncludeTextReader {
|
||||
}
|
||||
}
|
||||
else {
|
||||
contentType = rawContentType.trim();
|
||||
contentType = (rawContentType != null) ? rawContentType.trim() : "";
|
||||
}
|
||||
|
||||
String detectedEncoding = null;
|
||||
/** The encoding of such a resource is determined by:
|
||||
1 external encoding information, if available, otherwise
|
||||
-- the most common type of external information is the "charset" parameter of a MIME package
|
||||
2 if the media type of the resource is text/xml, application/xml, or matches the conventions text/*+xml or application/*+xml as described in XML Media Types [IETF RFC 3023], the encoding is recognized as specified in XML 1.0, otherwise
|
||||
2 if the media type of the resource is text/xml, application/xml, or matches the conventions
|
||||
text/*+xml or application/*+xml as described in XML Media Types [IETF RFC 3023], the encoding
|
||||
is recognized as specified in XML 1.0, otherwise
|
||||
3 the value of the encoding attribute if one exists, otherwise
|
||||
4 UTF-8.
|
||||
**/
|
||||
@ -225,15 +229,17 @@ public class XIncludeTextReader {
|
||||
// eat the Byte Order Mark
|
||||
encoding = consumeBOM(stream, encoding);
|
||||
|
||||
// If the document is UTF-8 or US-ASCII use
|
||||
// the Xerces readers for these encodings. For
|
||||
// US-ASCII consult the encoding map since
|
||||
// this encoding has many aliases.
|
||||
// If the document is UTF-8, UTF-16, US-ASCII or ISO-8859-1 use
|
||||
// the Xerces readers for these encodings. For US-ASCII and ISO-8859-1
|
||||
// consult the encoding map since these encodings have many aliases.
|
||||
if (encoding.equals("UTF-8")) {
|
||||
return new UTF8Reader(stream,
|
||||
fTempString.ch.length,
|
||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
||||
fErrorReporter.getLocale() );
|
||||
return createUTF8Reader(stream);
|
||||
}
|
||||
else if (encoding.equals("UTF-16BE")) {
|
||||
return createUTF16Reader(stream, true);
|
||||
}
|
||||
else if (encoding.equals("UTF-16LE")) {
|
||||
return createUTF16Reader(stream, false);
|
||||
}
|
||||
|
||||
// Try to use a Java reader.
|
||||
@ -251,16 +257,45 @@ public class XIncludeTextReader {
|
||||
new Object[] {encoding} ) );
|
||||
}
|
||||
else if (javaEncoding.equals("ASCII")) {
|
||||
return new ASCIIReader(stream,
|
||||
fTempString.ch.length,
|
||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
||||
fErrorReporter.getLocale() );
|
||||
return createASCIIReader(stream);
|
||||
}
|
||||
else if (javaEncoding.equals("ISO8859_1")) {
|
||||
return createLatin1Reader(stream);
|
||||
}
|
||||
|
||||
return new InputStreamReader(stream, javaEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a new UTF-8 reader from the InputStream. **/
|
||||
private Reader createUTF8Reader(InputStream stream) {
|
||||
return new UTF8Reader(stream,
|
||||
fTempString.ch.length,
|
||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
||||
fErrorReporter.getLocale());
|
||||
}
|
||||
|
||||
/** Create a new UTF-16 reader from the InputStream. **/
|
||||
private Reader createUTF16Reader(InputStream stream, boolean isBigEndian) {
|
||||
return new UTF16Reader(stream,
|
||||
(fTempString.ch.length << 1),
|
||||
isBigEndian,
|
||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
||||
fErrorReporter.getLocale());
|
||||
}
|
||||
|
||||
/** Create a new ASCII reader from the InputStream. **/
|
||||
private Reader createASCIIReader(InputStream stream) {
|
||||
return new ASCIIReader(stream,
|
||||
fTempString.ch.length,
|
||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
||||
fErrorReporter.getLocale());
|
||||
}
|
||||
|
||||
/** Create a new ISO-8859-1 reader from the InputStream. **/
|
||||
private Reader createLatin1Reader(InputStream stream) {
|
||||
return new Latin1Reader(stream, fTempString.ch.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* XMLEntityManager cares about endian-ness, since it creates its own optimized
|
||||
* readers. Since we're just using generic Java readers for now, we're not caring
|
||||
@ -416,6 +451,7 @@ public class XIncludeTextReader {
|
||||
fReader = getReader(fSource);
|
||||
fSource = null;
|
||||
int readSize = fReader.read(fTempString.ch, 0, fTempString.ch.length - 1);
|
||||
fHandler.fHasIncludeReportedContent = true;
|
||||
while (readSize != -1) {
|
||||
for (int i = 0; i < readSize; ++i) {
|
||||
char ch = fTempString.ch[i];
|
||||
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8038043
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm common.EncodingErrorsReportingTest
|
||||
* @run testng/othervm -DrunSecMngr=true common.EncodingErrorsReportingTest
|
||||
* @summary Verifies that parsers reports location of wrong UTF-8 symbols in
|
||||
* XML files parsed and included via xi:include element
|
||||
*/
|
||||
package common;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.function.Function;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.Assert;
|
||||
|
||||
@Listeners({jaxp.library.BasePolicy.class})
|
||||
public class EncodingErrorsReportingTest implements EntityResolver {
|
||||
|
||||
/*
|
||||
* Test reporting of wrong UTF8 byte sequence location by SAX and DOM parsers
|
||||
*/
|
||||
@Test(dataProvider = "invalidUTF8BytesInXml")
|
||||
public void testMalformedByteException(Function<byte[], Exception> parseF,
|
||||
byte[] xmlData, int expLine, int expColumn) {
|
||||
// Check if data was generated without errors
|
||||
Assert.assertNotNull(xmlData, "Error in xml test data generation");
|
||||
|
||||
// Execute supplier to get parse exception
|
||||
Exception caughtEx = parseF.apply(xmlData);
|
||||
|
||||
// Check if exception was thrown
|
||||
Assert.assertNotNull(caughtEx, "No caught exception");
|
||||
boolean isSPE = caughtEx instanceof SAXParseException;
|
||||
Assert.assertTrue(isSPE, "Caught exception is not SAXParseException");
|
||||
SAXParseException spe = (SAXParseException) caughtEx;
|
||||
|
||||
// Check if cause is properly set
|
||||
Throwable cause = spe.getCause();
|
||||
Assert.assertNotNull(cause, "Cause is null");
|
||||
Assert.assertEquals("com.sun.org.apache.xerces.internal" +
|
||||
".impl.io.MalformedByteSequenceException",
|
||||
cause.getClass().getName(),
|
||||
"Cause is not MalformedByteSequenceException");
|
||||
|
||||
// Check error locator parameters
|
||||
int column_number = spe.getColumnNumber();
|
||||
int line_number = spe.getLineNumber();
|
||||
Assert.assertEquals(line_number, expLine, "Wrong line number reported");
|
||||
Assert.assertEquals(column_number, expColumn, "Wrong column number reported");
|
||||
}
|
||||
|
||||
// Provider with supplier functions that process XML content with different parsers
|
||||
@DataProvider(name = "invalidUTF8BytesInXml")
|
||||
public Object[][] parsersResultsSupplier() {
|
||||
return new Object[][]{
|
||||
// Tests for invalid UTF-8 byte in xml element
|
||||
{(Function<byte[], Exception>) this::parseWithSAX,
|
||||
invalidByteInXmlElement(), 3, 15},
|
||||
{(Function<byte[], Exception>) this::parseWithDOM,
|
||||
invalidByteInXmlElement(), 3, 15},
|
||||
// Tests for invalid UTF-8 byte in xml attribute
|
||||
{(Function<byte[], Exception>) this::parseWithSAX,
|
||||
invalidByteInXmlAttribute(), 4, 21},
|
||||
{(Function<byte[], Exception>) this::parseWithDOM,
|
||||
invalidByteInXmlAttribute(), 4, 21},
|
||||
// Tests for invalid UTF-8 byte in xml version string
|
||||
{(Function<byte[], Exception>) this::parseWithSAX,
|
||||
invalidByteInXmlVersionDecl(), 1, 16},
|
||||
{(Function<byte[], Exception>) this::parseWithDOM,
|
||||
invalidByteInXmlVersionDecl(), 1, 16},
|
||||
// Tests for invalid byte in XML file included
|
||||
// into parsed XML file with xi:include element
|
||||
{(Function<byte[], Exception>) this::parseSaxAndXinclude,
|
||||
XINCLUDE_TEST_XML.getBytes(), 5, 53},
|
||||
{(Function<byte[], Exception>) this::parseDomAndXinclude,
|
||||
XINCLUDE_TEST_XML.getBytes(), 5, 53},
|
||||
};
|
||||
}
|
||||
|
||||
// Parse constructed XML with SAXParser and save the observed exception
|
||||
private Exception parseWithSAX(byte[] data) {
|
||||
Exception caughtEx = null;
|
||||
try {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
InputStream inputStream = new ByteArrayInputStream(data);
|
||||
saxParser.parse(inputStream, new DefaultHandler());
|
||||
} catch (Exception e) {
|
||||
caughtEx = e;
|
||||
}
|
||||
return caughtEx;
|
||||
}
|
||||
|
||||
// Parse constructed XML with DOMParser and save the observed exception
|
||||
private Exception parseWithDOM(byte[] data) {
|
||||
Exception caughtEx = null;
|
||||
try {
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
InputStream inputStream = new ByteArrayInputStream(data);
|
||||
db.parse(inputStream);
|
||||
} catch (Exception e) {
|
||||
caughtEx = e;
|
||||
}
|
||||
return caughtEx;
|
||||
}
|
||||
|
||||
// Parse XML content that includes faulty XML content with xi:include element.
|
||||
// XML data is parsed by SAX parser
|
||||
private Exception parseSaxAndXinclude(byte[] data) {
|
||||
Exception caughtEx = null;
|
||||
try {
|
||||
// Create SAX parser factory and make it xi:include aware
|
||||
SAXParserFactory spf = SAXParserFactory.newDefaultInstance();
|
||||
spf.setNamespaceAware(true);
|
||||
spf.setXIncludeAware(true);
|
||||
// Set this test class as entity resolver
|
||||
XMLReader reader = spf.newSAXParser().getXMLReader();
|
||||
reader.setEntityResolver(this);
|
||||
// Parse XML
|
||||
InputStream inputStream = new ByteArrayInputStream(data);
|
||||
reader.parse(new InputSource(inputStream));
|
||||
} catch (Exception e) {
|
||||
caughtEx = e;
|
||||
}
|
||||
return caughtEx;
|
||||
}
|
||||
|
||||
// Parse XML content that includes faulty XML content with xi:include element.
|
||||
// XML data is parsed by DOM parser
|
||||
private Exception parseDomAndXinclude(byte[] data) {
|
||||
Exception caughtEx = null;
|
||||
try {
|
||||
// Create DOM builder factory and make it xi:include aware
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setXIncludeAware(true);
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
// Set this test class as entity resolver
|
||||
db.setEntityResolver(this);
|
||||
InputStream inputStream = new ByteArrayInputStream(data);
|
||||
// Parse XML
|
||||
db.parse(inputStream);
|
||||
} catch (Exception e) {
|
||||
caughtEx = e;
|
||||
}
|
||||
return caughtEx;
|
||||
}
|
||||
|
||||
// EntityResolver method to intercept load of test XML file content and
|
||||
// redirect it to ByteArrayInputStream
|
||||
@Override
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
|
||||
if (systemId != null && systemId.endsWith(XINCLUDE_TEST_FN)) {
|
||||
return new InputSource(
|
||||
new ByteArrayInputStream(
|
||||
generateXmlBytes("Wrong byte is ", "here", 0xFE)
|
||||
)
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Construct XML content with invalid byte in xml element
|
||||
private static byte[] invalidByteInXmlElement() {
|
||||
final String prefix = "<?xml version=\"1.0\"?>\n<test>\n<bad-encoding>";
|
||||
final String postfix = "</bad-encoding></test>";
|
||||
return generateXmlBytes(prefix, postfix, 0xFA);
|
||||
}
|
||||
|
||||
// Construct XML content with invalid byte in xml version declaration
|
||||
private static byte[] invalidByteInXmlVersionDecl() {
|
||||
final String prefix = "<?xml version=\"";
|
||||
final String postfix = "1.0\"?><test><bad-encoding></bad-encoding></test>";
|
||||
return generateXmlBytes(prefix, postfix, 0xFB);
|
||||
}
|
||||
|
||||
// Construct XML content with invalid byte in xml attribute
|
||||
private static byte[] invalidByteInXmlAttribute() {
|
||||
final String prefix = "<?xml version=\"1.0\"?>\n<test>\n\n<bad-att attribute=\"";
|
||||
final String postfix = "\"></bad-att></test>";
|
||||
return generateXmlBytes(prefix, postfix, 0xFC);
|
||||
}
|
||||
|
||||
// Test helper function to generate XML text with invalid UTF-8 byte inside
|
||||
private static byte[] generateXmlBytes(String prefix, String postfix, int b) {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
baos.write(prefix.getBytes());
|
||||
baos.write(b);
|
||||
baos.write(postfix.getBytes());
|
||||
return baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// XML file name to be included with xi:include directive
|
||||
private final static String XINCLUDE_TEST_FN = "xincludeTestFile.xml";
|
||||
|
||||
// xi:include test XML file that includes xml content with invalid byte
|
||||
private final static String XINCLUDE_TEST_XML =
|
||||
"<?xml version=\"1.0\"?>\n" +
|
||||
"<!DOCTYPE testXInclude [\n" +
|
||||
"<!ENTITY xincludeTestFile \""+XINCLUDE_TEST_FN+"\">]>\n" +
|
||||
"<testXInclude xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n" +
|
||||
"<xi:include href=\"&xincludeTestFile;\" parse=\"text\"/>\n" +
|
||||
"</testXInclude>";
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user