-
Notifications
You must be signed in to change notification settings - Fork 1k
fix(xml): re-enable DTD validation and stop losing data in toXml() #3315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
juherr
wants to merge
6
commits into
testng-team:master
Choose a base branch
from
juherr:juherr/xml-roundtrip-safety-net
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0af93d8
fix(xml): re-enable DTD validation and stop losing data in toXml()
juherr e83e6a0
fix(xml): make validation self-consistent and stop it depending on JV…
juherr dd4dd49
fix(xml): let the validation mode take effect after start-up
juherr 9b4e342
test(xml): clean up the temporary DTD fixture
juherr b8b3b7c
test(xml): keep fixture cleanup from masking a test failure
juherr 9dc9436
fix(xml): stop serializing every suite parse behind one lock
juherr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
testng-core/src/main/java/org/testng/xml/XmlValidationMode.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| package org.testng.xml; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.Locale; | ||
| import org.testng.internal.RuntimeBehavior; | ||
| import org.testng.log4testng.Logger; | ||
|
|
||
| /** | ||
| * How strictly a suite file is checked against the TestNG DTD, selected with the {@code | ||
| * testng.xml.validation} system property. | ||
| * | ||
| * <p>Validation used to be silently disabled: {@code XMLParser} probed the SAX validation feature | ||
| * under an {@code https} identifier, which no parser recognizes, so {@code setValidating(true)} was | ||
| * never reached and DTD violations went unreported. Turning it back on means suite files that have | ||
| * been accepted for years can suddenly be rejected -- the DTD constrains the order of the children | ||
| * of {@code <suite>}, for instance -- so {@link #WARN} is the default for now and reports | ||
| * violations without failing the run. | ||
| * | ||
| * <p>The property is read at two different moments, which constrains when it can be changed. {@code | ||
| * XMLParser} decides <em>whether to validate</em> once, when it builds its single static {@code | ||
| * SAXParser}; {@code TestNGContentHandler.error} decides <em>how to report</em> a violation on | ||
| * every occurrence. Moving between {@link #WARN} and {@link #STRICT} at run time therefore takes | ||
| * effect, but moving away from {@link #OFF} does not, because no violation is ever raised to | ||
| * report. Set the property on the command line to be safe. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| */ | ||
| public enum XmlValidationMode { | ||
|
|
||
| /** Do not validate at all. */ | ||
| OFF, | ||
|
|
||
| /** Validate and report violations as warnings. The default. */ | ||
| WARN, | ||
|
|
||
| /** Validate and fail on the first violation. */ | ||
| STRICT; | ||
|
|
||
| private static final XmlValidationMode DEFAULT = WARN; | ||
|
|
||
| public boolean isValidating() { | ||
| return this != OFF; | ||
| } | ||
|
|
||
| /** | ||
| * The mode requested by the {@code testng.xml.validation} system property, falling back to {@link | ||
| * #WARN} when the property is absent or holds an unknown value. | ||
| */ | ||
| public static XmlValidationMode current() { | ||
| String requested = RuntimeBehavior.getXmlValidationMode(); | ||
| if (requested == null || requested.trim().isEmpty()) { | ||
| return DEFAULT; | ||
| } | ||
| try { | ||
| return valueOf(requested.trim().toUpperCase(Locale.ROOT)); | ||
| } catch (IllegalArgumentException e) { | ||
| Logger.getLogger(XmlValidationMode.class) | ||
| .warn( | ||
| "Unknown value [" | ||
| + requested | ||
| + "] for the system property [" | ||
| + RuntimeBehavior.XML_VALIDATION_MODE | ||
| + "]. Expected one of " | ||
| + Arrays.toString(values()) | ||
| + ". Falling back to [" | ||
| + DEFAULT | ||
| + "]."); | ||
| return DEFAULT; | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: testng-team/testng
Length of output: 5583
🏁 Script executed:
Repository: testng-team/testng
Length of output: 11650
🏁 Script executed:
Repository: testng-team/testng
Length of output: 5081
🏁 Script executed:
Repository: testng-team/testng
Length of output: 37641
🌐 Web query:
Java SAX EntityResolver resolveEntity internal DTD subset startDTD LexicalHandler invoked internal DTD💡 Result:
In Java SAX parsing, the interaction between the EntityResolver, LexicalHandler, and DTD subsets works as follows: 1. EntityResolver resolveEntity: The EntityResolver is primarily used for intercepting and resolving external entities [1]. The SAX parser calls resolveEntity before opening any external entity, which includes the external DTD subset (if present) and external parameter entities [1][2]. However, the EntityResolver is not invoked for the internal DTD subset, as it is part of the main document and is already available to the parser [1][2]. 2. LexicalHandler startDTD: The LexicalHandler.startDTD method is used to report the beginning of DTD declarations [3][4]. It is invoked by the parser regardless of whether the DTD contains only an internal subset or both internal and external subsets [3][4]. - When startDTD is called, the name parameter provides the document type name [3][5]. - If an external DTD subset exists, the publicId and systemId parameters provide its identifiers [3][4]. - If only an internal DTD subset exists (i.e., no external DTD subset is declared), the publicId and systemId parameters will be null [3][6]. 3. Internal DTD Subset Scope: Declarations are generally assumed to belong to the internal DTD subset unless they appear between startEntity and endEntity events (which indicate the inclusion of an external entity) [3][5]. Comments and processing instructions found within the DTD are reported by the LexicalHandler between the startDTD and endDTD events [3][7]. In summary, resolveEntity is specifically for external entities and does not handle the internal DTD subset, whereas startDTD is a lifecycle event that reports the DTD's presence and its external subset identifiers, if applicable, even when an internal subset is present [1][3].
Citations:
Track internal DTD declarations with lexical DTD handling.
m_doctypeDeclaredis only set fromEntityResolver.resolveEntity(), but SAX only resolves external entities; an internal<!DOCTYPE suite [ ... ]>can still establish the DTD grammar. As a result, XML validation violations in internal-only DTD suites are ignored instrictmode. Implement/setLexicalHandler(or another DTD lifecycle callback) and mark the document declared fromstartDTD.🤖 Prompt for AI Agents