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


##########
plugins/header_rewrite/condition.cc:
##########
@@ -75,6 +75,30 @@ parse_matcher_op(std::string &arg)
   }
 }
 
+void
+Condition::normalize(std::string &s, size_t start)
+{
+  auto pos = s.find('%', start);
+
+  // Percent-decoding is the only normalization so far.
+  if (pos == std::string::npos) {
+    return;
+  }
+
+  size_t len     = s.size() - pos;
+  size_t written = 0;
+
+  // Decoding shrinks, so in place is safe; the extra byte is for the NUL it 
appends.
+  s.push_back('\0');
+
+  if (TSStringPercentDecode(s.data() + pos, len, s.data() + pos, len + 1, 
&written) != TS_SUCCESS) {
+    written = len;
+    Dbg(pi_dbg_ctl, "Failed to percent-decode, leaving the value untouched");
+  }

Review Comment:
   This decoder is also used for `%{... [NORM]}` operator values, so a 
client-controlled path such as `%0d%0aX-Evil:%20yes` becomes raw CR/LF in the 
expanded string. `set-header` passes that string (with its explicit length) to 
the MIME field setter, which stores and serializes the bytes without filtering, 
allowing a configured response/request header to inject additional lines. 
Please reject or sanitize decoded control bytes for value expansions before 
they reach header/body sinks, or otherwise constrain NORM's output alphabet.



##########
plugins/header_rewrite/condition.cc:
##########
@@ -75,6 +75,30 @@ parse_matcher_op(std::string &arg)
   }
 }
 
+void
+Condition::normalize(std::string &s, size_t start)
+{
+  auto pos = s.find('%', start);
+
+  // Percent-decoding is the only normalization so far.
+  if (pos == std::string::npos) {
+    return;
+  }
+
+  size_t len     = s.size() - pos;
+  size_t written = 0;
+
+  // Decoding shrinks, so in place is safe; the extra byte is for the NUL it 
appends.
+  s.push_back('\0');
+
+  if (TSStringPercentDecode(s.data() + pos, len, s.data() + pos, len + 1, 
&written) != TS_SUCCESS) {
+    written = len;
+    Dbg(pi_dbg_ctl, "Failed to percent-decode, leaving the value untouched");
+  }

Review Comment:
   `TSStringPercentDecode()` does not report malformed input as `TS_ERROR` (the 
implementation always returns `TS_SUCCESS`), and its `unescape_str()` path 
drops an incomplete trailing escape. Consequently the fallback at lines 95-96 
is unreachable: with `[NORM]`, a value ending in `%` or `%4` is shortened 
instead of preserved, which can create false matches and contradicts the 
malformed-escape behavior tested in the new gold test. Preserve incomplete 
escapes or explicitly reject/leave the value unchanged before calling this 
decoder.



##########
plugins/header_rewrite/value.cc:
##########
@@ -51,9 +54,19 @@ Value::set_value(const std::string &val, Statement *owner)
       Condition *tcond_val = nullptr;
 
       if (token.substr(0, 2) == "%{") {
-        std::string cond_token = token.substr(2, token.size() - 3);
+        std::string    cond_token = token.substr(2, token.size() - 3);
+        swoc::TextView cond_name{cond_token};
+
+        // The factory only wants the condition and its qualifier, so hide any 
trailing
+        // [MODS] from it. The Parser still sees them, and initialize() 
consumes them.
+        if (cond_name.ends_with(']')) {
+          if (auto pos = cond_name.rfind('['); pos != swoc::TextView::npos) {

Review Comment:
   The new stripping logic treats any qualifier that ends in `]` as if it had a 
modifier suffix. This regresses valid query-parameter expansions such as 
`%{CLIENT-URL:QUERY:foo[]}`: `rfind('[')` removes `[]` before 
`condition_factory()` sees it, so the lookup is performed for `foo` instead of 
`foo[]`. Require whitespace before the `[` (the actual `%{} [MODS]` syntax) 
before removing this suffix.



-- 
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