Factor XML discard predicates into OverlayXml.qll

This commit is contained in:
Asger F
2025-11-19 15:11:04 +01:00
parent 0414555e43
commit dbf14c190a
12 changed files with 241 additions and 136 deletions

View File

@@ -2,6 +2,8 @@
* Defines entity discard predicates for Python overlay analysis.
*/
private import internal.OverlayXml
/*- Predicates -*/
/**
* Holds always for the overlay variant and never for the base variant.
@@ -303,33 +305,6 @@ final private class DiscardableComment extends Discardable instanceof @py_commen
}
}
/*- XML -*/
overlay[local]
final private class DiscardableXmlLocatable extends Discardable instanceof @xmllocatable {
override string getPath() {
exists(@location loc | xmllocations(this, loc) | result = getPathForLocation(loc))
}
}
overlay[local]
private predicate overlayXmlExtracted(string path) {
exists(DiscardableXmlLocatable d | not files(d, _) and not xmlNs(d, _, _, _) |
d.existsInOverlay() and
path = d.getPath()
)
}
overlay[discard_entity]
private predicate discardXmlLocatable(@xmllocatable el) {
exists(DiscardableXmlLocatable d | d = el |
// The XML extractor is currently not incremental and may extract more
// XML files than those included in `overlayChangedFiles`, so this discard predicate
// handles those files alongside the normal `discardStarEntity` logic.
overlayXmlExtracted(d.getPath()) and
d.existsInBase()
)
}
/*- YAML -*/
overlay[local]
final private class DiscardableYamlLocatable extends Discardable instanceof @yaml_locatable {

View File

@@ -0,0 +1,45 @@
overlay[local]
module;
/**
* A local predicate that always holds for the overlay variant and never holds for the base variant.
* This is used to define local predicates that behave differently for the base and overlay variant.
*/
private predicate isOverlay() { databaseMetadata("isOverlay", "true") }
private @file getXmlFile(@xmllocatable locatable) {
exists(@location_default location | xmllocations(locatable, location) |
locations_default(location, result, _, _, _, _)
)
}
private @file getXmlFileInBase(@xmllocatable locatable) {
not isOverlay() and
result = getXmlFile(locatable)
}
/**
* Holds if the given `file` was extracted as part of the overlay and was extracted by the HTML/XML
* extractor.
*/
private predicate overlayXmlExtracted(@file file) {
isOverlay() and
exists(@xmllocatable locatable |
not files(locatable, _) and not xmlNs(locatable, _, _, _) and file = getXmlFile(locatable)
)
}
/**
* Holds if the given XML `locatable` should be discarded, because it is part of the overlay base
* and is in a file that was also extracted as part of the overlay database.
*/
overlay[discard_entity]
private predicate discardXmlLocatable(@xmllocatable locatable) {
exists(@file file | file = getXmlFileInBase(locatable) |
exists(string path | files(file, path) | overlayChangedFiles(path))
or
// The HTML/XML extractor is currently not incremental and may extract more files than those
// included in overlayChangedFiles.
overlayXmlExtracted(file)
)
}