mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
Merge
Reviewed-by: kcr, prr
This commit is contained in:
commit
b68fa4354c
@ -132,8 +132,16 @@ bool StackMapTable::match_stackmap(
|
||||
}
|
||||
|
||||
void StackMapTable::check_jump_target(
|
||||
StackMapFrame* frame, int32_t target, TRAPS) const {
|
||||
StackMapFrame* frame, int bci, int offset, TRAPS) const {
|
||||
ErrorContext ctx;
|
||||
// Jump targets must be within the method and the method size is limited. See JVMS 4.11
|
||||
int min_offset = -1 * max_method_code_size;
|
||||
if (offset < min_offset || offset > max_method_code_size) {
|
||||
frame->verifier()->verify_error(ErrorContext::bad_stackmap(bci, frame),
|
||||
"Illegal target of jump or branch (bci %d + offset %d)", bci, offset);
|
||||
return;
|
||||
}
|
||||
int target = bci + offset;
|
||||
bool match = match_stackmap(
|
||||
frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
|
||||
if (!match || (target < 0 || target >= _code_length)) {
|
||||
|
||||
@ -67,7 +67,7 @@ class StackMapTable : public StackObj {
|
||||
|
||||
// Check jump instructions. Make sure there are no uninitialized
|
||||
// instances on backward branch.
|
||||
void check_jump_target(StackMapFrame* frame, int32_t target, TRAPS) const;
|
||||
void check_jump_target(StackMapFrame* frame, int bci, int offset, TRAPS) const;
|
||||
|
||||
// The following methods are only used inside this class.
|
||||
|
||||
|
||||
@ -781,7 +781,6 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
|
||||
|
||||
// Merge with the next instruction
|
||||
{
|
||||
int target;
|
||||
VerificationType type, type2;
|
||||
VerificationType atype;
|
||||
|
||||
@ -1606,9 +1605,8 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
|
||||
case Bytecodes::_ifle:
|
||||
current_frame.pop_stack(
|
||||
VerificationType::integer_type(), CHECK_VERIFY(this));
|
||||
target = bcs.dest();
|
||||
stackmap_table.check_jump_target(
|
||||
¤t_frame, target, CHECK_VERIFY(this));
|
||||
¤t_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
|
||||
no_control_flow = false; break;
|
||||
case Bytecodes::_if_acmpeq :
|
||||
case Bytecodes::_if_acmpne :
|
||||
@ -1619,19 +1617,16 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
|
||||
case Bytecodes::_ifnonnull :
|
||||
current_frame.pop_stack(
|
||||
VerificationType::reference_check(), CHECK_VERIFY(this));
|
||||
target = bcs.dest();
|
||||
stackmap_table.check_jump_target
|
||||
(¤t_frame, target, CHECK_VERIFY(this));
|
||||
(¤t_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
|
||||
no_control_flow = false; break;
|
||||
case Bytecodes::_goto :
|
||||
target = bcs.dest();
|
||||
stackmap_table.check_jump_target(
|
||||
¤t_frame, target, CHECK_VERIFY(this));
|
||||
¤t_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
|
||||
no_control_flow = true; break;
|
||||
case Bytecodes::_goto_w :
|
||||
target = bcs.dest_w();
|
||||
stackmap_table.check_jump_target(
|
||||
¤t_frame, target, CHECK_VERIFY(this));
|
||||
¤t_frame, bcs.bci(), bcs.get_offset_s4(), CHECK_VERIFY(this));
|
||||
no_control_flow = true; break;
|
||||
case Bytecodes::_tableswitch :
|
||||
case Bytecodes::_lookupswitch :
|
||||
@ -2280,15 +2275,14 @@ void ClassVerifier::verify_switch(
|
||||
}
|
||||
}
|
||||
}
|
||||
int target = bci + default_offset;
|
||||
stackmap_table->check_jump_target(current_frame, target, CHECK_VERIFY(this));
|
||||
stackmap_table->check_jump_target(current_frame, bci, default_offset, CHECK_VERIFY(this));
|
||||
for (int i = 0; i < keys; i++) {
|
||||
// Because check_jump_target() may safepoint, the bytecode could have
|
||||
// moved, which means 'aligned_bcp' is no good and needs to be recalculated.
|
||||
aligned_bcp = align_up(bcs->bcp() + 1, jintSize);
|
||||
target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
|
||||
int offset = (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
|
||||
stackmap_table->check_jump_target(
|
||||
current_frame, target, CHECK_VERIFY(this));
|
||||
current_frame, bci, offset, CHECK_VERIFY(this));
|
||||
}
|
||||
NOT_PRODUCT(aligned_bcp = nullptr); // no longer valid at this point
|
||||
}
|
||||
|
||||
@ -100,8 +100,23 @@ class BaseBytecodeStream: StackObj {
|
||||
void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; }
|
||||
|
||||
// Bytecode-specific attributes
|
||||
int dest() const { return bci() + bytecode().get_offset_s2(raw_code()); }
|
||||
int dest_w() const { return bci() + bytecode().get_offset_s4(raw_code()); }
|
||||
int get_offset_s2() const { return bytecode().get_offset_s2(raw_code()); }
|
||||
int get_offset_s4() const { return bytecode().get_offset_s4(raw_code()); }
|
||||
|
||||
// These methods are not safe to use before or during verification as they may
|
||||
// have large offsets and cause overflows
|
||||
int dest() const {
|
||||
int min_offset = -1 * max_method_code_size;
|
||||
int offset = bytecode().get_offset_s2(raw_code());
|
||||
guarantee(offset >= min_offset && offset <= max_method_code_size, "must be");
|
||||
return bci() + offset;
|
||||
}
|
||||
int dest_w() const {
|
||||
int min_offset = -1 * max_method_code_size;
|
||||
int offset = bytecode().get_offset_s4(raw_code());
|
||||
guarantee(offset >= min_offset && offset <= max_method_code_size, "must be");
|
||||
return bci() + offset;
|
||||
}
|
||||
|
||||
// One-byte indices.
|
||||
u1 get_index_u1() const { assert_raw_index_size(1); return *(jubyte*)(bcp()+1); }
|
||||
|
||||
@ -1448,8 +1448,8 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence
|
||||
shift(currValue, coder, count, dstOffset, len);
|
||||
count += len;
|
||||
// Coder of CharSequence may be a mismatch, requiring the value array to be inflated
|
||||
byte[] newValue = (s instanceof String str)
|
||||
? putStringAt(currValue, coder, count, dstOffset, str, start, end)
|
||||
byte[] newValue = (s instanceof String str && str.length() == len)
|
||||
? putStringAt(currValue, coder, count, dstOffset, str)
|
||||
: putCharsAt(currValue, coder, count, dstOffset, s, start, end);
|
||||
if (currValue != newValue) {
|
||||
this.coder = UTF16;
|
||||
@ -1928,10 +1928,10 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence
|
||||
* @param index the index to insert the string
|
||||
* @param str the string
|
||||
*/
|
||||
private static byte[] putStringAt(byte[] value, byte coder, int count, int index, String str, int off, int end) {
|
||||
private static byte[] putStringAt(byte[] value, byte coder, int count, int index, String str) {
|
||||
byte[] newValue = inflateIfNeededFor(value, count, coder, str.coder());
|
||||
coder = (newValue == value) ? coder : UTF16;
|
||||
str.getBytes(newValue, off, index, coder, end - off);
|
||||
str.getBytes(newValue, 0, index, coder, str.length());
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
@ -859,6 +859,22 @@ public class DerValue {
|
||||
return readStringInternal(tag_UniversalString, new UTF_32BE());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the BMPString does not contain any surrogate characters,
|
||||
* which are outside the Basic Multilingual Plane.
|
||||
*
|
||||
* @throws IOException if illegal characters are detected
|
||||
*/
|
||||
public void validateBMPString() throws IOException {
|
||||
String bmpString = getBMPString();
|
||||
for (int i = 0; i < bmpString.length(); i++) {
|
||||
if (Character.isSurrogate(bmpString.charAt(i))) {
|
||||
throw new IOException(
|
||||
"Illegal character in BMPString, index: " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the ASN.1 NULL value
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2025, 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
|
||||
@ -28,10 +28,13 @@ package sun.security.x509;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.Normalizer;
|
||||
import java.util.*;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.ISO_8859_1;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.nio.charset.StandardCharsets.UTF_16BE;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.pkcs.PKCS9Attribute;
|
||||
@ -589,6 +592,10 @@ public class AVA implements DerEncoder {
|
||||
throw new IOException("AVA, extra bytes = "
|
||||
+ derval.data.available());
|
||||
}
|
||||
|
||||
if (value.tag == DerValue.tag_BMPString) {
|
||||
value.validateBMPString();
|
||||
}
|
||||
}
|
||||
|
||||
AVA(DerInputStream in) throws IOException {
|
||||
@ -713,7 +720,8 @@ public class AVA implements DerEncoder {
|
||||
* NOTE: this implementation only emits DirectoryStrings of the
|
||||
* types returned by isDerString().
|
||||
*/
|
||||
String valStr = new String(value.getDataBytes(), UTF_8);
|
||||
String valStr =
|
||||
new String(value.getDataBytes(), getCharset(value, false));
|
||||
|
||||
/*
|
||||
* 2.4 (cont): If the UTF-8 string does not have any of the
|
||||
@ -832,7 +840,8 @@ public class AVA implements DerEncoder {
|
||||
* NOTE: this implementation only emits DirectoryStrings of the
|
||||
* types returned by isDerString().
|
||||
*/
|
||||
String valStr = new String(value.getDataBytes(), UTF_8);
|
||||
String valStr =
|
||||
new String(value.getDataBytes(), getCharset(value, true));
|
||||
|
||||
/*
|
||||
* 2.4 (cont): If the UTF-8 string does not have any of the
|
||||
@ -927,6 +936,39 @@ public class AVA implements DerEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the charset that should be used to decode each DN string type.
|
||||
*
|
||||
* This method ensures that multi-byte (UTF8String and BMPString) types
|
||||
* are decoded using the correct charset and the String forms represent
|
||||
* the correct characters. For 8-bit ASCII-based types (PrintableString
|
||||
* and IA5String), we return ISO_8859_1 rather than ASCII, so that the
|
||||
* complete range of characters can be represented, as many certificates
|
||||
* do not comply with the Internationalized Domain Name ACE format.
|
||||
*
|
||||
* NOTE: this method only supports DirectoryStrings of the types returned
|
||||
* by isDerString().
|
||||
*/
|
||||
private static Charset getCharset(DerValue value, boolean canonical) {
|
||||
if (canonical) {
|
||||
return switch (value.tag) {
|
||||
case DerValue.tag_PrintableString -> ISO_8859_1;
|
||||
case DerValue.tag_UTF8String -> UTF_8;
|
||||
default -> throw new Error("unexpected tag: " + value.tag);
|
||||
};
|
||||
}
|
||||
|
||||
return switch (value.tag) {
|
||||
case DerValue.tag_PrintableString,
|
||||
DerValue.tag_T61String,
|
||||
DerValue.tag_IA5String,
|
||||
DerValue.tag_GeneralString -> ISO_8859_1;
|
||||
case DerValue.tag_BMPString -> UTF_16BE;
|
||||
case DerValue.tag_UTF8String -> UTF_8;
|
||||
default -> throw new Error("unexpected tag: " + value.tag);
|
||||
};
|
||||
}
|
||||
|
||||
boolean hasRFC2253Keyword() {
|
||||
return AVAKeyword.hasKeyword(oid, RFC2253);
|
||||
}
|
||||
|
||||
@ -395,7 +395,8 @@ static jboolean is_superclass(context_type *, fullinfo_type);
|
||||
|
||||
static void initialize_exception_table(context_type *);
|
||||
static int instruction_length(unsigned char *iptr, unsigned char *end);
|
||||
static jboolean isLegalTarget(context_type *, int offset);
|
||||
static jboolean isLegalOffset(context_type *, int bci, int offset);
|
||||
static jboolean isLegalTarget(context_type *, int target);
|
||||
static void verify_constant_pool_type(context_type *, int, unsigned);
|
||||
|
||||
static void initialize_dataflow(context_type *);
|
||||
@ -1154,9 +1155,9 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
|
||||
case JVM_OPC_goto: {
|
||||
/* Set the ->operand to be the instruction number of the target. */
|
||||
int jump = (((signed char)(code[offset+1])) << 8) + code[offset+2];
|
||||
int target = offset + jump;
|
||||
if (!isLegalTarget(context, target))
|
||||
if (!isLegalOffset(context, offset, jump))
|
||||
CCerror(context, "Illegal target of jump or branch");
|
||||
int target = offset + jump;
|
||||
this_idata->operand.i = code_data[target];
|
||||
break;
|
||||
}
|
||||
@ -1170,9 +1171,9 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
|
||||
int jump = (((signed char)(code[offset+1])) << 24) +
|
||||
(code[offset+2] << 16) + (code[offset+3] << 8) +
|
||||
(code[offset + 4]);
|
||||
int target = offset + jump;
|
||||
if (!isLegalTarget(context, target))
|
||||
if (!isLegalOffset(context, offset, jump))
|
||||
CCerror(context, "Illegal target of jump or branch");
|
||||
int target = offset + jump;
|
||||
this_idata->operand.i = code_data[target];
|
||||
break;
|
||||
}
|
||||
@ -1211,13 +1212,16 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
|
||||
}
|
||||
}
|
||||
saved_operand = NEW(int, keys + 2);
|
||||
if (!isLegalTarget(context, offset + _ck_ntohl(lpc[0])))
|
||||
int jump = _ck_ntohl(lpc[0]);
|
||||
if (!isLegalOffset(context, offset, jump))
|
||||
CCerror(context, "Illegal default target in switch");
|
||||
saved_operand[keys + 1] = code_data[offset + _ck_ntohl(lpc[0])];
|
||||
int target = offset + jump;
|
||||
saved_operand[keys + 1] = code_data[target];
|
||||
for (k = keys, lptr = &lpc[3]; --k >= 0; lptr += delta) {
|
||||
int target = offset + _ck_ntohl(lptr[0]);
|
||||
if (!isLegalTarget(context, target))
|
||||
jump = _ck_ntohl(lptr[0]);
|
||||
if (!isLegalOffset(context, offset, jump))
|
||||
CCerror(context, "Illegal branch in tableswitch");
|
||||
target = offset + jump;
|
||||
saved_operand[k + 1] = code_data[target];
|
||||
}
|
||||
saved_operand[0] = keys + 1; /* number of successors */
|
||||
@ -1746,11 +1750,24 @@ static int instruction_length(unsigned char *iptr, unsigned char *end)
|
||||
|
||||
/* Given the target of a branch, make sure that it's a legal target. */
|
||||
static jboolean
|
||||
isLegalTarget(context_type *context, int offset)
|
||||
isLegalTarget(context_type *context, int target)
|
||||
{
|
||||
int code_length = context->code_length;
|
||||
int *code_data = context->code_data;
|
||||
return (offset >= 0 && offset < code_length && code_data[offset] >= 0);
|
||||
return (target >= 0 && target < code_length && code_data[target] >= 0);
|
||||
}
|
||||
|
||||
/* Given a bci and offset, make sure the offset is valid and the target is legal */
|
||||
static jboolean
|
||||
isLegalOffset(context_type *context, int bci, int offset)
|
||||
{
|
||||
int code_length = context->code_length;
|
||||
int *code_data = context->code_data;
|
||||
int max_offset = 65535; // JVMS 4.11
|
||||
int min_offset = -65535;
|
||||
if (offset < min_offset || offset > max_offset) return JNI_FALSE;
|
||||
int target = bci + offset;
|
||||
return (target >= 0 && target < code_length && code_data[target] >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ import org.xml.sax.SAXNotSupportedException;
|
||||
/**
|
||||
* @author Rajiv Mordani
|
||||
* @author Edwin Goei
|
||||
* @LastModified: May 2025
|
||||
* @LastModified: June 2025
|
||||
*/
|
||||
public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
|
||||
/** These are DocumentBuilderFactory attributes not DOM attributes */
|
||||
@ -59,11 +59,24 @@ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory {
|
||||
XMLSecurityManager fSecurityManager;
|
||||
XMLSecurityPropertyManager fSecurityPropertyMgr;
|
||||
|
||||
/**
|
||||
* Creates a new {@code DocumentBuilderFactory} instance.
|
||||
*/
|
||||
public DocumentBuilderFactoryImpl() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code DocumentBuilderFactory} instance with a {@code XMLSecurityManager}
|
||||
* and {@code XMLSecurityPropertyManager}.
|
||||
* @param xsm the {@code XMLSecurityManager}
|
||||
* @param xspm the {@code XMLSecurityPropertyManager}
|
||||
*/
|
||||
public DocumentBuilderFactoryImpl(XMLSecurityManager xsm, XMLSecurityPropertyManager xspm) {
|
||||
JdkXmlConfig config = JdkXmlConfig.getInstance(false);
|
||||
// security (property) managers updated with current system properties
|
||||
fSecurityManager = config.getXMLSecurityManager(true);
|
||||
fSecurityPropertyMgr = config.getXMLSecurityPropertyManager(true);
|
||||
fSecurityManager = (xsm == null) ? config.getXMLSecurityManager(true) : xsm;
|
||||
fSecurityPropertyMgr = (xspm == null) ? config.getXMLSecurityPropertyManager(true) : xspm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -35,7 +35,7 @@ import jdk.xml.internal.*;
|
||||
*
|
||||
* @author Ramesh Mandava
|
||||
*
|
||||
* @LastModified: May 2025
|
||||
* @LastModified: June 2025
|
||||
*/
|
||||
public class XPathFactoryImpl extends XPathFactory {
|
||||
|
||||
@ -72,6 +72,7 @@ public class XPathFactoryImpl extends XPathFactory {
|
||||
* The XML security manager
|
||||
*/
|
||||
private XMLSecurityManager _xmlSecMgr;
|
||||
private XMLSecurityPropertyManager _xmlSecPropMgr;
|
||||
|
||||
/**
|
||||
* javax.xml.xpath.XPathFactory implementation.
|
||||
@ -80,6 +81,7 @@ public class XPathFactoryImpl extends XPathFactory {
|
||||
JdkXmlConfig config = JdkXmlConfig.getInstance(false);
|
||||
_xmlSecMgr = config.getXMLSecurityManager(true);
|
||||
_featureManager = config.getXMLFeatures(true);
|
||||
_xmlSecPropMgr = config.getXMLSecurityPropertyManager(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,7 +131,7 @@ public class XPathFactoryImpl extends XPathFactory {
|
||||
*/
|
||||
public javax.xml.xpath.XPath newXPath() {
|
||||
return new XPathImpl(xPathVariableResolver, xPathFunctionResolver,
|
||||
!_isNotSecureProcessing, _featureManager, _xmlSecMgr);
|
||||
!_isNotSecureProcessing, _featureManager, _xmlSecMgr, _xmlSecPropMgr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,6 +185,7 @@ public class XPathFactoryImpl extends XPathFactory {
|
||||
if (value && _featureManager != null) {
|
||||
_featureManager.setFeature(JdkXmlFeatures.XmlFeature.ENABLE_EXTENSION_FUNCTION,
|
||||
JdkProperty.State.FSP, false);
|
||||
_xmlSecMgr.setSecureProcessing(value);
|
||||
}
|
||||
|
||||
// all done processing feature
|
||||
@ -338,8 +341,7 @@ public class XPathFactoryImpl extends XPathFactory {
|
||||
throw new NullPointerException(fmsg);
|
||||
}
|
||||
|
||||
if (_xmlSecMgr != null &&
|
||||
_xmlSecMgr.setLimit(name, JdkProperty.State.APIPROPERTY, value)) {
|
||||
if (JdkXmlUtils.setProperty(_xmlSecMgr, _xmlSecPropMgr, name, value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ import javax.xml.xpath.XPathVariableResolver;
|
||||
import jdk.xml.internal.JdkXmlConfig;
|
||||
import jdk.xml.internal.JdkXmlFeatures;
|
||||
import jdk.xml.internal.XMLSecurityManager;
|
||||
import jdk.xml.internal.XMLSecurityPropertyManager;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
@ -50,7 +51,7 @@ import org.xml.sax.InputSource;
|
||||
* New methods: evaluateExpression
|
||||
* Refactored to share code with XPathExpressionImpl.
|
||||
*
|
||||
* @LastModified: May 2025
|
||||
* @LastModified: June 2025
|
||||
*/
|
||||
public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
|
||||
|
||||
@ -62,12 +63,13 @@ public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
|
||||
XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
|
||||
this(vr, fr, false,
|
||||
JdkXmlConfig.getInstance(false).getXMLFeatures(false),
|
||||
JdkXmlConfig.getInstance(false).getXMLSecurityManager(false));
|
||||
JdkXmlConfig.getInstance(false).getXMLSecurityManager(false),
|
||||
JdkXmlConfig.getInstance(false).getXMLSecurityPropertyManager(false));
|
||||
}
|
||||
|
||||
XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
|
||||
boolean featureSecureProcessing, JdkXmlFeatures featureManager,
|
||||
XMLSecurityManager xmlSecMgr) {
|
||||
XMLSecurityManager xmlSecMgr, XMLSecurityPropertyManager xmlSecPropMgr) {
|
||||
this.origVariableResolver = this.variableResolver = vr;
|
||||
this.origFunctionResolver = this.functionResolver = fr;
|
||||
this.featureSecureProcessing = featureSecureProcessing;
|
||||
@ -75,6 +77,7 @@ public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
|
||||
overrideDefaultParser = featureManager.getFeature(
|
||||
JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER);
|
||||
this.xmlSecMgr = xmlSecMgr;
|
||||
this.xmlSecPropMgr = xmlSecPropMgr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ import com.sun.org.apache.xpath.internal.axes.LocPathIterator;
|
||||
import com.sun.org.apache.xpath.internal.objects.XObject;
|
||||
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
|
||||
import java.io.IOException;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
@ -44,6 +45,7 @@ import javax.xml.xpath.XPathVariableResolver;
|
||||
import jdk.xml.internal.JdkXmlFeatures;
|
||||
import jdk.xml.internal.JdkXmlUtils;
|
||||
import jdk.xml.internal.XMLSecurityManager;
|
||||
import jdk.xml.internal.XMLSecurityPropertyManager;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
@ -54,7 +56,7 @@ import org.xml.sax.SAXException;
|
||||
* This class contains several utility methods used by XPathImpl and
|
||||
* XPathExpressionImpl
|
||||
*
|
||||
* @LastModified: Apr 2025
|
||||
* @LastModified: June 2025
|
||||
*/
|
||||
class XPathImplUtil {
|
||||
XPathFunctionResolver functionResolver;
|
||||
@ -67,6 +69,7 @@ class XPathImplUtil {
|
||||
boolean featureSecureProcessing = false;
|
||||
JdkXmlFeatures featureManager;
|
||||
XMLSecurityManager xmlSecMgr;
|
||||
XMLSecurityPropertyManager xmlSecPropMgr;
|
||||
|
||||
/**
|
||||
* Evaluate an XPath context using the internal XPath engine
|
||||
@ -128,7 +131,12 @@ class XPathImplUtil {
|
||||
//
|
||||
// so we really have to create a fresh DocumentBuilder every time we need one
|
||||
// - KK
|
||||
DocumentBuilderFactory dbf = JdkXmlUtils.getDOMFactory(overrideDefaultParser);
|
||||
DocumentBuilderFactory dbf = JdkXmlUtils.getDOMFactory(
|
||||
overrideDefaultParser, xmlSecMgr, xmlSecPropMgr);
|
||||
if (xmlSecMgr != null && xmlSecMgr.isSecureProcessingSet()) {
|
||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
|
||||
xmlSecMgr.isSecureProcessing());
|
||||
}
|
||||
return dbf.newDocumentBuilder().parse(source);
|
||||
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||
throw new XPathExpressionException (e);
|
||||
|
||||
@ -445,6 +445,20 @@ public class JdkXmlUtils {
|
||||
* @return a DocumentBuilderFactory instance.
|
||||
*/
|
||||
public static DocumentBuilderFactory getDOMFactory(boolean overrideDefaultParser) {
|
||||
return getDOMFactory(overrideDefaultParser, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a DocumentBuilderFactory instance}
|
||||
*
|
||||
* @param overrideDefaultParser a flag indicating whether the system-default
|
||||
* implementation may be overridden. If the system property of the
|
||||
* DOM factory ID is set, override is always allowed.
|
||||
* @param xsm XMLSecurityManager
|
||||
* @param xspm XMLSecurityPropertyManager
|
||||
*/
|
||||
public static DocumentBuilderFactory getDOMFactory(boolean overrideDefaultParser,
|
||||
XMLSecurityManager xsm, XMLSecurityPropertyManager xspm) {
|
||||
boolean override = overrideDefaultParser;
|
||||
String spDOMFactory = SecuritySupport.getJAXPSystemProperty(DOM_FACTORY_ID);
|
||||
|
||||
@ -453,7 +467,7 @@ public class JdkXmlUtils {
|
||||
}
|
||||
DocumentBuilderFactory dbf
|
||||
= !override
|
||||
? new DocumentBuilderFactoryImpl()
|
||||
? new DocumentBuilderFactoryImpl(xsm, xspm)
|
||||
: DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
// false is the default setting. This step here is for compatibility
|
||||
|
||||
@ -244,6 +244,12 @@ public final class XMLSecurityManager implements Cloneable {
|
||||
*/
|
||||
boolean secureProcessing;
|
||||
|
||||
/**
|
||||
* Flag indicating the secure processing is set explicitly through factories'
|
||||
* setFeature method and then the setSecureProcessing method
|
||||
*/
|
||||
boolean secureProcessingSet;
|
||||
|
||||
/**
|
||||
* States that determine if properties are set explicitly
|
||||
*/
|
||||
@ -340,6 +346,7 @@ public final class XMLSecurityManager implements Cloneable {
|
||||
* Setting FEATURE_SECURE_PROCESSING explicitly
|
||||
*/
|
||||
public void setSecureProcessing(boolean secure) {
|
||||
secureProcessingSet = true;
|
||||
secureProcessing = secure;
|
||||
for (Limit limit : Limit.values()) {
|
||||
if (secure) {
|
||||
@ -358,6 +365,15 @@ public final class XMLSecurityManager implements Cloneable {
|
||||
return secureProcessing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state indicating whether the Secure Processing is set explicitly,
|
||||
* via factories' setFeature and then this class' setSecureProcessing method.
|
||||
* @return the state indicating whether the Secure Processing is set explicitly
|
||||
*/
|
||||
public boolean isSecureProcessingSet() {
|
||||
return secureProcessingSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a limit's new name with the given property name.
|
||||
* @param propertyName the property name specified
|
||||
|
||||
@ -53,6 +53,7 @@ import sun.security.x509.KeyUsageExtension;
|
||||
import sun.security.x509.SubjectAlternativeNameExtension;
|
||||
import sun.security.x509.URIName;
|
||||
import sun.security.x509.KeyIdentifier;
|
||||
import sun.security.x509.X500Name;
|
||||
|
||||
|
||||
/**
|
||||
@ -90,7 +91,7 @@ import sun.security.x509.KeyIdentifier;
|
||||
public class CertificateBuilder {
|
||||
private final CertificateFactory factory;
|
||||
|
||||
private X500Principal subjectName = null;
|
||||
private X500Name subjectName = null;
|
||||
private BigInteger serialNumber = null;
|
||||
private PublicKey publicKey = null;
|
||||
private Date notBefore = null;
|
||||
@ -199,7 +200,7 @@ public class CertificateBuilder {
|
||||
* on this certificate.
|
||||
*/
|
||||
public CertificateBuilder setSubjectName(X500Principal name) {
|
||||
subjectName = name;
|
||||
subjectName = X500Name.asX500Name(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -209,7 +210,23 @@ public class CertificateBuilder {
|
||||
* @param name The subject name in RFC 2253 format
|
||||
*/
|
||||
public CertificateBuilder setSubjectName(String name) {
|
||||
subjectName = new X500Principal(name);
|
||||
try {
|
||||
subjectName = new X500Name(name);
|
||||
} catch (IOException ioe) {
|
||||
throw new IllegalArgumentException(ioe);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subject name for the certificate. This method is useful when
|
||||
* you need more control over the contents of the subject name.
|
||||
*
|
||||
* @param name an {@code X500Name} to be used as the subject name
|
||||
* on this certificate
|
||||
*/
|
||||
public CertificateBuilder setSubjectName(X500Name name) {
|
||||
subjectName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user