Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions java/ql/lib/change-notes/2026-01-27-struts-7-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added support for Struts 7.x package names in the Struts framework library. The library now recognizes both the legacy `com.opensymphony.xwork2` package names (Struts 2.x-6.x) and the new `org.apache.struts2` package names (Struts 7.x+), maintaining backward compatibility while enabling analysis of code using the latest Struts versions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ class Struts2ActionClass extends Class {
// If there are no XML files present, then we assume we any class that extends a struts 2
// action must be reflectively constructed, as we have no better indication.
not exists(XmlFile xmlFile) and
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action")
(
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action") or
this.getAnAncestor().hasQualifiedName("org.apache.struts2.action", "Action")
)
or
// If there is a struts.xml file, then any class that is specified as an action is considered
// to be reflectively constructed.
Expand Down Expand Up @@ -78,7 +81,8 @@ class Struts2ActionClass extends Class {
* Holds if this action class extends the preparable interface.
*/
predicate isPreparable() {
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Preparable")
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Preparable") or
this.getAnAncestor().hasQualifiedName("org.apache.struts2", "Preparable")
}

/**
Expand Down Expand Up @@ -122,7 +126,8 @@ class Struts2PrepareMethod extends Method {
*/
class Struts2ActionSupportClass extends Class {
Struts2ActionSupportClass() {
this.getASourceSupertype+().hasQualifiedName("com.opensymphony.xwork2", "ActionSupport")
this.getASourceSupertype+().hasQualifiedName("com.opensymphony.xwork2", "ActionSupport") or
this.getASourceSupertype+().hasQualifiedName("org.apache.struts2", "ActionSupport")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private string getConventionSuffix(RefType refType) {
*
* The convention plugin identifies as an action class any class that has an ancestor package with
* the name "struts", "struts2", "action" or "actions", and either has an indicative suffix on the
* name, or extends com.opensymphony.xwork2.Action.
* name, or extends com.opensymphony.xwork2.Action (Struts 2.x-6.x) or org.apache.struts2.action.Action (Struts 7.x+).
*/
class Struts2ConventionActionClass extends Class {
Struts2ConventionActionClass() {
Expand All @@ -108,7 +108,8 @@ class Struts2ConventionActionClass extends Class {
) and
(
this.getName().matches("%" + getConventionSuffix(this)) or
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action")
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action") or
this.getAnAncestor().hasQualifiedName("org.apache.struts2.action", "Action")
)
}

Expand Down