8276050: XMLInputFactoryImpl.getProperty() returns null

Reviewed-by: rriggs
This commit is contained in:
Joe Wang 2022-04-04 20:00:36 +00:00
parent 7381868afe
commit 61d06c2d28
2 changed files with 164 additions and 71 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,6 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package com.sun.org.apache.xerces.internal.impl; package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
@ -39,29 +38,31 @@ import jdk.xml.internal.JdkProperty;
import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.JdkXmlUtils;
/** /**
* This class manages different properties related to Stax specification and its implementation. * This class manages the properties for the Stax specification and its
* This class constructor also takes itself (PropertyManager object) as parameter and initializes the * implementation. A PropertyManager object can be constructed based on the
* object with the property taken from the object passed. * context or initialized with another PropertyManager object.
* *
* @author Neeraj Bajaj * @author Neeraj Bajaj
* @author K Venugopal * @author K Venugopal
* @author Sunitha Reddy * @author Sunitha Reddy
*/ */
public class PropertyManager { public class PropertyManager {
public static final String STAX_NOTATIONS = "javax.xml.stream.notations"; public static final String STAX_NOTATIONS = "javax.xml.stream.notations";
public static final String STAX_ENTITIES = "javax.xml.stream.entities"; public static final String STAX_ENTITIES = "javax.xml.stream.entities";
private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning"; private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
/** Property identifier: Security manager. */ /**
* Property identifier: Security manager.
*/
private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER; private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
/** Property identifier: Security property manager. */ /**
private static final String XML_SECURITY_PROPERTY_MANAGER = * Property identifier: Security property manager.
JdkConstants.XML_SECURITY_PROPERTY_MANAGER; */
private static final String XML_SECURITY_PROPERTY_MANAGER
= JdkConstants.XML_SECURITY_PROPERTY_MANAGER;
HashMap<String, Object> supportedProps = new HashMap<>(); HashMap<String, Object> supportedProps = new HashMap<>();
@ -71,14 +72,18 @@ public class PropertyManager {
public static final int CONTEXT_READER = 1; public static final int CONTEXT_READER = 1;
public static final int CONTEXT_WRITER = 2; public static final int CONTEXT_WRITER = 2;
/** Creates a new instance of PropertyManager */ /**
* Creates a new instance of the PropertyManager based on the context.
*
* @param context a flag indicating the context: for a reader or writer.
*/
public PropertyManager(int context) { public PropertyManager(int context) {
switch(context){ switch (context) {
case CONTEXT_READER:{ case CONTEXT_READER: {
initConfigurableReaderProperties(); initConfigurableReaderProperties();
break; break;
} }
case CONTEXT_WRITER:{ case CONTEXT_WRITER: {
initWriterProps(); initWriterProps();
break; break;
} }
@ -86,28 +91,29 @@ public class PropertyManager {
} }
/** /**
* Initialize this object with the properties taken from passed PropertyManager object. * Initializes the object with the properties of another
* PropertyManager object.
*
* @param propertyManager another PropertyManager object
*/ */
public PropertyManager(PropertyManager propertyManager){ public PropertyManager(PropertyManager propertyManager) {
HashMap<String, Object> properties = propertyManager.getProperties(); HashMap<String, Object> properties = propertyManager.getProperties();
supportedProps.putAll(properties); supportedProps.putAll(properties);
fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER); fSecurityManager = (XMLSecurityManager) getProperty(SECURITY_MANAGER);
fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER); fSecurityPropertyMgr = (XMLSecurityPropertyManager) getProperty(XML_SECURITY_PROPERTY_MANAGER);
} }
private HashMap<String, Object> getProperties(){ private HashMap<String, Object> getProperties() {
return supportedProps ; return supportedProps;
} }
/** /**
* Important point: * Initializes reader properties.
* 1. We are not exposing Xerces namespace property. Application should configure namespace through
* Stax specific property.
* *
* @implNote: StAX defined namespace rather than Xerces' should be used.
*/ */
private void initConfigurableReaderProperties(){ private void initConfigurableReaderProperties() {
//spec default values //spec default values
supportedProps.put(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE); supportedProps.put(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
supportedProps.put(XMLInputFactory.IS_VALIDATING, Boolean.FALSE); supportedProps.put(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
@ -118,18 +124,18 @@ public class PropertyManager {
supportedProps.put(XMLInputFactory.REPORTER, null); supportedProps.put(XMLInputFactory.REPORTER, null);
supportedProps.put(XMLInputFactory.RESOLVER, null); supportedProps.put(XMLInputFactory.RESOLVER, null);
supportedProps.put(XMLInputFactory.ALLOCATOR, null); supportedProps.put(XMLInputFactory.ALLOCATOR, null);
supportedProps.put(STAX_NOTATIONS,null ); supportedProps.put(STAX_NOTATIONS, null);
//zephyr (implementation) specific properties which can be set by the application. //zephyr (implementation) specific properties which can be set by the application.
//interning is always done //interning is always done
supportedProps.put(Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE , true); supportedProps.put(Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE, true);
//recognizing java encoding names by default //recognizing java encoding names by default
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE, true) ; supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE, true);
//in stax mode, namespace declarations are not added as attributes //in stax mode, namespace declarations are not added as attributes
supportedProps.put(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE , Boolean.FALSE) ; supportedProps.put(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE, Boolean.FALSE);
supportedProps.put(Constants.READER_IN_DEFINED_STATE, true); supportedProps.put(Constants.READER_IN_DEFINED_STATE, true);
supportedProps.put(Constants.REUSE_INSTANCE, true); supportedProps.put(Constants.REUSE_INSTANCE, true);
supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT , false); supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT, false);
supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD, Boolean.FALSE); supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD, Boolean.FALSE);
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, false); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, false);
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, false); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, false);
@ -142,61 +148,89 @@ public class PropertyManager {
// Initialize Catalog features // Initialize Catalog features
supportedProps.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); supportedProps.put(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT);
for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) { for (CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
supportedProps.put(f.getPropertyName(), null); supportedProps.put(f.getPropertyName(), null);
} }
supportedProps.put(JdkConstants.CDATA_CHUNK_SIZE, JdkConstants.CDATA_CHUNK_SIZE_DEFAULT); supportedProps.put(JdkConstants.CDATA_CHUNK_SIZE, JdkConstants.CDATA_CHUNK_SIZE_DEFAULT);
} }
private void initWriterProps(){ /**
supportedProps.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES , Boolean.FALSE); * Initializes writer properties.
*/
private void initWriterProps() {
supportedProps.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.FALSE);
//default value of escaping characters is 'true' //default value of escaping characters is 'true'
supportedProps.put(Constants.ESCAPE_CHARACTERS , Boolean.TRUE); supportedProps.put(Constants.ESCAPE_CHARACTERS, Boolean.TRUE);
supportedProps.put(Constants.REUSE_INSTANCE, true); supportedProps.put(Constants.REUSE_INSTANCE, true);
} }
/** /**
* public void reset(){ * Checks whether a property is managed by the PropertyManager.
* supportedProps.clear() ; *
* } * @param property the name of a property
* @return true if the property is managed by the PropertyManager, false
* otherwise
*/ */
public boolean containsProperty(String property){ public boolean containsProperty(String property) {
return supportedProps.containsKey(property) || return supportedProps.containsKey(property)
(fSecurityManager != null && fSecurityManager.getIndex(property) > -1) || || (fSecurityManager != null && fSecurityManager.getIndex(property) > -1)
(fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ; || (fSecurityPropertyMgr != null && fSecurityPropertyMgr.getIndex(property) > -1);
} }
public Object getProperty(String property){ /**
/** Check to see if the property is managed by the security manager **/ * Returns the value of a property.
String propertyValue = (fSecurityManager != null) ? *
fSecurityManager.getLimitAsString(property) : null; * @param property the name of the property
* @return the value of a property
*/
public Object getProperty(String property) {
/**
* Check to see if the property is managed by the security manager *
*/
String propertyValue = (fSecurityManager != null)
? fSecurityManager.getLimitAsString(property) : null;
/**
* Check to see if the property is managed by the security property
* manager
*/
if (propertyValue == null) {
propertyValue = (fSecurityPropertyMgr != null)
? fSecurityPropertyMgr.getValue(property) : null;
}
return propertyValue != null ? propertyValue : supportedProps.get(property); return propertyValue != null ? propertyValue : supportedProps.get(property);
} }
public void setProperty(String property, Object value){ /**
String equivalentProperty = null ; * Sets a property value.
if(property.equals(XMLInputFactory.IS_NAMESPACE_AWARE)){ *
equivalentProperty = Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE ; * @param property the name of the property
} * @param value the value of the property
else if(property.equals(XMLInputFactory.IS_VALIDATING)){ */
if( (value instanceof Boolean) && ((Boolean)value).booleanValue()){ public void setProperty(String property, Object value) {
throw new java.lang.IllegalArgumentException("true value of isValidating not supported") ; String equivalentProperty = null;
if (property.equals(XMLInputFactory.IS_NAMESPACE_AWARE)) {
equivalentProperty = Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
} else if (property.equals(XMLInputFactory.IS_VALIDATING)) {
if ((value instanceof Boolean) && ((Boolean) value)) {
throw new IllegalArgumentException("true value of isValidating not supported");
} }
} } else if (property.equals(STRING_INTERNING)) {
else if(property.equals(STRING_INTERNING)){ if ((value instanceof Boolean) && !((Boolean) value)) {
if( (value instanceof Boolean) && !((Boolean)value).booleanValue()){ throw new IllegalArgumentException("false value of " +
throw new java.lang.IllegalArgumentException("false value of " + STRING_INTERNING + "feature is not supported") ; STRING_INTERNING + "feature is not supported");
} }
} } else if (property.equals(XMLInputFactory.RESOLVER)) {
else if(property.equals(XMLInputFactory.RESOLVER)){
//add internal stax property //add internal stax property
supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; supportedProps.put(Constants.XERCES_PROPERTY_PREFIX +
Constants.STAX_ENTITY_RESOLVER_PROPERTY,
new StaxEntityResolverWrapper((XMLResolver) value));
} }
/** /**
* It's possible for users to set a security manager through the interface. * It's possible for users to set a security manager through the
* If it's the old SecurityManager, convert it to the new XMLSecurityManager * interface. If it's the old SecurityManager, convert it to the new
* XMLSecurityManager
*/ */
if (property.equals(Constants.SECURITY_MANAGER)) { if (property.equals(Constants.SECURITY_MANAGER)) {
fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager); fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager);
@ -207,29 +241,30 @@ public class PropertyManager {
if (value == null) { if (value == null) {
fSecurityPropertyMgr = new XMLSecurityPropertyManager(); fSecurityPropertyMgr = new XMLSecurityPropertyManager();
} else { } else {
fSecurityPropertyMgr = (XMLSecurityPropertyManager)value; fSecurityPropertyMgr = (XMLSecurityPropertyManager) value;
} }
supportedProps.put(JdkConstants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); supportedProps.put(JdkConstants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
return; return;
} }
//check if the property is managed by security manager //check if the property is managed by security manager
if (fSecurityManager == null || if (fSecurityManager == null
!fSecurityManager.setLimit(property, JdkProperty.State.APIPROPERTY, value)) { || !fSecurityManager.setLimit(property, JdkProperty.State.APIPROPERTY, value)) {
//check if the property is managed by security property manager //check if the property is managed by security property manager
if (fSecurityPropertyMgr == null || if (fSecurityPropertyMgr == null
!fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) { || !fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
//fall back to the existing property manager //fall back to the existing property manager
supportedProps.put(property, value); supportedProps.put(property, value);
} }
} }
if(equivalentProperty != null){ if (equivalentProperty != null) {
supportedProps.put(equivalentProperty, value ) ; supportedProps.put(equivalentProperty, value);
} }
} }
public String toString(){ @Override
public String toString() {
return supportedProps.toString(); return supportedProps.toString();
} }

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2022, 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.
*/
package stream.XMLInputFactoryTest;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLInputFactory;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/*
* @test
* @bug 8276050
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm stream.XMLInputFactoryTest.InputFactoryTest
* @summary Test XMLInputFactory functionalities.
*/
public class InputFactoryTest {
@DataProvider(name = "AEProperties")
public Object[][] getAEProperties() throws Exception {
return new Object[][]{
{XMLConstants.ACCESS_EXTERNAL_DTD, "all", "all"},
{XMLConstants.ACCESS_EXTERNAL_SCHEMA, "all", "all"},
{XMLConstants.ACCESS_EXTERNAL_DTD, "", ""},
{XMLConstants.ACCESS_EXTERNAL_SCHEMA, "", ""},
};
}
/*
* Verifies that the XMLInputFactory returns security properties correctly.
*/
@Test(dataProvider = "AEProperties")
public void testProperty(String name, String value, String expected) {
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);
Assert.assertEquals(expected, (String)xif.getProperty(name));
}
}