Skip to content

Commit cc7f98e

Browse files
authored
Merge pull request #2555 from hvitved/csharp/xml-sync
C#: Sync `XML.qll` with other languages
2 parents de55a68 + 29cd6a9 commit cc7f98e

File tree

7 files changed

+157
-50
lines changed

7 files changed

+157
-50
lines changed

config/identical-files.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@
268268
],
269269
"XML": [
270270
"cpp/ql/src/semmle/code/cpp/XML.qll",
271+
"csharp/ql/src/semmle/code/csharp/XML.qll",
271272
"java/ql/src/semmle/code/xml/XML.qll",
272273
"javascript/ql/src/semmle/javascript/XML.qll",
273274
"python/ql/src/semmle/python/xml/XML.qll"

cpp/ql/src/semmle/code/cpp/XML.qll

100644100755
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ abstract class XMLLocatable extends @xmllocatable {
99
/** Gets the source location for this element. */
1010
Location getLocation() { xmllocations(this, result) }
1111

12+
/**
13+
* DEPRECATED: Use `getLocation()` instead.
14+
*
15+
* Gets the source location for this element.
16+
*/
17+
deprecated Location getALocation() { result = this.getLocation() }
18+
1219
/**
1320
* Holds if this element is at the specified location.
1421
* The location spans column `startcolumn` of line `startline` to
@@ -155,7 +162,7 @@ class XMLFile extends XMLParent, File {
155162
* <!ELEMENT lastName (#PCDATA)>
156163
* ```
157164
*/
158-
class XMLDTD extends @xmldtd {
165+
class XMLDTD extends XMLLocatable, @xmldtd {
159166
/** Gets the name of the root element of this DTD. */
160167
string getRoot() { xmlDTDs(this, result, _, _, _) }
161168

@@ -171,8 +178,7 @@ class XMLDTD extends @xmldtd {
171178
/** Gets the parent of this DTD. */
172179
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
173180

174-
/** Gets a printable representation of this DTD. */
175-
string toString() {
181+
override string toString() {
176182
this.isPublic() and
177183
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
178184
or
@@ -275,7 +281,7 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
275281
* xmlns:android="http://schemas.android.com/apk/res/android"
276282
* ```
277283
*/
278-
class XMLNamespace extends @xmlnamespace {
284+
class XMLNamespace extends XMLLocatable, @xmlnamespace {
279285
/** Gets the prefix of this namespace. */
280286
string getPrefix() { xmlNs(this, result, _, _) }
281287

@@ -285,8 +291,7 @@ class XMLNamespace extends @xmlnamespace {
285291
/** Holds if this namespace has no prefix. */
286292
predicate isDefault() { this.getPrefix() = "" }
287293

288-
/** Gets a printable representation of this XML namespace. */
289-
string toString() {
294+
override string toString() {
290295
this.isDefault() and result = this.getURI()
291296
or
292297
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()

csharp/ql/src/semmle/code/csharp/XML.qll

100644100755
Lines changed: 111 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,37 @@
22
* Provides classes and predicates for working with XML files and their content.
33
*/
44

5-
import semmle.code.csharp.Element
6-
import semmle.code.csharp.Location
5+
import semmle.files.FileSystem
76

87
/** An XML element that has a location. */
9-
class XMLLocatable extends @xmllocatable {
10-
XMLLocatable() {
11-
not this instanceof File // in the dbscheme
12-
}
13-
8+
abstract class XMLLocatable extends @xmllocatable {
149
/** Gets the source location for this element. */
15-
Location getALocation() { xmllocations(this, result) }
10+
Location getLocation() { xmllocations(this, result) }
11+
12+
/**
13+
* DEPRECATED: Use `getLocation()` instead.
14+
*
15+
* Gets the source location for this element.
16+
*/
17+
deprecated Location getALocation() { result = this.getLocation() }
1618

1719
/**
18-
* Whether this element has the specified location information,
19-
* including file path, start line, start column, end line and end column.
20+
* Holds if this element is at the specified location.
21+
* The location spans column `startcolumn` of line `startline` to
22+
* column `endcolumn` of line `endline` in file `filepath`.
23+
* For more information, see
24+
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
2025
*/
2126
predicate hasLocationInfo(
2227
string filepath, int startline, int startcolumn, int endline, int endcolumn
2328
) {
24-
exists(File f, Location l | l = this.getALocation() |
29+
exists(File f, Location l | l = this.getLocation() |
2530
locations_default(l, f, startline, startcolumn, endline, endcolumn) and
2631
filepath = f.getAbsolutePath()
2732
)
2833
}
2934

30-
/** Gets a printable representation of this element. */
35+
/** Gets a textual representation of this element. */
3136
abstract string toString();
3237
}
3338

@@ -36,6 +41,12 @@ class XMLLocatable extends @xmllocatable {
3641
* both of which can contain other elements.
3742
*/
3843
class XMLParent extends @xmlparent {
44+
XMLParent() {
45+
// explicitly restrict `this` to be either an `XMLElement` or an `XMLFile`;
46+
// the type `@xmlparent` currently also includes non-XML files
47+
this instanceof @xmlelement or xmlEncoding(this, _)
48+
}
49+
3950
/**
4051
* Gets a printable representation of this XML parent.
4152
* (Intended to be overridden in subclasses.)
@@ -69,7 +80,25 @@ class XMLParent extends @xmlparent {
6980
/** Gets the number of places in the body of this XML parent where text occurs. */
7081
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
7182

72-
/** Append all the character sequences of this XML parent from left to right, separated by a space. */
83+
/**
84+
* DEPRECATED: Internal.
85+
*
86+
* Append the character sequences of this XML parent from left to right, separated by a space,
87+
* up to a specified (zero-based) index.
88+
*/
89+
deprecated string charsSetUpTo(int n) {
90+
n = 0 and xmlChars(_, result, this, 0, _, _)
91+
or
92+
n > 0 and
93+
exists(string chars | xmlChars(_, chars, this, n, _, _) |
94+
result = this.charsSetUpTo(n - 1) + " " + chars
95+
)
96+
}
97+
98+
/**
99+
* Gets the result of appending all the character sequences of this XML parent from
100+
* left to right, separated by a space.
101+
*/
73102
string allCharactersString() {
74103
result = concat(string chars, int pos |
75104
xmlChars(_, chars, this, pos, _, _)
@@ -93,15 +122,21 @@ class XMLFile extends XMLParent, File {
93122
override string toString() { result = XMLParent.super.toString() }
94123

95124
/** Gets the name of this XML file. */
96-
override string getName() { files(this, result, _, _, _) }
125+
override string getName() { result = File.super.getAbsolutePath() }
97126

98-
/** Gets the path of this XML file. */
99-
string getPath() { files(this, _, result, _, _) }
127+
/**
128+
* DEPRECATED: Use `getAbsolutePath()` instead.
129+
*
130+
* Gets the path of this XML file.
131+
*/
132+
deprecated string getPath() { result = getAbsolutePath() }
100133

101-
/** Gets the path of the folder that contains this XML file. */
102-
string getFolder() {
103-
result = this.getPath().substring(0, this.getPath().length() - this.getName().length())
104-
}
134+
/**
135+
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
136+
*
137+
* Gets the path of the folder that contains this XML file.
138+
*/
139+
deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
105140

106141
/** Gets the encoding of this XML file. */
107142
string getEncoding() { xmlEncoding(this, result) }
@@ -116,7 +151,17 @@ class XMLFile extends XMLParent, File {
116151
XMLDTD getADTD() { xmlDTDs(result, _, _, _, this) }
117152
}
118153

119-
/** A "Document Type Definition" of an XML file. */
154+
/**
155+
* An XML document type definition (DTD).
156+
*
157+
* Example:
158+
*
159+
* ```
160+
* <!ELEMENT person (firstName, lastName?)>
161+
* <!ELEMENT firstName (#PCDATA)>
162+
* <!ELEMENT lastName (#PCDATA)>
163+
* ```
164+
*/
120165
class XMLDTD extends XMLLocatable, @xmldtd {
121166
/** Gets the name of the root element of this DTD. */
122167
string getRoot() { xmlDTDs(this, result, _, _, _) }
@@ -133,7 +178,6 @@ class XMLDTD extends XMLLocatable, @xmldtd {
133178
/** Gets the parent of this DTD. */
134179
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
135180

136-
/** Gets a printable representation of this DTD. */
137181
override string toString() {
138182
this.isPublic() and
139183
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
@@ -143,7 +187,17 @@ class XMLDTD extends XMLLocatable, @xmldtd {
143187
}
144188
}
145189

146-
/** An XML tag in an XML file. */
190+
/**
191+
* An XML element in an XML file.
192+
*
193+
* Example:
194+
*
195+
* ```
196+
* <manifest xmlns:android="http://schemas.android.com/apk/res/android"
197+
* package="com.example.exampleapp" android:versionCode="1">
198+
* </manifest>
199+
* ```
200+
*/
147201
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
148202
/** Holds if this XML element has the given `name`. */
149203
predicate hasName(string name) { name = getName() }
@@ -188,7 +242,16 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
188242
override string toString() { result = XMLParent.super.toString() }
189243
}
190244

191-
/** An attribute that occurs inside an XML element. */
245+
/**
246+
* An attribute that occurs inside an XML element.
247+
*
248+
* Examples:
249+
*
250+
* ```
251+
* package="com.example.exampleapp"
252+
* android:versionCode="1"
253+
* ```
254+
*/
192255
class XMLAttribute extends @xmlattribute, XMLLocatable {
193256
/** Gets the name of this attribute. */
194257
string getName() { xmlAttrs(this, _, result, _, _, _) }
@@ -209,7 +272,15 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
209272
override string toString() { result = this.getName() + "=" + this.getValue() }
210273
}
211274

212-
/** A namespace used in an XML file */
275+
/**
276+
* A namespace used in an XML file.
277+
*
278+
* Example:
279+
*
280+
* ```
281+
* xmlns:android="http://schemas.android.com/apk/res/android"
282+
* ```
283+
*/
213284
class XMLNamespace extends XMLLocatable, @xmlnamespace {
214285
/** Gets the prefix of this namespace. */
215286
string getPrefix() { xmlNs(this, result, _, _) }
@@ -227,7 +298,15 @@ class XMLNamespace extends XMLLocatable, @xmlnamespace {
227298
}
228299
}
229300

230-
/** A comment of the form `<!-- ... -->` is an XML comment. */
301+
/**
302+
* A comment in an XML file.
303+
*
304+
* Example:
305+
*
306+
* ```
307+
* <!-- This is a comment. -->
308+
* ```
309+
*/
231310
class XMLComment extends @xmlcomment, XMLLocatable {
232311
/** Gets the text content of this XML comment. */
233312
string getText() { xmlComments(this, result, _, _) }
@@ -242,6 +321,12 @@ class XMLComment extends @xmlcomment, XMLLocatable {
242321
/**
243322
* A sequence of characters that occurs between opening and
244323
* closing tags of an XML element, excluding other elements.
324+
*
325+
* Example:
326+
*
327+
* ```
328+
* <content>This is a sequence of characters.</content>
329+
* ```
245330
*/
246331
class XMLCharacters extends @xmlcharacters, XMLLocatable {
247332
/** Gets the content of this character sequence. */
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/** Provides classes for working with files and folders. */
22

33
import semmle.code.csharp.File
4+
import semmle.code.csharp.Location

java/ql/src/semmle/code/xml/XML.qll

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ abstract class XMLLocatable extends @xmllocatable {
99
/** Gets the source location for this element. */
1010
Location getLocation() { xmllocations(this, result) }
1111

12+
/**
13+
* DEPRECATED: Use `getLocation()` instead.
14+
*
15+
* Gets the source location for this element.
16+
*/
17+
deprecated Location getALocation() { result = this.getLocation() }
18+
1219
/**
1320
* Holds if this element is at the specified location.
1421
* The location spans column `startcolumn` of line `startline` to
@@ -155,7 +162,7 @@ class XMLFile extends XMLParent, File {
155162
* <!ELEMENT lastName (#PCDATA)>
156163
* ```
157164
*/
158-
class XMLDTD extends @xmldtd {
165+
class XMLDTD extends XMLLocatable, @xmldtd {
159166
/** Gets the name of the root element of this DTD. */
160167
string getRoot() { xmlDTDs(this, result, _, _, _) }
161168

@@ -171,8 +178,7 @@ class XMLDTD extends @xmldtd {
171178
/** Gets the parent of this DTD. */
172179
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
173180

174-
/** Gets a printable representation of this DTD. */
175-
string toString() {
181+
override string toString() {
176182
this.isPublic() and
177183
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
178184
or
@@ -275,7 +281,7 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
275281
* xmlns:android="http://schemas.android.com/apk/res/android"
276282
* ```
277283
*/
278-
class XMLNamespace extends @xmlnamespace {
284+
class XMLNamespace extends XMLLocatable, @xmlnamespace {
279285
/** Gets the prefix of this namespace. */
280286
string getPrefix() { xmlNs(this, result, _, _) }
281287

@@ -285,8 +291,7 @@ class XMLNamespace extends @xmlnamespace {
285291
/** Holds if this namespace has no prefix. */
286292
predicate isDefault() { this.getPrefix() = "" }
287293

288-
/** Gets a printable representation of this XML namespace. */
289-
string toString() {
294+
override string toString() {
290295
this.isDefault() and result = this.getURI()
291296
or
292297
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()

javascript/ql/src/semmle/javascript/XML.qll

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ abstract class XMLLocatable extends @xmllocatable {
99
/** Gets the source location for this element. */
1010
Location getLocation() { xmllocations(this, result) }
1111

12+
/**
13+
* DEPRECATED: Use `getLocation()` instead.
14+
*
15+
* Gets the source location for this element.
16+
*/
17+
deprecated Location getALocation() { result = this.getLocation() }
18+
1219
/**
1320
* Holds if this element is at the specified location.
1421
* The location spans column `startcolumn` of line `startline` to
@@ -155,7 +162,7 @@ class XMLFile extends XMLParent, File {
155162
* <!ELEMENT lastName (#PCDATA)>
156163
* ```
157164
*/
158-
class XMLDTD extends @xmldtd {
165+
class XMLDTD extends XMLLocatable, @xmldtd {
159166
/** Gets the name of the root element of this DTD. */
160167
string getRoot() { xmlDTDs(this, result, _, _, _) }
161168

@@ -171,8 +178,7 @@ class XMLDTD extends @xmldtd {
171178
/** Gets the parent of this DTD. */
172179
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
173180

174-
/** Gets a printable representation of this DTD. */
175-
string toString() {
181+
override string toString() {
176182
this.isPublic() and
177183
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
178184
or
@@ -275,7 +281,7 @@ class XMLAttribute extends @xmlattribute, XMLLocatable {
275281
* xmlns:android="http://schemas.android.com/apk/res/android"
276282
* ```
277283
*/
278-
class XMLNamespace extends @xmlnamespace {
284+
class XMLNamespace extends XMLLocatable, @xmlnamespace {
279285
/** Gets the prefix of this namespace. */
280286
string getPrefix() { xmlNs(this, result, _, _) }
281287

@@ -285,8 +291,7 @@ class XMLNamespace extends @xmlnamespace {
285291
/** Holds if this namespace has no prefix. */
286292
predicate isDefault() { this.getPrefix() = "" }
287293

288-
/** Gets a printable representation of this XML namespace. */
289-
string toString() {
294+
override string toString() {
290295
this.isDefault() and result = this.getURI()
291296
or
292297
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()

0 commit comments

Comments
 (0)