Skip to content

Commit aa0b113

Browse files
author
Ruslan Nigmatullin
committed
pass UrlUnescapeSpec all the way through
1 parent 06868a8 commit aa0b113

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

src/include/grpc_transcoding/path_matcher.h

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,12 @@ inline int hex_digit_to_int(char c) {
223223
// If the next three characters are an escaped character then this function will
224224
// also return what character is escaped.
225225
bool GetEscapedChar(const std::string& src, size_t i,
226-
bool unescape_reserved_chars, bool unescape_slash_char,
227-
char* out) {
226+
UrlUnescapeSpec unescape_spec, char* out) {
227+
const bool unescape_slash_char =
228+
unescape_spec == UrlUnescapeSpec::kAllCharacters;
229+
const bool unescape_reserved_chars =
230+
(unescape_spec == UrlUnescapeSpec::kAllCharacters) ||
231+
(unescape_spec == UrlUnescapeSpec::kAllCharactersExceptSlash);
228232
if (i + 2 < src.size() && src[i] == '%') {
229233
if (ascii_isxdigit(src[i + 1]) && ascii_isxdigit(src[i + 2])) {
230234
char c =
@@ -246,15 +250,13 @@ bool GetEscapedChar(const std::string& src, size_t i,
246250
// (as specified in RFC 6570) are not escaped if unescape_reserved_chars is
247251
// false.
248252
std::string UrlUnescapeString(const std::string& part,
249-
bool unescape_reserved_chars,
250-
bool unescape_slash_char) {
253+
UrlUnescapeSpec unescape_spec) {
251254
std::string unescaped;
252255
// Check whether we need to escape at all.
253256
bool needs_unescaping = false;
254257
char ch = '\0';
255258
for (size_t i = 0; i < part.size(); ++i) {
256-
if (GetEscapedChar(part, i, unescape_reserved_chars, unescape_slash_char,
257-
&ch)) {
259+
if (GetEscapedChar(part, i, unescape_spec, &ch)) {
258260
needs_unescaping = true;
259261
break;
260262
}
@@ -270,8 +272,7 @@ std::string UrlUnescapeString(const std::string& part,
270272
char* p = begin;
271273

272274
for (size_t i = 0; i < part.size();) {
273-
if (GetEscapedChar(part, i, unescape_reserved_chars, unescape_slash_char,
274-
&ch)) {
275+
if (GetEscapedChar(part, i, unescape_spec, &ch)) {
275276
*p++ = ch;
276277
i += 3;
277278
} else {
@@ -288,8 +289,7 @@ template <class VariableBinding>
288289
void ExtractBindingsFromPath(const std::vector<HttpTemplate::Variable>& vars,
289290
const std::vector<std::string>& parts,
290291
std::vector<VariableBinding>* bindings,
291-
bool fully_decode_reserved_expansion,
292-
bool decode_slash_character) {
292+
UrlUnescapeSpec unescape_spec) {
293293
for (const auto& var : vars) {
294294
// Determine the subpath bound to the variable based on the
295295
// [start_segment, end_segment) segment range of the variable.
@@ -307,12 +307,13 @@ void ExtractBindingsFromPath(const std::vector<HttpTemplate::Variable>& vars,
307307
// multi-part match by checking if it->second.end_segment is negative.
308308
bool is_multipart =
309309
(end_segment - var.start_segment) > 1 || var.end_segment < 0;
310+
const UrlUnescapeSpec var_unescape_spec =
311+
is_multipart ? unescape_spec : UrlUnescapeSpec::kAllCharacters;
312+
310313
// Joins parts with "/" to form a path string.
311314
for (size_t i = var.start_segment; i < end_segment; ++i) {
312315
// For multipart matches only unescape non-reserved characters.
313-
binding.value += UrlUnescapeString(
314-
parts[i], fully_decode_reserved_expansion || !is_multipart,
315-
decode_slash_character || !is_multipart);
316+
binding.value += UrlUnescapeString(parts[i], var_unescape_spec);
316317
if (i < end_segment - 1) {
317318
binding.value += "/";
318319
}
@@ -345,7 +346,8 @@ void ExtractBindingsFromQueryParameters(
345346
// in the request, e.g. `book.author.name`.
346347
VariableBinding binding;
347348
split(name, '.', binding.field_path);
348-
binding.value = UrlUnescapeString(param.substr(pos + 1), true, true);
349+
binding.value = UrlUnescapeString(param.substr(pos + 1),
350+
UrlUnescapeSpec::kAllCharacters);
349351
bindings->emplace_back(std::move(binding));
350352
}
351353
}
@@ -456,11 +458,8 @@ Method PathMatcher<Method>::Lookup(
456458
MethodData* method_data = reinterpret_cast<MethodData*>(lookup_result.data);
457459
if (variable_bindings != nullptr) {
458460
variable_bindings->clear();
459-
ExtractBindingsFromPath(
460-
method_data->variables, parts, variable_bindings,
461-
unescape_spec_ == UrlUnescapeSpec::kAllCharacters ||
462-
unescape_spec_ == UrlUnescapeSpec::kAllCharactersExceptSlash,
463-
unescape_spec_ == UrlUnescapeSpec::kAllCharacters);
461+
ExtractBindingsFromPath(method_data->variables, parts, variable_bindings,
462+
unescape_spec_);
464463
ExtractBindingsFromQueryParameters(
465464
query_params, method_data->system_query_parameter_names,
466465
variable_bindings);

0 commit comments

Comments
 (0)