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;
|
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.impl.msg.XMLMessageFormatter;
|
||||||
import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
|
import com.sun.org.apache.xerces.internal.util.AugmentationsImpl;
|
||||||
import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl;
|
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.XMLBufferListener;
|
||||||
import com.sun.xml.internal.stream.XMLEntityStorage;
|
import com.sun.xml.internal.stream.XMLEntityStorage;
|
||||||
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
||||||
|
import java.io.CharConversionException;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
@ -3075,6 +3077,20 @@ public class XMLDocumentFragmentScannerImpl
|
|||||||
|
|
||||||
}//switch
|
}//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
|
// premature end of file
|
||||||
catch (EOFException e) {
|
catch (EOFException e) {
|
||||||
endOfFileHook(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;
|
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.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.impl.validation.ValidationManager;
|
||||||
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
|
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
|
||||||
import com.sun.org.apache.xerces.internal.util.XMLChar;
|
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.Entity;
|
||||||
import com.sun.xml.internal.stream.StaxXMLInputSource;
|
import com.sun.xml.internal.stream.StaxXMLInputSource;
|
||||||
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
|
||||||
|
import java.io.CharConversionException;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
@ -758,7 +761,19 @@ public class XMLDocumentScannerImpl
|
|||||||
return XMLEvent.START_DOCUMENT;
|
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
|
// premature end of file
|
||||||
catch (EOFException e) {
|
catch (EOFException e) {
|
||||||
reportFatalError("PrematureEOF", null);
|
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
|
// premature end of file
|
||||||
catch (EOFException e) {
|
catch (EOFException e) {
|
||||||
reportFatalError("PrematureEOF", null);
|
reportFatalError("PrematureEOF", null);
|
||||||
@ -1152,7 +1180,19 @@ public class XMLDocumentScannerImpl
|
|||||||
}
|
}
|
||||||
} while (complete || again);
|
} 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
|
// premature end of file
|
||||||
catch (EOFException e) {
|
catch (EOFException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -1416,7 +1456,18 @@ public class XMLDocumentScannerImpl
|
|||||||
}
|
}
|
||||||
default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
|
default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
|
||||||
}//switch
|
}//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) {
|
} catch (EOFException e) {
|
||||||
// NOTE: This is the only place we're allowed to reach
|
// NOTE: This is the only place we're allowed to reach
|
||||||
// the real end of the document stream. Unless the
|
// 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
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
@ -20,9 +20,11 @@
|
|||||||
|
|
||||||
package com.sun.org.apache.xerces.internal.impl;
|
package com.sun.org.apache.xerces.internal.impl;
|
||||||
|
|
||||||
|
import java.io.CharConversionException;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
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.impl.msg.XMLMessageFormatter;
|
||||||
import com.sun.org.apache.xerces.internal.util.SymbolTable;
|
import com.sun.org.apache.xerces.internal.util.SymbolTable;
|
||||||
import com.sun.org.apache.xerces.internal.xni.XMLString;
|
import com.sun.org.apache.xerces.internal.xni.XMLString;
|
||||||
@ -196,7 +198,21 @@ public class XMLVersionDetector {
|
|||||||
return Constants.XML_VERSION_1_0;
|
return Constants.XML_VERSION_1_0;
|
||||||
// premature end of file
|
// 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(
|
fErrorReporter.reportError(
|
||||||
XMLMessageFormatter.XML_DOMAIN,
|
XMLMessageFormatter.XML_DOMAIN,
|
||||||
"PrematureEOF",
|
"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
|
* 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.AttributePSVI;
|
||||||
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
|
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
|
||||||
import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
|
import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
|
||||||
|
import java.io.CharConversionException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
@ -1143,7 +1144,7 @@ public abstract class AbstractSAXParser
|
|||||||
// wrap XNI exceptions as SAX exceptions
|
// wrap XNI exceptions as SAX exceptions
|
||||||
catch (XMLParseException e) {
|
catch (XMLParseException e) {
|
||||||
Exception ex = e.getException();
|
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
|
// must be a parser exception; mine it for locator info and throw
|
||||||
// a SAXParseException
|
// a SAXParseException
|
||||||
LocatorImpl locatorImpl = new LocatorImpl(){
|
LocatorImpl locatorImpl = new LocatorImpl(){
|
||||||
@ -1163,7 +1164,9 @@ public abstract class AbstractSAXParser
|
|||||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||||
locatorImpl.setLineNumber(e.getLineNumber());
|
locatorImpl.setLineNumber(e.getLineNumber());
|
||||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
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) {
|
if (ex instanceof SAXException) {
|
||||||
// why did we create an XMLParseException?
|
// why did we create an XMLParseException?
|
||||||
@ -1216,7 +1219,7 @@ public abstract class AbstractSAXParser
|
|||||||
// wrap XNI exceptions as SAX exceptions
|
// wrap XNI exceptions as SAX exceptions
|
||||||
catch (XMLParseException e) {
|
catch (XMLParseException e) {
|
||||||
Exception ex = e.getException();
|
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
|
// must be a parser exception; mine it for locator info and throw
|
||||||
// a SAXParseException
|
// a SAXParseException
|
||||||
LocatorImpl locatorImpl = new LocatorImpl() {
|
LocatorImpl locatorImpl = new LocatorImpl() {
|
||||||
@ -1236,7 +1239,9 @@ public abstract class AbstractSAXParser
|
|||||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||||
locatorImpl.setLineNumber(e.getLineNumber());
|
locatorImpl.setLineNumber(e.getLineNumber());
|
||||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
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) {
|
if (ex instanceof SAXException) {
|
||||||
// why did we create an XMLParseException?
|
// 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.XMLInputSource;
|
||||||
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
|
||||||
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
|
||||||
|
import java.io.CharConversionException;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.xml.sax.EntityResolver;
|
import org.xml.sax.EntityResolver;
|
||||||
import org.xml.sax.ErrorHandler;
|
import org.xml.sax.ErrorHandler;
|
||||||
@ -184,7 +185,7 @@ public class DOMParser
|
|||||||
// wrap XNI exceptions as SAX exceptions
|
// wrap XNI exceptions as SAX exceptions
|
||||||
catch (XMLParseException e) {
|
catch (XMLParseException e) {
|
||||||
Exception ex = e.getException();
|
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
|
// must be a parser exception; mine it for locator info and throw
|
||||||
// a SAXParseException
|
// a SAXParseException
|
||||||
LocatorImpl locatorImpl = new LocatorImpl();
|
LocatorImpl locatorImpl = new LocatorImpl();
|
||||||
@ -192,7 +193,9 @@ public class DOMParser
|
|||||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||||
locatorImpl.setLineNumber(e.getLineNumber());
|
locatorImpl.setLineNumber(e.getLineNumber());
|
||||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
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) {
|
if (ex instanceof SAXException) {
|
||||||
// why did we create an XMLParseException?
|
// why did we create an XMLParseException?
|
||||||
@ -246,7 +249,7 @@ public class DOMParser
|
|||||||
// wrap XNI exceptions as SAX exceptions
|
// wrap XNI exceptions as SAX exceptions
|
||||||
catch (XMLParseException e) {
|
catch (XMLParseException e) {
|
||||||
Exception ex = e.getException();
|
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
|
// must be a parser exception; mine it for locator info and throw
|
||||||
// a SAXParseException
|
// a SAXParseException
|
||||||
LocatorImpl locatorImpl = new LocatorImpl();
|
LocatorImpl locatorImpl = new LocatorImpl();
|
||||||
@ -254,7 +257,9 @@ public class DOMParser
|
|||||||
locatorImpl.setSystemId(e.getExpandedSystemId());
|
locatorImpl.setSystemId(e.getExpandedSystemId());
|
||||||
locatorImpl.setLineNumber(e.getLineNumber());
|
locatorImpl.setLineNumber(e.getLineNumber());
|
||||||
locatorImpl.setColumnNumber(e.getColumnNumber());
|
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) {
|
if (ex instanceof SAXException) {
|
||||||
// why did we create an XMLParseException?
|
// 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
|
* 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.URI;
|
||||||
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
|
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.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.XMLResourceIdentifierImpl;
|
||||||
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
|
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.XMLSecurityManager;
|
||||||
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
|
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
|
||||||
import com.sun.org.apache.xerces.internal.xni.Augmentations;
|
import com.sun.org.apache.xerces.internal.xni.Augmentations;
|
||||||
@ -157,8 +157,8 @@ public class XIncludeHandler
|
|||||||
public final static String CURRENT_BASE_URI = "currentBaseURI";
|
public final static String CURRENT_BASE_URI = "currentBaseURI";
|
||||||
|
|
||||||
// used for adding [base URI] attributes
|
// used for adding [base URI] attributes
|
||||||
public final static String XINCLUDE_BASE = "base".intern();
|
private final static String XINCLUDE_BASE = "base".intern();
|
||||||
public final static QName XML_BASE_QNAME =
|
private final static QName XML_BASE_QNAME =
|
||||||
new QName(
|
new QName(
|
||||||
XMLSymbols.PREFIX_XML,
|
XMLSymbols.PREFIX_XML,
|
||||||
XINCLUDE_BASE,
|
XINCLUDE_BASE,
|
||||||
@ -166,15 +166,15 @@ public class XIncludeHandler
|
|||||||
NamespaceContext.XML_URI);
|
NamespaceContext.XML_URI);
|
||||||
|
|
||||||
// used for adding [language] attributes
|
// used for adding [language] attributes
|
||||||
public final static String XINCLUDE_LANG = "lang".intern();
|
private final static String XINCLUDE_LANG = "lang".intern();
|
||||||
public final static QName XML_LANG_QNAME =
|
private final static QName XML_LANG_QNAME =
|
||||||
new QName(
|
new QName(
|
||||||
XMLSymbols.PREFIX_XML,
|
XMLSymbols.PREFIX_XML,
|
||||||
XINCLUDE_LANG,
|
XINCLUDE_LANG,
|
||||||
(XMLSymbols.PREFIX_XML + ":" + XINCLUDE_LANG).intern(),
|
(XMLSymbols.PREFIX_XML + ":" + XINCLUDE_LANG).intern(),
|
||||||
NamespaceContext.XML_URI);
|
NamespaceContext.XML_URI);
|
||||||
|
|
||||||
public final static QName NEW_NS_ATTR_QNAME =
|
private final static QName NEW_NS_ATTR_QNAME =
|
||||||
new QName(
|
new QName(
|
||||||
XMLSymbols.PREFIX_XMLNS,
|
XMLSymbols.PREFIX_XMLNS,
|
||||||
"",
|
"",
|
||||||
@ -217,6 +217,10 @@ public class XIncludeHandler
|
|||||||
protected static final String XINCLUDE_FIXUP_LANGUAGE =
|
protected static final String XINCLUDE_FIXUP_LANGUAGE =
|
||||||
Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
|
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. */
|
/** Property identifier: symbol table. */
|
||||||
protected static final String SYMBOL_TABLE =
|
protected static final String SYMBOL_TABLE =
|
||||||
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
|
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
|
||||||
@ -234,7 +238,7 @@ public class XIncludeHandler
|
|||||||
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
|
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
|
||||||
|
|
||||||
/** property identifier: buffer size. */
|
/** property identifier: buffer size. */
|
||||||
public static final String BUFFER_SIZE =
|
protected static final String BUFFER_SIZE =
|
||||||
Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY;
|
Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY;
|
||||||
|
|
||||||
protected static final String PARSER_SETTINGS =
|
protected static final String PARSER_SETTINGS =
|
||||||
@ -292,6 +296,7 @@ public class XIncludeHandler
|
|||||||
protected XPointerProcessor fXPtrProcessor = null;
|
protected XPointerProcessor fXPtrProcessor = null;
|
||||||
|
|
||||||
protected XMLLocator fDocLocation;
|
protected XMLLocator fDocLocation;
|
||||||
|
protected XMLLocatorWrapper fXIncludeLocator = new XMLLocatorWrapper();
|
||||||
protected XIncludeMessageFormatter fXIncludeMessageFormatter = new XIncludeMessageFormatter();
|
protected XIncludeMessageFormatter fXIncludeMessageFormatter = new XIncludeMessageFormatter();
|
||||||
protected XIncludeNamespaceSupport fNamespaceContext;
|
protected XIncludeNamespaceSupport fNamespaceContext;
|
||||||
protected SymbolTable fSymbolTable;
|
protected SymbolTable fSymbolTable;
|
||||||
@ -305,17 +310,19 @@ public class XIncludeHandler
|
|||||||
protected XIncludeTextReader fXInclude11TextReader;
|
protected XIncludeTextReader fXInclude11TextReader;
|
||||||
|
|
||||||
// these are needed for XML Base processing
|
// these are needed for XML Base processing
|
||||||
protected XMLResourceIdentifier fCurrentBaseURI;
|
protected final XMLResourceIdentifier fCurrentBaseURI;
|
||||||
protected IntStack fBaseURIScope;
|
protected final IntStack fBaseURIScope;
|
||||||
protected Stack<String> fBaseURI;
|
protected final Stack<String> fBaseURI;
|
||||||
protected Stack<String> fLiteralSystemID;
|
protected final Stack<String> fLiteralSystemID;
|
||||||
protected Stack<String> fExpandedSystemID;
|
protected final Stack<String> fExpandedSystemID;
|
||||||
|
|
||||||
// these are needed for Language Fixup
|
// these are needed for Language Fixup
|
||||||
protected IntStack fLanguageScope;
|
protected final IntStack fLanguageScope;
|
||||||
protected Stack<String> fLanguageStack;
|
protected final Stack<String> fLanguageStack;
|
||||||
protected String fCurrentLanguage;
|
protected String fCurrentLanguage;
|
||||||
|
|
||||||
|
protected String fHrefFromParent;
|
||||||
|
|
||||||
// used for passing features on to child XIncludeHandler objects
|
// used for passing features on to child XIncludeHandler objects
|
||||||
protected ParserConfigurationSettings fSettings;
|
protected ParserConfigurationSettings fSettings;
|
||||||
|
|
||||||
@ -361,6 +368,9 @@ public class XIncludeHandler
|
|||||||
// track whether a DTD is being parsed
|
// track whether a DTD is being parsed
|
||||||
private boolean fInDTD;
|
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
|
// track whether the root element of the result infoset has been processed
|
||||||
private boolean fSeenRootElement;
|
private boolean fSeenRootElement;
|
||||||
|
|
||||||
@ -593,15 +603,21 @@ public class XIncludeHandler
|
|||||||
copyFeatures(componentManager, fSettings);
|
copyFeatures(componentManager, fSettings);
|
||||||
|
|
||||||
// We don't want a schema validator on the new pipeline,
|
// We don't want a schema validator on the new pipeline,
|
||||||
// so if it was enabled, we set the feature to false. If
|
// so if it was enabled, we set the feature to false.
|
||||||
// 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.
|
|
||||||
try {
|
try {
|
||||||
if (componentManager.getFeature(SCHEMA_VALIDATION)) {
|
if (componentManager.getFeature(SCHEMA_VALIDATION)) {
|
||||||
fSettings.setFeature(SCHEMA_VALIDATION, false);
|
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);
|
fSettings.setFeature(DYNAMIC_VALIDATION, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -776,7 +792,15 @@ public class XIncludeHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDocumentHandler(XMLDocumentHandler handler) {
|
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
|
@Override
|
||||||
@ -806,36 +830,39 @@ public class XIncludeHandler
|
|||||||
// otherwise, the locator from the root document would always be used
|
// otherwise, the locator from the root document would always be used
|
||||||
fErrorReporter.setDocumentLocator(locator);
|
fErrorReporter.setDocumentLocator(locator);
|
||||||
|
|
||||||
if (!isRootDocument()
|
|
||||||
&& fParentXIncludeHandler.searchForRecursiveIncludes(locator)) {
|
|
||||||
reportFatalError(
|
|
||||||
"RecursiveInclude",
|
|
||||||
new Object[] { locator.getExpandedSystemId()});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
|
if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
|
||||||
reportFatalError("IncompatibleNamespaceContext");
|
reportFatalError("IncompatibleNamespaceContext");
|
||||||
}
|
}
|
||||||
fNamespaceContext = (XIncludeNamespaceSupport)namespaceContext;
|
fNamespaceContext = (XIncludeNamespaceSupport)namespaceContext;
|
||||||
fDocLocation = locator;
|
fDocLocation = locator;
|
||||||
|
fXIncludeLocator.setLocator(fDocLocation);
|
||||||
|
|
||||||
// initialize the current base URI
|
// initialize the current base URI
|
||||||
fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
|
setupCurrentBaseURI(locator);
|
||||||
fCurrentBaseURI.setExpandedSystemId(locator.getExpandedSystemId());
|
|
||||||
fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
|
|
||||||
saveBaseURI();
|
saveBaseURI();
|
||||||
if (augs == null) {
|
if (augs == null) {
|
||||||
augs = new AugmentationsImpl();
|
augs = new AugmentationsImpl();
|
||||||
}
|
}
|
||||||
augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
|
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
|
// initialize the current language
|
||||||
fCurrentLanguage = XMLSymbols.EMPTY_STRING;
|
fCurrentLanguage = XMLSymbols.EMPTY_STRING;
|
||||||
saveLanguage(fCurrentLanguage);
|
saveLanguage(fCurrentLanguage);
|
||||||
|
|
||||||
if (isRootDocument() && fDocumentHandler != null) {
|
if (isRootDocument() && fDocumentHandler != null) {
|
||||||
fDocumentHandler.startDocument(
|
fDocumentHandler.startDocument(
|
||||||
locator,
|
fXIncludeLocator,
|
||||||
encoding,
|
encoding,
|
||||||
namespaceContext,
|
namespaceContext,
|
||||||
augs);
|
augs);
|
||||||
@ -1671,7 +1698,7 @@ public class XIncludeHandler
|
|||||||
catch (IOException | CatalogException e) {
|
catch (IOException | CatalogException e) {
|
||||||
reportResourceError(
|
reportResourceError(
|
||||||
"XMLResourceError",
|
"XMLResourceError",
|
||||||
new Object[] { href, e.getMessage()});
|
new Object[] { href, e.getMessage()}, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1750,6 +1777,8 @@ public class XIncludeHandler
|
|||||||
// ???
|
// ???
|
||||||
|
|
||||||
newHandler.setParent(this);
|
newHandler.setParent(this);
|
||||||
|
newHandler.setHref(href);
|
||||||
|
newHandler.setXIncludeLocator(fXIncludeLocator);
|
||||||
newHandler.setDocumentHandler(this.getDocumentHandler());
|
newHandler.setDocumentHandler(this.getDocumentHandler());
|
||||||
fXPointerChildConfig = fChildConfig;
|
fXPointerChildConfig = fChildConfig;
|
||||||
} else {
|
} else {
|
||||||
@ -1758,7 +1787,8 @@ public class XIncludeHandler
|
|||||||
Constants.XERCES_PROPERTY_PREFIX
|
Constants.XERCES_PROPERTY_PREFIX
|
||||||
+ Constants.XINCLUDE_HANDLER_PROPERTY);
|
+ Constants.XINCLUDE_HANDLER_PROPERTY);
|
||||||
|
|
||||||
newHandler.setParent(this);
|
newHandler.setParent(this);
|
||||||
|
newHandler.setHref(href);
|
||||||
newHandler.setDocumentHandler(this.getDocumentHandler());
|
newHandler.setDocumentHandler(this.getDocumentHandler());
|
||||||
fXIncludeChildConfig = fChildConfig;
|
fXIncludeChildConfig = fChildConfig;
|
||||||
}
|
}
|
||||||
@ -1766,7 +1796,7 @@ public class XIncludeHandler
|
|||||||
|
|
||||||
// If an xpointer attribute is present
|
// If an xpointer attribute is present
|
||||||
if (xpointer != null ) {
|
if (xpointer != null ) {
|
||||||
fChildConfig = fXPointerChildConfig ;
|
fChildConfig = fXPointerChildConfig;
|
||||||
|
|
||||||
// Parse the XPointer expression
|
// Parse the XPointer expression
|
||||||
try {
|
try {
|
||||||
@ -1790,10 +1820,12 @@ public class XIncludeHandler
|
|||||||
fNeedCopyFeatures = false;
|
fNeedCopyFeatures = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
fHasIncludeReportedContent = false;
|
||||||
fNamespaceContext.pushScope();
|
fNamespaceContext.pushScope();
|
||||||
|
|
||||||
fChildConfig.parse(includedSource);
|
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) {
|
if (fErrorReporter != null) {
|
||||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||||
}
|
}
|
||||||
@ -1811,23 +1843,32 @@ public class XIncludeHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (XNIException e) {
|
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) {
|
if (fErrorReporter != null) {
|
||||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||||
}
|
}
|
||||||
reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
|
reportFatalError("XMLParseError", new Object[] { href, e.getMessage() });
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
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) {
|
if (fErrorReporter != null) {
|
||||||
fErrorReporter.setDocumentLocator(fDocLocation);
|
fErrorReporter.setDocumentLocator(fDocLocation);
|
||||||
}
|
}
|
||||||
// An IOException indicates that we had trouble reading the file, not
|
// If the start document event has been seen on the child pipeline it
|
||||||
// that it was an invalid XML file. So we send a resource error, not a
|
// means the resource was successfully opened and we started reporting
|
||||||
// fatal error.
|
// 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(
|
reportResourceError(
|
||||||
"XMLResourceError",
|
"XMLResourceError",
|
||||||
new Object[] { href, e.getMessage()});
|
new Object[] { href, e.getMessage()}, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@ -1841,6 +1882,8 @@ public class XIncludeHandler
|
|||||||
XIncludeTextReader textReader = null;
|
XIncludeTextReader textReader = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
fHasIncludeReportedContent = false;
|
||||||
|
|
||||||
// Setup the appropriate text reader.
|
// Setup the appropriate text reader.
|
||||||
if (!fIsXML11) {
|
if (!fIsXML11) {
|
||||||
if (fXInclude10TextReader == null) {
|
if (fXInclude10TextReader == null) {
|
||||||
@ -1866,16 +1909,22 @@ public class XIncludeHandler
|
|||||||
// encoding errors
|
// encoding errors
|
||||||
catch (MalformedByteSequenceException ex) {
|
catch (MalformedByteSequenceException ex) {
|
||||||
fErrorReporter.reportError(ex.getDomain(), ex.getKey(),
|
fErrorReporter.reportError(ex.getDomain(), ex.getKey(),
|
||||||
ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, ex);
|
||||||
}
|
}
|
||||||
catch (CharConversionException e) {
|
catch (CharConversionException e) {
|
||||||
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
|
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
|
||||||
"CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR);
|
"CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
|
||||||
}
|
}
|
||||||
catch (IOException 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(
|
reportResourceError(
|
||||||
"TextResourceError",
|
"TextResourceError",
|
||||||
new Object[] { href, e.getMessage()});
|
new Object[] { href, e.getMessage()}, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@ -1886,7 +1935,7 @@ public class XIncludeHandler
|
|||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
reportResourceError(
|
reportResourceError(
|
||||||
"TextResourceError",
|
"TextResourceError",
|
||||||
new Object[] { href, e.getMessage()});
|
new Object[] { href, e.getMessage()}, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1977,37 +2026,51 @@ public class XIncludeHandler
|
|||||||
return parentLanguage != null && parentLanguage.equalsIgnoreCase(fCurrentLanguage);
|
return parentLanguage != null && parentLanguage.equalsIgnoreCase(fCurrentLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void setupCurrentBaseURI(XMLLocator locator) {
|
||||||
* Checks if the file indicated by the given XMLLocator has already been included
|
fCurrentBaseURI.setBaseSystemId(locator.getBaseSystemId());
|
||||||
* in the current stack.
|
if (locator.getLiteralSystemId() != null) {
|
||||||
* @param includedSource the source to check for inclusion
|
fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
|
||||||
* @return true if the source has already been included
|
}
|
||||||
*/
|
else {
|
||||||
protected boolean searchForRecursiveIncludes(XMLLocator includedSource) {
|
fCurrentBaseURI.setLiteralSystemId(fHrefFromParent);
|
||||||
String includedSystemId = includedSource.getExpandedSystemId();
|
}
|
||||||
|
|
||||||
if (includedSystemId == null) {
|
String expandedSystemId = locator.getExpandedSystemId();
|
||||||
|
if (expandedSystemId == null) {
|
||||||
|
// attempt to expand it ourselves
|
||||||
try {
|
try {
|
||||||
includedSystemId =
|
expandedSystemId =
|
||||||
XMLEntityManager.expandSystemId(
|
XMLEntityManager.expandSystemId(
|
||||||
includedSource.getLiteralSystemId(),
|
fCurrentBaseURI.getLiteralSystemId(),
|
||||||
includedSource.getBaseSystemId(),
|
fCurrentBaseURI.getBaseSystemId(),
|
||||||
false);
|
false);
|
||||||
|
if (expandedSystemId == null) {
|
||||||
|
expandedSystemId = fCurrentBaseURI.getLiteralSystemId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (MalformedURIException e) {
|
catch (MalformedURIException e) {
|
||||||
reportFatalError("ExpandedSystemId");
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (fParentXIncludeHandler == null) {
|
||||||
if (fParentXIncludeHandler == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return fParentXIncludeHandler.searchForRecursiveIncludes(
|
else {
|
||||||
includedSource);
|
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
|
* unparsed entities are processed as described in the spec, sections 4.5.1 and 4.5.2
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @return
|
* @return the processed XMLAttributes
|
||||||
*/
|
*/
|
||||||
protected XMLAttributes processAttributes(XMLAttributes attributes) {
|
protected XMLAttributes processAttributes(XMLAttributes attributes) {
|
||||||
if (isTopLevelIncludedItem()) {
|
if (isTopLevelIncludedItem()) {
|
||||||
@ -2198,7 +2261,7 @@ public class XIncludeHandler
|
|||||||
return relativeURI;
|
return relativeURI;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (relativeURI.equals("")) {
|
if (relativeURI.length() == 0) {
|
||||||
relativeURI = fCurrentBaseURI.getLiteralSystemId();
|
relativeURI = fCurrentBaseURI.getLiteralSystemId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2207,7 +2270,7 @@ public class XIncludeHandler
|
|||||||
fParentRelativeURI =
|
fParentRelativeURI =
|
||||||
fParentXIncludeHandler.getRelativeBaseURI();
|
fParentXIncludeHandler.getRelativeBaseURI();
|
||||||
}
|
}
|
||||||
if (fParentRelativeURI.equals("")) {
|
if (fParentRelativeURI.length() == 0) {
|
||||||
return relativeURI;
|
return relativeURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2420,7 +2483,7 @@ public class XIncludeHandler
|
|||||||
* as an ancestor of the current item.
|
* as an ancestor of the current item.
|
||||||
*
|
*
|
||||||
* @param depth
|
* @param depth
|
||||||
* @return
|
* @return true if an include was seen at the given depth, false otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean getSawInclude(int depth) {
|
protected boolean getSawInclude(int depth) {
|
||||||
if (depth >= fSawInclude.length) {
|
if (depth >= fSawInclude.length) {
|
||||||
@ -2430,11 +2493,15 @@ public class XIncludeHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void reportResourceError(String key) {
|
protected void reportResourceError(String key) {
|
||||||
this.reportFatalError(key, null);
|
this.reportResourceError(key, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reportResourceError(String key, Object[] args) {
|
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) {
|
protected void reportFatalError(String key) {
|
||||||
@ -2442,16 +2509,21 @@ public class XIncludeHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void reportFatalError(String key, Object[] args) {
|
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) {
|
if (fErrorReporter != null) {
|
||||||
fErrorReporter.reportError(
|
fErrorReporter.reportError(
|
||||||
XIncludeMessageFormatter.XINCLUDE_DOMAIN,
|
XIncludeMessageFormatter.XINCLUDE_DOMAIN,
|
||||||
key,
|
key,
|
||||||
args,
|
args,
|
||||||
severity);
|
severity,
|
||||||
|
exception);
|
||||||
}
|
}
|
||||||
// we won't worry about when error reporter is null, since there should always be
|
// we won't worry about when error reporter is null, since there should always be
|
||||||
// at least the default error reporter
|
// at least the default error reporter
|
||||||
@ -2465,6 +2537,14 @@ public class XIncludeHandler
|
|||||||
fParentXIncludeHandler = parent;
|
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
|
// used to know whether to pass declarations to the document handler
|
||||||
protected boolean isRootDocument() {
|
protected boolean isRootDocument() {
|
||||||
return fParentXIncludeHandler == null;
|
return fParentXIncludeHandler == null;
|
||||||
@ -2849,7 +2929,7 @@ public class XIncludeHandler
|
|||||||
/**
|
/**
|
||||||
* Saves the given language on the top of the stack.
|
* 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) {
|
protected void saveLanguage(String language) {
|
||||||
fLanguageScope.push(fDepth);
|
fLanguageScope.push(fDepth);
|
||||||
@ -3013,7 +3093,7 @@ public class XIncludeHandler
|
|||||||
// the second hex character if a character needs to be escaped
|
// the second hex character if a character needs to be escaped
|
||||||
private static final char gAfterEscaping2[] = new char[128];
|
private static final char gAfterEscaping2[] = new char[128];
|
||||||
private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
|
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
|
// initialize the above 3 arrays
|
||||||
static {
|
static {
|
||||||
char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
|
char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
|
||||||
@ -3104,7 +3184,7 @@ public class XIncludeHandler
|
|||||||
// for each byte
|
// for each byte
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
b = bytes[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) {
|
if (b < 0) {
|
||||||
ch = b + 256;
|
ch = b + 256;
|
||||||
buffer.append('%');
|
buffer.append('%');
|
||||||
@ -3123,7 +3203,7 @@ public class XIncludeHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If escaping happened, create a new string;
|
// If escaping happened, create a new string;
|
||||||
// otherwise, return the orginal one.
|
// otherwise, return the original one.
|
||||||
if (buffer.length() != len) {
|
if (buffer.length() != len) {
|
||||||
return buffer.toString();
|
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
|
* 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.XMLEntityManager;
|
||||||
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
|
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.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.io.UTF8Reader;
|
||||||
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
|
||||||
import com.sun.org.apache.xerces.internal.util.EncodingMap;
|
import com.sun.org.apache.xerces.internal.util.EncodingMap;
|
||||||
@ -67,7 +69,7 @@ import java.util.Map;
|
|||||||
public class XIncludeTextReader {
|
public class XIncludeTextReader {
|
||||||
|
|
||||||
private Reader fReader;
|
private Reader fReader;
|
||||||
private XIncludeHandler fHandler;
|
private final XIncludeHandler fHandler;
|
||||||
private XMLInputSource fSource;
|
private XMLInputSource fSource;
|
||||||
private XMLErrorReporter fErrorReporter;
|
private XMLErrorReporter fErrorReporter;
|
||||||
private XMLString fTempString = new XMLString();
|
private XMLString fTempString = new XMLString();
|
||||||
@ -149,12 +151,12 @@ public class XIncludeTextReader {
|
|||||||
stream = new BufferedInputStream(urlCon.getInputStream());
|
stream = new BufferedInputStream(urlCon.getInputStream());
|
||||||
|
|
||||||
// content type will be string like "text/xml; charset=UTF-8" or "text/xml"
|
// 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
|
// 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;
|
String charset = null;
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
// this should be something like "text/xml"
|
// this should be something like "text/xml"
|
||||||
@ -181,14 +183,16 @@ public class XIncludeTextReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
contentType = rawContentType.trim();
|
contentType = (rawContentType != null) ? rawContentType.trim() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String detectedEncoding = null;
|
String detectedEncoding = null;
|
||||||
/** The encoding of such a resource is determined by:
|
/** The encoding of such a resource is determined by:
|
||||||
1 external encoding information, if available, otherwise
|
1 external encoding information, if available, otherwise
|
||||||
-- the most common type of external information is the "charset" parameter of a MIME package
|
-- 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
|
3 the value of the encoding attribute if one exists, otherwise
|
||||||
4 UTF-8.
|
4 UTF-8.
|
||||||
**/
|
**/
|
||||||
@ -225,15 +229,17 @@ public class XIncludeTextReader {
|
|||||||
// eat the Byte Order Mark
|
// eat the Byte Order Mark
|
||||||
encoding = consumeBOM(stream, encoding);
|
encoding = consumeBOM(stream, encoding);
|
||||||
|
|
||||||
// If the document is UTF-8 or US-ASCII use
|
// If the document is UTF-8, UTF-16, US-ASCII or ISO-8859-1 use
|
||||||
// the Xerces readers for these encodings. For
|
// the Xerces readers for these encodings. For US-ASCII and ISO-8859-1
|
||||||
// US-ASCII consult the encoding map since
|
// consult the encoding map since these encodings have many aliases.
|
||||||
// this encoding has many aliases.
|
|
||||||
if (encoding.equals("UTF-8")) {
|
if (encoding.equals("UTF-8")) {
|
||||||
return new UTF8Reader(stream,
|
return createUTF8Reader(stream);
|
||||||
fTempString.ch.length,
|
}
|
||||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
else if (encoding.equals("UTF-16BE")) {
|
||||||
fErrorReporter.getLocale() );
|
return createUTF16Reader(stream, true);
|
||||||
|
}
|
||||||
|
else if (encoding.equals("UTF-16LE")) {
|
||||||
|
return createUTF16Reader(stream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to use a Java reader.
|
// Try to use a Java reader.
|
||||||
@ -251,16 +257,45 @@ public class XIncludeTextReader {
|
|||||||
new Object[] {encoding} ) );
|
new Object[] {encoding} ) );
|
||||||
}
|
}
|
||||||
else if (javaEncoding.equals("ASCII")) {
|
else if (javaEncoding.equals("ASCII")) {
|
||||||
return new ASCIIReader(stream,
|
return createASCIIReader(stream);
|
||||||
fTempString.ch.length,
|
}
|
||||||
fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN),
|
else if (javaEncoding.equals("ISO8859_1")) {
|
||||||
fErrorReporter.getLocale() );
|
return createLatin1Reader(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InputStreamReader(stream, javaEncoding);
|
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
|
* 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
|
* 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);
|
fReader = getReader(fSource);
|
||||||
fSource = null;
|
fSource = null;
|
||||||
int readSize = fReader.read(fTempString.ch, 0, fTempString.ch.length - 1);
|
int readSize = fReader.read(fTempString.ch, 0, fTempString.ch.length - 1);
|
||||||
|
fHandler.fHasIncludeReportedContent = true;
|
||||||
while (readSize != -1) {
|
while (readSize != -1) {
|
||||||
for (int i = 0; i < readSize; ++i) {
|
for (int i = 0; i < readSize; ++i) {
|
||||||
char ch = fTempString.ch[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