bloaty/third_party/re2/util/strutil.cc
Go to the documentation of this file.
1 // Copyright 1999-2005 The RE2 Authors. All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 #include <stdarg.h>
6 #include <stdio.h>
7 
8 #include "util/strutil.h"
9 
10 #ifdef _WIN32
11 #define snprintf _snprintf
12 #define vsnprintf _vsnprintf
13 #endif
14 
15 namespace re2 {
16 
17 // ----------------------------------------------------------------------
18 // CEscapeString()
19 // Copies 'src' to 'dest', escaping dangerous characters using
20 // C-style escape sequences. 'src' and 'dest' should not overlap.
21 // Returns the number of bytes written to 'dest' (not including the \0)
22 // or (size_t)-1 if there was insufficient space.
23 // ----------------------------------------------------------------------
24 static size_t CEscapeString(const char* src, size_t src_len,
25  char* dest, size_t dest_len) {
26  const char* src_end = src + src_len;
27  size_t used = 0;
28 
29  for (; src < src_end; src++) {
30  if (dest_len - used < 2) // space for two-character escape
31  return (size_t)-1;
32 
33  unsigned char c = *src;
34  switch (c) {
35  case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break;
36  case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break;
37  case '\t': dest[used++] = '\\'; dest[used++] = 't'; break;
38  case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
39  case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
40  case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
41  default:
42  // Note that if we emit \xNN and the src character after that is a hex
43  // digit then that digit must be escaped too to prevent it being
44  // interpreted as part of the character code by C.
45  if (c < ' ' || c > '~') {
46  if (dest_len - used < 5) // space for four-character escape + \0
47  return (size_t)-1;
48  snprintf(dest + used, 5, "\\%03o", c);
49  used += 4;
50  } else {
51  dest[used++] = c; break;
52  }
53  }
54  }
55 
56  if (dest_len - used < 1) // make sure that there is room for \0
57  return (size_t)-1;
58 
59  dest[used] = '\0'; // doesn't count towards return value though
60  return used;
61 }
62 
63 // ----------------------------------------------------------------------
64 // CEscape()
65 // Copies 'src' to result, escaping dangerous characters using
66 // C-style escape sequences. 'src' and 'dest' should not overlap.
67 // ----------------------------------------------------------------------
69  const size_t dest_len = src.size() * 4 + 1; // Maximum possible expansion
70  char* dest = new char[dest_len];
71  const size_t used = CEscapeString(src.data(), src.size(),
72  dest, dest_len);
73  std::string s = std::string(dest, used);
74  delete[] dest;
75  return s;
76 }
77 
79  // We can increment the last character in the string and be done
80  // unless that character is 255, in which case we have to erase the
81  // last character and increment the previous character, unless that
82  // is 255, etc. If the string is empty or consists entirely of
83  // 255's, we just return the empty string.
84  while (!prefix->empty()) {
85  char& c = prefix->back();
86  if (c == '\xff') { // char literal avoids signed/unsigned.
87  prefix->pop_back();
88  } else {
89  ++c;
90  break;
91  }
92  }
93 }
94 
95 static void StringAppendV(std::string* dst, const char* format, va_list ap) {
96  // First try with a small fixed size buffer
97  char space[1024];
98 
99  // It's possible for methods that use a va_list to invalidate
100  // the data in it upon use. The fix is to make a copy
101  // of the structure before using it and use that copy instead.
102  va_list backup_ap;
103  va_copy(backup_ap, ap);
104  int result = vsnprintf(space, sizeof(space), format, backup_ap);
105  va_end(backup_ap);
106 
107  if ((result >= 0) && (static_cast<size_t>(result) < sizeof(space))) {
108  // It fit
109  dst->append(space, result);
110  return;
111  }
112 
113  // Repeatedly increase buffer size until it fits
114  int length = sizeof(space);
115  while (true) {
116  if (result < 0) {
117  // Older behavior: just try doubling the buffer size
118  length *= 2;
119  } else {
120  // We need exactly "result+1" characters
121  length = result+1;
122  }
123  char* buf = new char[length];
124 
125  // Restore the va_list before we use it again
126  va_copy(backup_ap, ap);
127  result = vsnprintf(buf, length, format, backup_ap);
128  va_end(backup_ap);
129 
130  if ((result >= 0) && (result < length)) {
131  // It fit
132  dst->append(buf, result);
133  delete[] buf;
134  return;
135  }
136  delete[] buf;
137  }
138 }
139 
140 std::string StringPrintf(const char* format, ...) {
141  va_list ap;
142  va_start(ap, format);
144  StringAppendV(&result, format, ap);
145  va_end(ap);
146  return result;
147 }
148 
149 } // namespace re2
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
vsnprintf
int __cdecl vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
Definition: libc.cpp:135
http2_test_server.format
format
Definition: http2_test_server.py:118
re2::StringAppendV
static void StringAppendV(std::string *dst, const char *format, va_list ap)
Definition: bloaty/third_party/re2/util/strutil.cc:95
re2::StringPiece::size
size_type size() const
Definition: bloaty/third_party/re2/re2/stringpiece.h:80
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
re2
Definition: bloaty/third_party/re2/re2/bitmap256.h:17
re2::CEscapeString
static size_t CEscapeString(const char *src, size_t src_len, char *dest, size_t dest_len)
Definition: bloaty/third_party/re2/util/strutil.cc:24
re2::StringPrintf
std::string StringPrintf(const char *format,...)
Definition: bloaty/third_party/re2/util/strutil.cc:140
tests.qps.qps_worker.dest
dest
Definition: qps_worker.py:45
re2::PrefixSuccessor
void PrefixSuccessor(std::string *prefix)
Definition: bloaty/third_party/re2/util/strutil.cc:78
re2::StringPiece::data
const_pointer data() const
Definition: bloaty/third_party/re2/re2/stringpiece.h:85
re2::CEscape
std::string CEscape(const StringPiece &src)
Definition: bloaty/third_party/re2/util/strutil.cc:68
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
re2::StringPiece
Definition: bloaty/third_party/re2/re2/stringpiece.h:39


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:23