Merge pull request #2541 from max-schaefer/unify-xml-qlls

C++/Java/JavaScript/Python: Unify XML libraries.
This commit is contained in:
Jonas Jensen
2019-12-18 10:35:34 +01:00
committed by GitHub
5 changed files with 329 additions and 180 deletions

View File

@@ -2,7 +2,7 @@
* Provides classes and predicates for working with XML files and their content.
*/
import semmle.code.cpp.Location
import semmle.files.FileSystem
/** An XML element that has a location. */
abstract class XMLLocatable extends @xmllocatable {
@@ -10,19 +10,22 @@ abstract class XMLLocatable extends @xmllocatable {
Location getLocation() { xmllocations(this, result) }
/**
* Holds if this element has the specified location information,
* including file path, start line, start column, end line and end column.
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(File f, Location l | l = this.getLocation() |
locations_default(l, unresolveElement(f), startline, startcolumn, endline, endcolumn) and
locations_default(l, f, startline, startcolumn, endline, endcolumn) and
filepath = f.getAbsolutePath()
)
}
/** Gets a printable representation of this element. */
/** Gets a textual representation of this element. */
abstract string toString();
}
@@ -112,15 +115,21 @@ class XMLFile extends XMLParent, File {
override string toString() { result = XMLParent.super.toString() }
/** Gets the name of this XML file. */
override string getName() { files(this, result, _, _, _) }
override string getName() { result = File.super.getAbsolutePath() }
/** Gets the path of this XML file. */
string getPath() { files(this, _, result, _, _) }
/**
* DEPRECATED: Use `getAbsolutePath()` instead.
*
* Gets the path of this XML file.
*/
deprecated string getPath() { result = getAbsolutePath() }
/** Gets the path of the folder that contains this XML file. */
string getFolder() {
result = this.getPath().substring(0, this.getPath().length() - this.getName().length())
}
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
@@ -135,7 +144,17 @@ class XMLFile extends XMLParent, File {
XMLDTD getADTD() { xmlDTDs(result, _, _, _, this) }
}
/** A "Document Type Definition" of an XML file. */
/**
* An XML document type definition (DTD).
*
* Example:
*
* ```
* <!ELEMENT person (firstName, lastName?)>
* <!ELEMENT firstName (#PCDATA)>
* <!ELEMENT lastName (#PCDATA)>
* ```
*/
class XMLDTD extends @xmldtd {
/** Gets the name of the root element of this DTD. */
string getRoot() { xmlDTDs(this, result, _, _, _) }
@@ -162,7 +181,17 @@ class XMLDTD extends @xmldtd {
}
}
/** An XML tag in an XML file. */
/**
* An XML element in an XML file.
*
* Example:
*
* ```
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
* package="com.example.exampleapp" android:versionCode="1">
* </manifest>
* ```
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
/** Holds if this XML element has the given `name`. */
predicate hasName(string name) { name = getName() }
@@ -207,7 +236,16 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
override string toString() { result = XMLParent.super.toString() }
}
/** An attribute that occurs inside an XML element. */
/**
* An attribute that occurs inside an XML element.
*
* Examples:
*
* ```
* package="com.example.exampleapp"
* android:versionCode="1"
* ```
*/
class XMLAttribute extends @xmlattribute, XMLLocatable {
/** Gets the name of this attribute. */
string getName() { xmlAttrs(this, _, result, _, _, _) }
@@ -228,7 +266,15 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
override string toString() { result = this.getName() + "=" + this.getValue() }
}
/** A namespace used in an XML file */
/**
* A namespace used in an XML file.
*
* Example:
*
* ```
* xmlns:android="http://schemas.android.com/apk/res/android"
* ```
*/
class XMLNamespace extends @xmlnamespace {
/** Gets the prefix of this namespace. */
string getPrefix() { xmlNs(this, result, _, _) }
@@ -247,7 +293,15 @@ class XMLNamespace extends @xmlnamespace {
}
}
/** A comment of the form `<!-- ... -->` is an XML comment. */
/**
* A comment in an XML file.
*
* Example:
*
* ```
* <!-- This is a comment. -->
* ```
*/
class XMLComment extends @xmlcomment, XMLLocatable {
/** Gets the text content of this XML comment. */
string getText() { xmlComments(this, result, _, _) }
@@ -262,6 +316,12 @@ class XMLComment extends @xmlcomment, XMLLocatable {
/**
* A sequence of characters that occurs between opening and
* closing tags of an XML element, excluding other elements.
*
* Example:
*
* ```
* <content>This is a sequence of characters.</content>
* ```
*/
class XMLCharacters extends @xmlcharacters, XMLLocatable {
/** Gets the content of this character sequence. */