Skip to content

Commit 5b9d567

Browse files
tausbnRasmusWL
authored andcommitted
Python: Refactor references to ElementTree
This would probably be better as a module, but I wanted to verify first that this would yield the right results.
1 parent d29879a commit 5b9d567

File tree

2 files changed

+19
-41
lines changed

2 files changed

+19
-41
lines changed

python/ql/lib/semmle/python/frameworks/Stdlib.qll

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3616,27 +3616,23 @@ module StdlibPrivate {
36163616
// ---------------------------------------------------------------------------
36173617
// xml.etree.ElementTree
36183618
// ---------------------------------------------------------------------------
3619+
/** A reference to the `xml.etree.ElementTree` class */
3620+
API::Node elementTreeClassRef() {
3621+
result = API::moduleImport("xml").getMember("etree").getMember("ElementTree").getASubclass*() or
3622+
result = ModelOutput::getATypeNode("xml.etree.ElementTree~Subclass").getASubclass*()
3623+
}
3624+
36193625
/**
36203626
* An instance of `xml.etree.ElementTree.ElementTree`.
36213627
*
36223628
* See https://docs.python.org/3.10/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree
36233629
*/
36243630
private API::Node elementTreeInstance() {
36253631
//parse to a tree
3626-
result =
3627-
API::moduleImport("xml")
3628-
.getMember("etree")
3629-
.getMember("ElementTree")
3630-
.getMember("parse")
3631-
.getReturn()
3632+
result = elementTreeClassRef().getMember("parse").getReturn()
36323633
or
36333634
// construct a tree without parsing
3634-
result =
3635-
API::moduleImport("xml")
3636-
.getMember("etree")
3637-
.getMember("ElementTree")
3638-
.getMember("ElementTree")
3639-
.getReturn()
3635+
result = elementTreeClassRef().getMember("ElementTree").getReturn()
36403636
}
36413637

36423638
/**
@@ -3649,21 +3645,9 @@ module StdlibPrivate {
36493645
result = elementTreeInstance().getMember(["parse", "getroot"]).getReturn()
36503646
or
36513647
// parse directly to an element
3652-
result =
3653-
API::moduleImport("xml")
3654-
.getMember("etree")
3655-
.getMember("ElementTree")
3656-
.getMember(["fromstring", "fromstringlist", "XML"])
3657-
.getReturn()
3648+
result = elementTreeClassRef().getMember(["fromstring", "fromstringlist", "XML"]).getReturn()
36583649
or
3659-
result =
3660-
API::moduleImport("xml")
3661-
.getMember("etree")
3662-
.getMember("ElementTree")
3663-
.getMember("XMLParser")
3664-
.getReturn()
3665-
.getMember("close")
3666-
.getReturn()
3650+
result = elementTreeClassRef().getMember("XMLParser").getReturn().getMember("close").getReturn()
36673651
}
36683652

36693653
/**
@@ -3708,12 +3692,7 @@ module StdlibPrivate {
37083692
/** A direct instantiation of `xml.etree` parsers. */
37093693
private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode {
37103694
ClassInstantiation() {
3711-
this =
3712-
API::moduleImport("xml")
3713-
.getMember("etree")
3714-
.getMember("ElementTree")
3715-
.getMember(["XMLParser", "XMLPullParser"])
3716-
.getACall()
3695+
this = elementTreeClassRef().getMember(["XMLParser", "XMLPullParser"]).getACall()
37173696
}
37183697
}
37193698

@@ -3770,9 +3749,7 @@ module StdlibPrivate {
37703749
private class XmlEtreeParsing extends DataFlow::CallCfgNode, XML::XmlParsing::Range {
37713750
XmlEtreeParsing() {
37723751
this =
3773-
API::moduleImport("xml")
3774-
.getMember("etree")
3775-
.getMember("ElementTree")
3752+
elementTreeClassRef()
37763753
.getMember(["fromstring", "fromstringlist", "XML", "XMLID", "parse", "iterparse"])
37773754
.getACall()
37783755
or
@@ -3820,12 +3797,7 @@ module StdlibPrivate {
38203797
*/
38213798
private class FileAccessFromXmlEtreeParsing extends XmlEtreeParsing, FileSystemAccess::Range {
38223799
FileAccessFromXmlEtreeParsing() {
3823-
this =
3824-
API::moduleImport("xml")
3825-
.getMember("etree")
3826-
.getMember("ElementTree")
3827-
.getMember(["parse", "iterparse"])
3828-
.getACall()
3800+
this = elementTreeClassRef().getMember(["parse", "iterparse"]).getACall()
38293801
or
38303802
this = elementTreeInstance().getMember("parse").getACall()
38313803
// I considered whether we should try to reduce FPs from people passing file-like

python/ql/src/meta/ClassHierarchy/Find.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,12 @@ class RestFrameworkApiException extends FindSubclassesSpec {
451451
override API::Node getAlreadyModeledClass() { result = RestFramework::ApiException::classRef() }
452452
}
453453

454+
class ElementTree extends FindSubclassesSpec {
455+
ElementTree() { this = "xml.etree.ElementTree~Subclass" }
456+
457+
override API::Node getAlreadyModeledClass() { result = StdlibPrivate::elementTreeClassRef() }
458+
}
459+
454460
bindingset[fullyQualified]
455461
predicate fullyQualifiedToYamlFormat(string fullyQualified, string type2, string path) {
456462
exists(int firstDot | firstDot = fullyQualified.indexOf(".", 0, 0) |

0 commit comments

Comments
 (0)