Fix possible crash during array comparison with HackArrCompatCheckCompare
[hiphop-php.git] / hphp / util / text-util.cpp
blobd85a699e1e1b016ce6f9454491b90435e100ef83
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/util/text-util.h"
19 #include <cassert>
20 #include <cstring> // memcpy
21 #include <string>
22 #include <vector>
23 #include "hphp/util/string-vsnprintf.h"
25 namespace HPHP {
27 using std::string;
28 using std::vector;
30 void replaceAll(string &s, const char *from, const char *to) {
31 assert(from && *from);
32 assert(to);
34 string::size_type lenFrom = strlen(from);
35 string::size_type lenTo = strlen(to);
36 for (string::size_type pos = s.find(from);
37 pos != string::npos;
38 pos = s.find(from, pos + lenTo)) {
39 s.replace(pos, lenFrom, to);
43 std::string toLower(folly::StringPiece s) {
44 std::string ret;
45 ret.reserve(s.size());
46 for (auto const c : s) {
47 ret += tolower(c);
49 return ret;
52 std::string toUpper(folly::StringPiece s) {
53 std::string ret;
54 ret.reserve(s.size());
55 for (auto const c : s) {
56 ret += toupper(c);
58 return ret;
61 std::string getIdentifier(const std::string &fileName) {
62 string ret = "hphp_" + fileName;
63 replaceAll(ret, "/", "__");
64 replaceAll(ret, ".", "__");
65 replaceAll(ret, "-", "__");
66 return ret;
69 std::string escapeStringForCPP(const char *input, int len,
70 bool* binary /* = NULL */) {
71 if (binary) *binary = false;
72 string ret;
73 ret.reserve((len << 1) + 2);
74 for (int i = 0; i < len; i++) {
75 unsigned char ch = input[i];
76 switch (ch) {
77 case '\n': ret += "\\n"; break;
78 case '\r': ret += "\\r"; break;
79 case '\t': ret += "\\t"; break;
80 case '\a': ret += "\\a"; break;
81 case '\b': ret += "\\b"; break;
82 case '\f': ret += "\\f"; break;
83 case '\v': ret += "\\v"; break;
84 case '\0': ret += "\\000"; if (binary) *binary = true; break;
85 case '\"': ret += "\\\""; break;
86 case '\\': ret += "\\\\"; break;
87 case '?': ret += "\\?"; break; // avoiding trigraph errors
88 default:
89 if (isprint(ch)) {
90 ret += ch;
91 } else {
92 // output in octal notation
93 char buf[10];
94 snprintf(buf, sizeof(buf), "\\%03o", ch);
95 ret += buf;
97 break;
100 return ret;
103 std::string escapeStringForPHP(const char *input, int len) {
104 string output;
105 output.reserve((len << 1) + 2);
106 output = "'";
107 for (int i = 0; i < len; i++) {
108 unsigned char ch = input[i];
109 switch (ch) {
110 case '\n': output += "'.\"\\n\".'"; break;
111 case '\r': output += "'.\"\\r\".'"; break;
112 case '\t': output += "'.\"\\t\".'"; break;
113 case '\'': output += "'.\"'\".'"; break;
114 case '\\': output += "'.\"\\\\\".'"; break;
115 case '\0': output += "'.\"\\0\".'"; break;
116 default:
117 output += ch;
118 break;
121 output += "'";
122 replaceAll(output, ".''.", ".");
123 replaceAll(output, "''.", "");
124 replaceAll(output, ".''", "");
125 replaceAll(output, "\".\"", "");
126 return output;
129 const void *buffer_duplicate(const void *src, size_t size) {
130 char *s = (char *)malloc(size + 1); // '\0' in the end
131 memcpy(s, src, size);
132 s[size] = '\0';
133 return s;
136 const void *buffer_append(const void *buf1, size_t size1,
137 const void *buf2, size_t size2) {
138 char *s = (char *)realloc(const_cast<void *>(buf1), size1 + size2 + 1);
139 memcpy((char *)s + size1, buf2, size2);
140 s[size1 + size2] = '\0';
141 return s;
144 void string_printf(std::string &msg, const char *fmt, ...) {
145 va_list ap;
146 va_start(ap, fmt);
147 string_vsnprintf(msg, fmt, ap);
148 va_end(ap);
151 std::string format_pattern(const std::string &pattern, bool prefixSlash) {
152 if (pattern.empty()) return pattern;
154 std::string ret = "#";
155 for (unsigned int i = 0; i < pattern.size(); i++) {
156 char ch = pattern[i];
158 // apache rewrite rules don't require initial slash
159 if (prefixSlash && i == 0 && ch == '^') {
160 char ch1 = pattern[1];
161 if (ch1 != '/' && ch1 != '(') {
162 ret += "^/";
163 continue;
167 if (ch == '#') {
168 ret += "\\#";
169 } else {
170 ret += ch;
173 ret += '#';
174 return ret;
177 } // namespace HPHP