Copilot commented on code in PR #13424:
URL: https://github.com/apache/trafficserver/pull/13424#discussion_r4264052294


##########
plugins/header_rewrite/operators.cc:
##########
@@ -532,6 +533,70 @@ OperatorRMDestination::exec(const Resources &res) const
   return true;
 }
 
+// OperatorSortDestination
+void
+OperatorSortDestination::initialize(Parser &p)
+{
+  Operator::initialize(p);
+
+  _url_qual = parse_url_qualifier(p.get_arg());
+
+  require_resources(RSRC_CLIENT_REQUEST_HEADERS);
+  require_resources(RSRC_SERVER_REQUEST_HEADERS);
+}
+
+bool
+OperatorSortDestination::exec(const Resources &res) const
+{
+  if (res._rri || (res.bufp && res.hdr_loc)) {
+    TSMBuffer bufp;
+    TSMLoc    url_m_loc;
+
+    // Determine which TSMBuffer and TSMLoc to use
+    if (res._rri && !res.changed_url) {
+      bufp      = res._rri->requestBufp;
+      url_m_loc = res._rri->requestUrl;
+    } else {
+      bufp = res.bufp;
+      if (TSHttpHdrUrlGet(res.bufp, res.hdr_loc, &url_m_loc) != TS_SUCCESS) {
+        Dbg(pi_dbg_ctl, "TSHttpHdrUrlGet was unable to return the url m_loc");
+        return true;
+      }

Review Comment:
   `TSHttpHdrUrlGet` returns a `TSMLoc` that (in the TS API) must be released 
with `TSHandleMLocRelease` when obtained from an HTTP header. In this hunk, 
`url_m_loc` is never released, which can leak per-transaction resources. Track 
whether `url_m_loc` was acquired via `TSHttpHdrUrlGet` and release it on all 
exit paths (including early returns / error branches), e.g., via a small scope 
guard/RAII helper.



##########
plugins/header_rewrite/operators.cc:
##########
@@ -532,6 +533,70 @@ OperatorRMDestination::exec(const Resources &res) const
   return true;
 }
 
+// OperatorSortDestination
+void
+OperatorSortDestination::initialize(Parser &p)
+{
+  Operator::initialize(p);
+
+  _url_qual = parse_url_qualifier(p.get_arg());
+
+  require_resources(RSRC_CLIENT_REQUEST_HEADERS);
+  require_resources(RSRC_SERVER_REQUEST_HEADERS);
+}
+
+bool
+OperatorSortDestination::exec(const Resources &res) const
+{
+  if (res._rri || (res.bufp && res.hdr_loc)) {
+    TSMBuffer bufp;
+    TSMLoc    url_m_loc;
+
+    // Determine which TSMBuffer and TSMLoc to use
+    if (res._rri && !res.changed_url) {
+      bufp      = res._rri->requestBufp;
+      url_m_loc = res._rri->requestUrl;
+    } else {
+      bufp = res.bufp;
+      if (TSHttpHdrUrlGet(res.bufp, res.hdr_loc, &url_m_loc) != TS_SUCCESS) {
+        Dbg(pi_dbg_ctl, "TSHttpHdrUrlGet was unable to return the url m_loc");
+        return true;
+      }
+    }
+
+    switch (_url_qual) {
+    case URL_QUAL_QUERY: {
+      int              q_len = 0;
+      const char      *q_ptr = TSUrlHttpQueryGet(bufp, url_m_loc, &q_len);
+      std::string_view query = q_len > 0 ? std::string_view(q_ptr, 
static_cast<size_t>(q_len)) : std::string_view();
+
+      if (is_query_sorted(query)) {
+        Dbg(pi_dbg_ctl, "OperatorSortDestination::exec() QUERY already sorted, 
leaving it unchanged");
+        break;
+      }
+
+      std::string sorted = sort_query(query);
+
+      if (TSUrlHttpQuerySet(bufp, url_m_loc, sorted.c_str(), sorted.size()) != 
TS_SUCCESS) {
+        Dbg(pi_dbg_ctl, "OperatorSortDestination::exec() unable to set QUERY");
+        break;
+      }
+      const_cast<Resources &>(res).changed_url = true;
+      res.reset_query_cache();
+      Dbg(pi_dbg_ctl, "OperatorSortDestination::exec() rewrote QUERY to 
\"%s\"", sorted.c_str());
+      break;
+    }
+    default:
+      Dbg(pi_dbg_ctl, "Sort destination %i has no handler", _url_qual);
+      break;
+    }
+  } else {
+    Dbg(pi_dbg_ctl, "OperatorSortDestination::exec() unable to continue due to 
missing bufp=%p or hdr_loc=%p, rri=%p!", res.bufp,
+        res.hdr_loc, res._rri);
+  }

Review Comment:
   The top-level guard allows entry when `res._rri` is set even if 
`res.bufp/res.hdr_loc` are not, but the else-branch unconditionally 
dereferences `res.bufp`/`res.hdr_loc` (it’s taken whenever `res.changed_url` is 
true). This can lead to calling `TSHttpHdrUrlGet` with null/invalid handles. 
Restructure the selection logic so the `TSHttpHdrUrlGet` path is only taken 
when `(res.bufp && res.hdr_loc)` is true (or split into two explicit guarded 
branches: (1) `_rri && !changed_url`, (2) `bufp && hdr_loc`).



##########
plugins/header_rewrite/operators.cc:
##########
@@ -532,6 +533,70 @@ OperatorRMDestination::exec(const Resources &res) const
   return true;
 }
 
+// OperatorSortDestination
+void
+OperatorSortDestination::initialize(Parser &p)
+{
+  Operator::initialize(p);
+
+  _url_qual = parse_url_qualifier(p.get_arg());
+
+  require_resources(RSRC_CLIENT_REQUEST_HEADERS);
+  require_resources(RSRC_SERVER_REQUEST_HEADERS);
+}
+
+bool
+OperatorSortDestination::exec(const Resources &res) const
+{
+  if (res._rri || (res.bufp && res.hdr_loc)) {
+    TSMBuffer bufp;
+    TSMLoc    url_m_loc;
+
+    // Determine which TSMBuffer and TSMLoc to use
+    if (res._rri && !res.changed_url) {
+      bufp      = res._rri->requestBufp;
+      url_m_loc = res._rri->requestUrl;
+    } else {
+      bufp = res.bufp;
+      if (TSHttpHdrUrlGet(res.bufp, res.hdr_loc, &url_m_loc) != TS_SUCCESS) {
+        Dbg(pi_dbg_ctl, "TSHttpHdrUrlGet was unable to return the url m_loc");
+        return true;
+      }
+    }
+
+    switch (_url_qual) {
+    case URL_QUAL_QUERY: {
+      int              q_len = 0;
+      const char      *q_ptr = TSUrlHttpQueryGet(bufp, url_m_loc, &q_len);
+      std::string_view query = q_len > 0 ? std::string_view(q_ptr, 
static_cast<size_t>(q_len)) : std::string_view();
+
+      if (is_query_sorted(query)) {
+        Dbg(pi_dbg_ctl, "OperatorSortDestination::exec() QUERY already sorted, 
leaving it unchanged");
+        break;
+      }
+
+      std::string sorted = sort_query(query);
+
+      if (TSUrlHttpQuerySet(bufp, url_m_loc, sorted.c_str(), sorted.size()) != 
TS_SUCCESS) {

Review Comment:
   `TSUrlHttpQuerySet` typically takes the length as an `int`. Passing 
`sorted.size()` (a `size_t`) relies on an implicit narrowing conversion and can 
trigger compiler warnings (and is theoretically unsafe for very large inputs). 
Prefer an explicit cast to the TS API’s expected length type (and/or 
clamp/check) before calling.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to