mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
C++: Get the simplest part of the query working, disable the rest for now, fix metadata, formatting etc.
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
/**
|
||||
* @name External Entity Expansion
|
||||
* @description
|
||||
* @description TODO
|
||||
* @kind path-problem
|
||||
* @id cpp/external-entity-expansion
|
||||
* @problem.severity warning
|
||||
* @security-severity TODO
|
||||
* @precision TODO
|
||||
* @tags security
|
||||
* external/cwe/cwe-611
|
||||
*/
|
||||
@@ -13,52 +15,65 @@ import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
import semmle.code.cpp.ir.IR
|
||||
|
||||
class XercesDOMParser extends Class {
|
||||
XercesDOMParser() { this.hasName("XercesDOMParser") }
|
||||
}
|
||||
|
||||
class AbstractDOMParser extends Class {
|
||||
AbstractDOMParser() { this.hasName("AbstractDOMParser") }
|
||||
}
|
||||
|
||||
class XercesDOMParser extends Class {
|
||||
XercesDOMParser() { this.hasName("XercesDOMParser") }
|
||||
}
|
||||
|
||||
class DisableDefaultEntityResolution extends Function {
|
||||
DisableDefaultEntityResolution() {
|
||||
this.hasQualifiedName(_, "AbstractOMParser", "setDisableDefaultEntityResolution")
|
||||
this.getDeclaringType() instanceof AbstractDOMParser and
|
||||
this.hasName("setDisableDefaultEntityResolution")
|
||||
}
|
||||
}
|
||||
|
||||
class SetCreateEntityReferenceNodes extends Function {
|
||||
SetCreateEntityReferenceNodes() {
|
||||
this.hasQualifiedName(_, "AbstractDOMParser", "setCreateEntityReferenceNodes")
|
||||
this.getDeclaringType() instanceof AbstractDOMParser and
|
||||
this.hasName("setCreateEntityReferenceNodes")
|
||||
}
|
||||
}
|
||||
|
||||
class CreateLSParser extends Function {
|
||||
CreateLSParser() {
|
||||
this.hasName("createLSParser")
|
||||
class Parse extends Function {
|
||||
Parse() {
|
||||
this.getDeclaringType() instanceof AbstractDOMParser and
|
||||
this.hasName("parse")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class CreateLSParser extends Function {
|
||||
CreateLSParser() { this.hasName("createLSParser") }
|
||||
}
|
||||
|
||||
class SetSecurityManager extends Function {
|
||||
SetSecurityManager() {
|
||||
this.hasQualifiedName(_, "AbstractDOMParser", "setSecurityManager")
|
||||
}
|
||||
SetSecurityManager() { this.hasQualifiedName(_, "AbstractDOMParser", "setSecurityManager") }
|
||||
}
|
||||
|
||||
class SAXParser extends Class {
|
||||
SAXParser() { this.hasName("SAXParser") }
|
||||
}
|
||||
|
||||
*/
|
||||
class XercesXXEConfiguration extends DataFlow::Configuration {
|
||||
XercesXXEConfiguration() { this = "XercesXXEConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node, string flowstate) {
|
||||
override predicate isSource(DataFlow::Node node/*, string flowstate*/) {
|
||||
// source is the write on `this` of a call to the XercesDOMParser
|
||||
// constructor.
|
||||
exists(CallInstruction call |
|
||||
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() = call.getThisArgument() and
|
||||
call.getStaticCallTarget().(Constructor).getDeclaringType() instanceof XercesDOMParser and
|
||||
flowstate = "XercesDOM"
|
||||
call.getStaticCallTarget() = any(XercesDOMParser c).getAConstructor() and
|
||||
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
|
||||
call.getThisArgument()/* and
|
||||
flowstate = "XercesDOM"*/
|
||||
)
|
||||
or
|
||||
/*exists(Call call |
|
||||
call.getTarget() = any(XercesDOMParser c).getAConstructor() and
|
||||
node.asExpr() = call
|
||||
)*/
|
||||
/* or
|
||||
exists(Call call |
|
||||
call.getTarget() instanceof CreateLSParser and
|
||||
call = node.asExpr() and
|
||||
@@ -66,21 +81,26 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
|
||||
)
|
||||
or
|
||||
exists(CallInstruction call |
|
||||
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() = call.getThisArgument() and
|
||||
node.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
|
||||
call.getThisArgument() and
|
||||
call.getStaticCallTarget().(Constructor).getDeclaringType() instanceof SAXParser and
|
||||
flowstate = "SAXParser"
|
||||
)
|
||||
)*/
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
exists(Call call, ReadSideEffectInstruction instr |
|
||||
call.getTarget().hasName("parse") and
|
||||
call.getQualifier() = instr.getArgumentDef().getUnconvertedResultExpression() and
|
||||
node.asOperand() = instr.getSideEffectOperand()
|
||||
// sink is the read of the qualifier of a call to `parse`.
|
||||
exists(Call call/*, ReadSideEffectInstruction instr*/ |
|
||||
call.getTarget() instanceof Parse and
|
||||
call.getQualifier() = node.asConvertedExpr()
|
||||
/*instr.getArgumentDef().getUnconvertedResultExpression() and
|
||||
node.asOperand() = instr.getSideEffectOperand()*/
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, string state1, DataFlow::Node node2, string state2) {
|
||||
/*override predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, string state1, DataFlow::Node node2, string state2
|
||||
) {
|
||||
exists(Call call |
|
||||
node1.asConvertedExpr() = call.getQualifier() and
|
||||
node2.asDefiningArgument() = call.getQualifier() and
|
||||
@@ -94,9 +114,9 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
|
||||
state2 = "XercesDOM-SCERN"
|
||||
)
|
||||
)
|
||||
}
|
||||
}*/
|
||||
|
||||
override predicate isBarrier(DataFlow::Node node, string flowstate) {
|
||||
/*override predicate isBarrier(DataFlow::Node node, string flowstate) {
|
||||
exists(Call call |
|
||||
(
|
||||
flowstate = "XercesDOM-DDER" and
|
||||
@@ -110,14 +130,15 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
|
||||
or
|
||||
exists(Call setSecurityManager |
|
||||
// todo: security manager setup
|
||||
flowstate = TODO
|
||||
setSecurityManager.getQualifier() = node.asDefiningArgument() and
|
||||
setSecurityManager.getTarget() instanceof SetSecurityManager
|
||||
)
|
||||
//or
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* parser created
|
||||
* needs doSchema set?
|
||||
* needs validation set?
|
||||
@@ -128,7 +149,7 @@ class XercesXXEConfiguration extends DataFlow::Configuration {
|
||||
* no
|
||||
*/
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, XercesXXEConfiguration conf
|
||||
from XercesXXEConfiguration conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink, source, sink,
|
||||
"This $@ is not configured to prevent an External Entity Expansion attack.", source, "XML parser"
|
||||
"This $@ is not configured to prevent an External Entity Expansion (XXE) attack.", source, "XML parser"
|
||||
|
||||
@@ -1,4 +1,87 @@
|
||||
edges
|
||||
| tests.cpp:33:23:33:43 | XercesDOMParser output argument | tests.cpp:35:2:35:2 | p |
|
||||
| tests.cpp:39:23:39:43 | XercesDOMParser output argument | tests.cpp:42:2:42:2 | p |
|
||||
| tests.cpp:46:23:46:43 | XercesDOMParser output argument | tests.cpp:49:2:49:2 | p |
|
||||
| tests.cpp:53:23:53:43 | XercesDOMParser output argument | tests.cpp:57:2:57:2 | p |
|
||||
| tests.cpp:61:23:61:43 | XercesDOMParser output argument | tests.cpp:65:2:65:2 | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:72:2:72:2 | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:74:2:74:2 | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:76:2:76:2 | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:78:2:78:2 | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:80:2:80:2 | p |
|
||||
| tests.cpp:84:23:84:43 | XercesDOMParser output argument | tests.cpp:87:2:87:2 | p |
|
||||
| tests.cpp:91:23:91:43 | XercesDOMParser output argument | tests.cpp:98:2:98:2 | p |
|
||||
| tests.cpp:103:24:103:44 | XercesDOMParser output argument | tests.cpp:106:3:106:3 | q |
|
||||
| tests.cpp:110:24:110:44 | XercesDOMParser output argument | tests.cpp:114:3:114:3 | q |
|
||||
| tests.cpp:118:24:118:44 | XercesDOMParser output argument | tests.cpp:122:3:122:3 | q |
|
||||
| tests.cpp:126:39:126:39 | p | tests.cpp:127:2:127:2 | p |
|
||||
| tests.cpp:130:39:130:39 | p | tests.cpp:131:2:131:2 | p |
|
||||
| tests.cpp:134:39:134:39 | p | tests.cpp:135:2:135:2 | p |
|
||||
| tests.cpp:139:23:139:43 | XercesDOMParser output argument | tests.cpp:143:18:143:18 | p |
|
||||
| tests.cpp:139:23:139:43 | XercesDOMParser output argument | tests.cpp:145:18:145:18 | p |
|
||||
| tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:144:18:144:18 | q |
|
||||
| tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:146:18:146:18 | q |
|
||||
| tests.cpp:143:18:143:18 | p | tests.cpp:126:39:126:39 | p |
|
||||
| tests.cpp:144:18:144:18 | q | tests.cpp:130:39:130:39 | p |
|
||||
| tests.cpp:145:18:145:18 | p | tests.cpp:134:39:134:39 | p |
|
||||
| tests.cpp:146:18:146:18 | q | tests.cpp:134:39:134:39 | p |
|
||||
nodes
|
||||
| tests.cpp:33:23:33:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:35:2:35:2 | p | semmle.label | p |
|
||||
| tests.cpp:39:23:39:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:42:2:42:2 | p | semmle.label | p |
|
||||
| tests.cpp:46:23:46:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:49:2:49:2 | p | semmle.label | p |
|
||||
| tests.cpp:53:23:53:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:57:2:57:2 | p | semmle.label | p |
|
||||
| tests.cpp:61:23:61:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:65:2:65:2 | p | semmle.label | p |
|
||||
| tests.cpp:69:23:69:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:72:2:72:2 | p | semmle.label | p |
|
||||
| tests.cpp:74:2:74:2 | p | semmle.label | p |
|
||||
| tests.cpp:76:2:76:2 | p | semmle.label | p |
|
||||
| tests.cpp:78:2:78:2 | p | semmle.label | p |
|
||||
| tests.cpp:80:2:80:2 | p | semmle.label | p |
|
||||
| tests.cpp:84:23:84:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:87:2:87:2 | p | semmle.label | p |
|
||||
| tests.cpp:91:23:91:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:98:2:98:2 | p | semmle.label | p |
|
||||
| tests.cpp:103:24:103:44 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:106:3:106:3 | q | semmle.label | q |
|
||||
| tests.cpp:110:24:110:44 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:114:3:114:3 | q | semmle.label | q |
|
||||
| tests.cpp:118:24:118:44 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:122:3:122:3 | q | semmle.label | q |
|
||||
| tests.cpp:126:39:126:39 | p | semmle.label | p |
|
||||
| tests.cpp:127:2:127:2 | p | semmle.label | p |
|
||||
| tests.cpp:130:39:130:39 | p | semmle.label | p |
|
||||
| tests.cpp:131:2:131:2 | p | semmle.label | p |
|
||||
| tests.cpp:134:39:134:39 | p | semmle.label | p |
|
||||
| tests.cpp:135:2:135:2 | p | semmle.label | p |
|
||||
| tests.cpp:139:23:139:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:140:23:140:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:143:18:143:18 | p | semmle.label | p |
|
||||
| tests.cpp:144:18:144:18 | q | semmle.label | q |
|
||||
| tests.cpp:145:18:145:18 | p | semmle.label | p |
|
||||
| tests.cpp:146:18:146:18 | q | semmle.label | q |
|
||||
subpaths
|
||||
#select
|
||||
| tests.cpp:35:2:35:2 | p | tests.cpp:33:23:33:43 | XercesDOMParser output argument | tests.cpp:35:2:35:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:33:23:33:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:42:2:42:2 | p | tests.cpp:39:23:39:43 | XercesDOMParser output argument | tests.cpp:42:2:42:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:39:23:39:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:49:2:49:2 | p | tests.cpp:46:23:46:43 | XercesDOMParser output argument | tests.cpp:49:2:49:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:46:23:46:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:57:2:57:2 | p | tests.cpp:53:23:53:43 | XercesDOMParser output argument | tests.cpp:57:2:57:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:53:23:53:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:65:2:65:2 | p | tests.cpp:61:23:61:43 | XercesDOMParser output argument | tests.cpp:65:2:65:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:61:23:61:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:72:2:72:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:72:2:72:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:74:2:74:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:74:2:74:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:76:2:76:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:76:2:76:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:78:2:78:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:78:2:78:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:80:2:80:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:80:2:80:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:87:2:87:2 | p | tests.cpp:84:23:84:43 | XercesDOMParser output argument | tests.cpp:87:2:87:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:84:23:84:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:98:2:98:2 | p | tests.cpp:91:23:91:43 | XercesDOMParser output argument | tests.cpp:98:2:98:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:91:23:91:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:106:3:106:3 | q | tests.cpp:103:24:103:44 | XercesDOMParser output argument | tests.cpp:106:3:106:3 | q | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:103:24:103:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:114:3:114:3 | q | tests.cpp:110:24:110:44 | XercesDOMParser output argument | tests.cpp:114:3:114:3 | q | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:110:24:110:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:122:3:122:3 | q | tests.cpp:118:24:118:44 | XercesDOMParser output argument | tests.cpp:122:3:122:3 | q | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:118:24:118:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:127:2:127:2 | p | tests.cpp:139:23:139:43 | XercesDOMParser output argument | tests.cpp:127:2:127:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:139:23:139:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:131:2:131:2 | p | tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:131:2:131:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:140:23:140:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:135:2:135:2 | p | tests.cpp:139:23:139:43 | XercesDOMParser output argument | tests.cpp:135:2:135:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:139:23:139:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:135:2:135:2 | p | tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:135:2:135:2 | p | This $@ is not configured to prevent an External Entity Expansion (XXE) attack. | tests.cpp:140:23:140:43 | XercesDOMParser output argument | XML parser |
|
||||
|
||||
@@ -39,7 +39,7 @@ void test2(InputSource &data) {
|
||||
XercesDOMParser *p = new XercesDOMParser();
|
||||
|
||||
p->setDisableDefaultEntityResolution(true);
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void test3(InputSource &data) {
|
||||
@@ -62,22 +62,22 @@ void test5(InputSource &data) {
|
||||
|
||||
p->setDisableDefaultEntityResolution(true);
|
||||
p->setCreateEntityReferenceNodes(true);
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void test6(InputSource &data) {
|
||||
XercesDOMParser *p = new XercesDOMParser();
|
||||
|
||||
p->setDisableDefaultEntityResolution(true);
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
p->setDisableDefaultEntityResolution(false);
|
||||
p->parse(data); // BAD (parser not correctly configured)
|
||||
p->setDisableDefaultEntityResolution(true);
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
p->setCreateEntityReferenceNodes(false);
|
||||
p->parse(data); // BAD (parser not correctly configured)
|
||||
p->setCreateEntityReferenceNodes(true);
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void test7(InputSource &data, bool cond) {
|
||||
@@ -111,7 +111,7 @@ void test9(InputSource &data) {
|
||||
XercesDOMParser &q = *p;
|
||||
|
||||
q.setDisableDefaultEntityResolution(true);
|
||||
q.parse(data); // GOOD
|
||||
q.parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
{
|
||||
@@ -119,12 +119,12 @@ void test9(InputSource &data) {
|
||||
XercesDOMParser &q = *p;
|
||||
|
||||
p->setDisableDefaultEntityResolution(true);
|
||||
q.parse(data); // GOOD
|
||||
q.parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
|
||||
void test10_doParseA(XercesDOMParser *p, InputSource &data) {
|
||||
p->parse(data); // GOOD
|
||||
p->parse(data); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void test10_doParseB(XercesDOMParser *p, InputSource &data) {
|
||||
@@ -149,7 +149,7 @@ void test10(InputSource &data) {
|
||||
void test11(InputSource &data) {
|
||||
LSParser *p = createLSParser();
|
||||
|
||||
p->parse(data); // BAD (parser not correctly configured)
|
||||
p->parse(data); // BAD (parser not correctly configured) [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test12(InputSource &data) {
|
||||
@@ -166,5 +166,5 @@ InputSource *g_data;
|
||||
void test13() {
|
||||
g_p1->setDisableDefaultEntityResolution(true);
|
||||
g_p1->parse(*g_data); // GOOD
|
||||
g_p2->parse(*g_data); // BAD (parser not correctly configured)
|
||||
g_p2->parse(*g_data); // BAD (parser not correctly configured) [NOT DETECTED]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user