tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

checker.h (3175B)


      1 // Copyright 2020 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
     16 #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
     17 
     18 #include <algorithm>
     19 
     20 #include "absl/base/attributes.h"
     21 #include "absl/strings/internal/str_format/arg.h"
     22 #include "absl/strings/internal/str_format/constexpr_parser.h"
     23 #include "absl/strings/internal/str_format/extension.h"
     24 
     25 // Compile time check support for entry points.
     26 
     27 #ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
     28 // We disable format checker under vscode intellisense compilation.
     29 // See https://github.com/microsoft/vscode-cpptools/issues/3683 for
     30 // more details.
     31 #if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) && \
     32    !defined(__INTELLISENSE__)
     33 #define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1
     34 #endif  // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) &&
     35        // !defined(__INTELLISENSE__)
     36 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
     37 
     38 namespace absl {
     39 ABSL_NAMESPACE_BEGIN
     40 namespace str_format_internal {
     41 
     42 #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
     43 
     44 template <FormatConversionCharSet... C>
     45 constexpr bool ValidFormatImpl(string_view format) {
     46  int next_arg = 0;
     47  const char* p = format.data();
     48  const char* const end = p + format.size();
     49  constexpr FormatConversionCharSet
     50      kAllowedConvs[(std::max)(sizeof...(C), size_t{1})] = {C...};
     51  bool used[(std::max)(sizeof...(C), size_t{1})]{};
     52  constexpr int kNumArgs = sizeof...(C);
     53  while (p != end) {
     54    while (p != end && *p != '%') ++p;
     55    if (p == end) {
     56      break;
     57    }
     58    if (p + 1 >= end) return false;
     59    if (p[1] == '%') {
     60      // %%
     61      p += 2;
     62      continue;
     63    }
     64 
     65    UnboundConversion conv(absl::kConstInit);
     66    p = ConsumeUnboundConversion(p + 1, end, &conv, &next_arg);
     67    if (p == nullptr) return false;
     68    if (conv.arg_position <= 0 || conv.arg_position > kNumArgs) {
     69      return false;
     70    }
     71    if (!Contains(kAllowedConvs[conv.arg_position - 1], conv.conv)) {
     72      return false;
     73    }
     74    used[conv.arg_position - 1] = true;
     75    for (auto extra : {conv.width, conv.precision}) {
     76      if (extra.is_from_arg()) {
     77        int pos = extra.get_from_arg();
     78        if (pos <= 0 || pos > kNumArgs) return false;
     79        used[pos - 1] = true;
     80        if (!Contains(kAllowedConvs[pos - 1], '*')) {
     81          return false;
     82        }
     83      }
     84    }
     85  }
     86  if (sizeof...(C) != 0) {
     87    for (bool b : used) {
     88      if (!b) return false;
     89    }
     90  }
     91  return true;
     92 }
     93 
     94 #endif  // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
     95 
     96 }  // namespace str_format_internal
     97 ABSL_NAMESPACE_END
     98 }  // namespace absl
     99 
    100 #endif  // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_