String StringUtil::CDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_stripcslashes(input, len); return String(ret, len, AttachString); }
Variant StringUtil::Explode(CStrRef input, CStrRef delimiter, int limit /* = 0x7FFFFFFF */) { if (delimiter.empty()) { throw_invalid_argument("delimiter: (empty)"); return false; } Array ret(Array::Create()); if (input.empty()) { if (limit >= 0) { ret.append(""); } return ret; } if (limit > 1) { int pos = input.find(delimiter); if (pos < 0) { ret.append(input); } else { int len = delimiter.size(); int pos0 = 0; do { ret.append(input.substr(pos0, pos - pos0)); pos += len; pos0 = pos; } while ((pos = input.find(delimiter, pos)) >= 0 && --limit > 1); if (pos0 <= input.size()) { ret.append(input.substr(pos0)); } } } else if (limit < 0) { int pos = input.find(delimiter); if (pos >= 0) { vector<int> positions; int len = delimiter.size(); int pos0 = 0; int found = 0; do { positions.push_back(pos0); positions.push_back(pos - pos0); pos += len; pos0 = pos; found++; } while ((pos = input.find(delimiter, pos)) >= 0); if (pos0 <= input.size()) { positions.push_back(pos0); positions.push_back(input.size() - pos0); found++; } int iMax = (found + limit) << 1; for (int i = 0; i < iMax; i += 2) { ret.append(input.substr(positions[i], positions[i+1])); } } // else we have negative limit and delimiter not found } else { ret.append(input); } return ret; }
Variant f_strtr(CStrRef str, CVarRef from, CVarRef to /* = null_variant */) { if (str.empty()) { return str; } if (!to.isNull()) { TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE); return StringUtil::Translate(str, from.toString(), to.toString()); } if (!from.is(KindOfArray)) { throw_invalid_argument("2nd argument: (not array)"); return false; } int maxlen = 0; int minlen = -1; Array arr = from.toArray(); if (arr.empty()) { // Nothing to translate return str; } for (ArrayIter iter(arr); iter; ++iter) { String search = iter.first(); int len = search.size(); if (len < 1) return false; if (maxlen < len) maxlen = len; if (minlen == -1 || minlen > len) minlen = len; } TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE); const char *s = str.data(); int slen = str.size(); char *key = (char *)malloc(maxlen+1); StringBuffer result(slen); for (int pos = 0; pos < slen; ) { if ((pos + maxlen) > slen) { maxlen = slen - pos; } bool found = false; memcpy(key, s + pos, maxlen); for (int len = maxlen; len >= minlen; len--) { key[len] = 0; if (arr.exists(key)) { String replace = arr[key].toString(); if (!replace.empty()) { result += replace; } pos += len; found = true; break; } } if (!found) { result += s[pos++]; } } free(key); return result.detach(); }
String StringUtil::QuotedPrintableDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_quoted_printable_decode(input.data(), len, false); return String(ret, len, AttachString); }
String StringUtil::ROT13(CStrRef input) { if (input.empty()) return input; return String(string_rot13(input.data(), input.size()), input.size(), AttachString); }
String StringUtil::HexEncode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_bin2hex(input, len); return String(ret, len, AttachString); }
String StringUtil::RegExEncode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_quotemeta(input.c_str(), len); return String(ret, len, AttachString); }
bool f_mcrypt_module_self_test(CStrRef algorithm, CStrRef lib_dir /* = null_string */) { String dir = lib_dir.empty() ? MCG(algorithms_dir) : lib_dir; return mcrypt_module_self_test((char*)algorithm.data(), (char*)dir.data()) == 0; }
static Variant php_mcrypt_do_crypt(CStrRef cipher, CStrRef key, CStrRef data, CStrRef mode, CStrRef iv, bool dencrypt) { MCRYPT td = mcrypt_module_open((char*)cipher.data(), (char*)MCG(algorithms_dir).data(), (char*)mode.data(), (char*)MCG(modes_dir).data()); if (td == MCRYPT_FAILED) { raise_warning(MCRYPT_OPEN_MODULE_FAILED); return false; } /* Checking for key-length */ int max_key_length = mcrypt_enc_get_key_size(td); if (key.size() > max_key_length) { raise_warning("Size of key is too large for this algorithm"); } int count; int *key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count); int use_key_length; char *key_s = NULL; if (count == 0 && key_length_sizes == NULL) { // all lengths 1 - k_l_s = OK use_key_length = key.size(); key_s = (char*)malloc(use_key_length); memcpy(key_s, key.data(), use_key_length); } else if (count == 1) { /* only m_k_l = OK */ key_s = (char*)malloc(key_length_sizes[0]); memset(key_s, 0, key_length_sizes[0]); memcpy(key_s, key.data(), MIN(key.size(), key_length_sizes[0])); use_key_length = key_length_sizes[0]; } else { /* dertermine smallest supported key > length of requested key */ use_key_length = max_key_length; /* start with max key length */ for (int i = 0; i < count; i++) { if (key_length_sizes[i] >= key.size() && key_length_sizes[i] < use_key_length) { use_key_length = key_length_sizes[i]; } } key_s = (char*)malloc(use_key_length); memset(key_s, 0, use_key_length); memcpy(key_s, key.data(), MIN(key.size(), use_key_length)); } mcrypt_free(key_length_sizes); /* Check IV */ char *iv_s = NULL; int iv_size = mcrypt_enc_get_iv_size(td); if (!iv.empty()) { if (iv_size != iv.size()) { raise_warning("The IV parameter must be as long as the blocksize"); } else { iv_s = (char*)malloc(iv_size + 1); memcpy(iv_s, iv.data(), iv_size); } } else if (iv_size != 0) { raise_warning("Attempt to use an empty IV, which is NOT recommended"); iv_s = (char*)malloc(iv_size + 1); memset(iv_s, 0, iv_size + 1); } int block_size; unsigned long int data_size; char *data_s; /* Check blocksize */ if (mcrypt_enc_is_block_mode(td) == 1) { /* It's a block algorithm */ block_size = mcrypt_enc_get_block_size(td); data_size = (((data.size() - 1) / block_size) + 1) * block_size; data_s = (char*)malloc(data_size + 1); memset(data_s, 0, data_size); memcpy(data_s, data.data(), data.size()); } else { /* It's not a block algorithm */ data_size = data.size(); data_s = (char*)malloc(data_size + 1); memcpy(data_s, data.data(), data.size()); } if (mcrypt_generic_init(td, key_s, use_key_length, iv_s) < 0) { raise_warning("Mcrypt initialisation failed"); return false; } if (dencrypt) { mdecrypt_generic(td, data_s, data_size); } else { mcrypt_generic(td, data_s, data_size); } data_s[data_size] = '\0'; String ret(data_s, data_size, AttachString); /* freeing vars */ mcrypt_generic_end(td); if (key_s != NULL) { free(key_s); } if (iv_s != NULL) { free(iv_s); } return ret; }
bool f_mcrypt_module_is_block_algorithm(CStrRef algorithm, CStrRef lib_dir /* = null_string */) { String dir = lib_dir.empty() ? MCG(algorithms_dir) : lib_dir; return mcrypt_module_is_block_algorithm((char*)algorithm.data(), (char*)dir.data()) == 1; }
bool f_mcrypt_module_is_block_mode(CStrRef mode, CStrRef lib_dir /* = null_string */) { String dir = lib_dir.empty() ? MCG(modes_dir) : lib_dir; return mcrypt_module_is_block_mode((char*)mode.data(), (char*)dir.data()) == 1; }
int f_mcrypt_module_get_algo_key_size(CStrRef algorithm, CStrRef lib_dir /* = null_string */) { String dir = lib_dir.empty() ? MCG(algorithms_dir) : lib_dir; return mcrypt_module_get_algo_key_size((char*)algorithm.data(), (char*)dir.data()); }
HOT_FUNC String String::operator+(CStrRef str) const { if (empty()) return str; if (str.empty()) return *this; return NEW(StringData)(slice(), str.slice()); }
bool f_posix_initgroups(CStrRef name, int base_group_id) { if (name.empty()) return false; return !initgroups(name.data(), base_group_id); }
String StringUtil::ToLower(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_to_lower(input.data(), len); return String(ret, len, AttachString); }
bool String::less(CStrRef v2) const { if (m_px == NULL && v2.get() == NULL) return false; if (m_px == NULL) return !v2.empty(); if (v2.get() == NULL) return empty(); return m_px->compare(v2.get()) < 0; }
String StringUtil::QuotedPrintableEncode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_quoted_printable_encode(input, len); return String(ret, len, AttachString); }
bool String::more(CStrRef v2) const { if (m_px == NULL && v2.get() == NULL) return false; if (m_px == NULL) return v2.empty(); if (v2.get() == NULL) return !empty(); return m_px->compare(v2.get()) > 0; }
Variant f_getaddrinfo(CStrRef host, CStrRef port, int family /* = 0 */, int socktype /* = 0 */, int protocol /* = 0 */, int flags /* = 0 */) { const char *hptr = NULL, *pptr = NULL; if (!host.empty()) { hptr = host.c_str(); } if (!port.empty()) { pptr = port.c_str(); } struct addrinfo hints, *res; struct addrinfo *res0 = NULL; int error; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = socktype; hints.ai_protocol = protocol; hints.ai_flags = flags; error = getaddrinfo(hptr, pptr, &hints, &res0); if (error) { raise_warning("%s", gai_strerror(error)); if (res0) { freeaddrinfo(res0); } return false; } Array ret = Array::Create(); for (res = res0; res; res = res->ai_next) { Array data = Array::Create(); Array sockinfo = Array::Create(); data.set(s_family, res->ai_family); data.set(s_socktype, res->ai_socktype); data.set(s_protocol, res->ai_protocol); switch (res->ai_addr->sa_family) { case AF_INET: { struct sockaddr_in *a; String buffer = ipaddr_convert(res->ai_addr, sizeof(*a)); if (!buffer.empty()) { a = (struct sockaddr_in *)res->ai_addr; sockinfo.set(s_address, buffer); sockinfo.set(s_port, ntohs(a->sin_port)); } break; } case AF_INET6: { struct sockaddr_in6 *a; String buffer = ipaddr_convert(res->ai_addr, sizeof(*a)); if (!buffer.empty()) { a = (struct sockaddr_in6 *)res->ai_addr; sockinfo.set(s_address, buffer); sockinfo.set(s_port, ntohs(a->sin6_port)); sockinfo.set(s_flow_info, (int32_t)a->sin6_flowinfo); sockinfo.set(s_scope_id, (int32_t)a->sin6_scope_id); } break; } } data.set(s_sockaddr, (sockinfo.empty() ? nullptr : sockinfo)); ret.append(data); } if (res0) { freeaddrinfo(res0); } return ret; }
String File::readRecord(CStrRef delimiter, int64 maxlen /* = 0 */) { if (eof() && m_writepos == m_readpos) { return empty_string; } if (maxlen <= 0 || maxlen > CHUNK_SIZE) { maxlen = CHUNK_SIZE; } int64 avail = m_writepos - m_readpos; if (m_buffer == NULL) { m_buffer = (char *)malloc(CHUNK_SIZE * 3); } if (avail < maxlen && !eof()) { assert(m_writepos + maxlen - avail <= CHUNK_SIZE * 3); m_writepos += readImpl(m_buffer + m_writepos, maxlen - avail); maxlen = m_writepos - m_readpos; } if (m_readpos >= CHUNK_SIZE) { memcpy(m_buffer, m_buffer + m_readpos, m_writepos - m_readpos); m_writepos -= m_readpos; m_readpos = 0; } int64 toread; const char *e; bool skip = false; if (delimiter.empty()) { toread = maxlen; } else { if (delimiter.size() == 1) { e = (const char *)memchr(m_buffer + m_readpos, delimiter.charAt(0), m_writepos - m_readpos); } else { int64 pos = string_find(m_buffer + m_readpos, m_writepos - m_readpos, delimiter.data(), delimiter.size(), 0, true); if (pos >= 0) { e = m_buffer + m_readpos + pos; } else { e = NULL; } } if (!e) { toread = maxlen; } else { toread = e - m_buffer - m_readpos; skip = true; } } if (toread > maxlen && maxlen > 0) { toread = maxlen; } if (toread >= 0) { String s = String(toread, ReserveString); char *buf = s.mutableSlice().ptr; if (toread) { memcpy(buf, m_buffer + m_readpos, toread); } m_readpos += toread; if (skip) { m_readpos += delimiter.size(); m_position += delimiter.size(); } return s.setSize(toread); } return empty_string; }
String StringUtil::HtmlEncodeExtra(CStrRef input, QuoteStyle quoteStyle, const char *charset, bool nbsp, Array extra) { if (input.empty()) return input; assert(charset); int flags = STRING_HTML_ENCODE_UTF8; if (nbsp) { flags |= STRING_HTML_ENCODE_NBSP; } if (RuntimeOption::Utf8izeReplace) { flags |= STRING_HTML_ENCODE_UTF8IZE_REPLACE; } if (!*charset || strcasecmp(charset, "UTF-8") == 0) { } else if (strcasecmp(charset, "ISO-8859-1") == 0) { flags &= ~STRING_HTML_ENCODE_UTF8; } else { throw NotImplementedException(charset); } const AsciiMap *am; AsciiMap tmp; switch (quoteStyle) { case FBUtf8Only: am = &mapNothing; flags |= STRING_HTML_ENCODE_HIGH; break; case FBUtf8: am = &mapBothQuotes; flags |= STRING_HTML_ENCODE_HIGH; break; case BothQuotes: am = &mapBothQuotes; break; case DoubleQuotes: am = &mapDoubleQuotes; break; case NoQuotes: am = &mapNoQuotes; break; default: am = &mapNothing; raise_error("Unknown quote style: %d", (int)quoteStyle); } if (quoteStyle != FBUtf8Only && extra.toBoolean()) { tmp = *am; am = &tmp; for (ArrayIter iter(extra); iter; ++iter) { String item = iter.second().toString(); char c = item.data()[0]; tmp.map[c & 64 ? 1 : 0] |= 1uLL << (c & 63); } } int len = input.size(); char *ret = string_html_encode_extra(input.data(), len, (StringHtmlEncoding)flags, am); if (!ret) { raise_error("HtmlEncode called on too large input (%d)", len); } return String(ret, len, AttachString); }
static bool isLocalHost(CStrRef host) { return host.empty() || host == "localhost" || host == "127.0.0.1"; }
String StringUtil::HexDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_hex2bin(input.data(), len); return String(ret, len, AttachString); }
Variant f_date(CStrRef format, int64_t timestamp /* = TimeStamp::Current() */) { if (format.empty()) return ""; String ret = DateTime(timestamp, false).toString(format, false); if (ret.isNull()) return false; return ret; }
String StringUtil::Reverse(CStrRef input) { if (input.empty()) return input; int len = input.size(); return String(string_reverse(input.data(), len), len, AttachString); }
bool Transport::setCookie(CStrRef name, CStrRef value, int64 expire /* = 0 */, CStrRef path /* = "" */, CStrRef domain /* = "" */, bool secure /* = false */, bool httponly /* = false */, bool encode_url /* = true */) { if (!name.empty() && strpbrk(name.data(), "=,; \t\r\n\013\014")) { Logger::Warning("Cookie names can not contain any of the following " "'=,; \\t\\r\\n\\013\\014'"); return false; } if (!encode_url && !value.empty() && strpbrk(value.data(), ",; \t\r\n\013\014")) { Logger::Warning("Cookie values can not contain any of the following " "',; \\t\\r\\n\\013\\014'"); return false; } char *encoded_value = NULL; int len = 0; if (!value.empty() && encode_url) { int encoded_value_len = value.size(); encoded_value = url_encode(value.data(), encoded_value_len); len += encoded_value_len; } else if (!value.empty()) { encoded_value = strdup(value.data()); len += value.size(); } len += path.size(); len += domain.size(); std::string cookie; cookie.reserve(len + 100); if (value.empty()) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ String sdt = DateTime(1, true) .toString(DateTime::Cookie); cookie += name.data(); cookie += "=deleted; expires="; cookie += sdt.data(); } else { cookie += name.data(); cookie += "="; cookie += encoded_value ? encoded_value : ""; if (expire > 0) { if (expire > 253402300799LL) { raise_warning("Expiry date cannot have a year greater then 9999"); return false; } cookie += "; expires="; String sdt = DateTime(expire, true).toString(DateTime::Cookie); cookie += sdt.data(); } } if (encoded_value) { free(encoded_value); } if (!path.empty()) { cookie += "; path="; cookie += path.data(); } if (!domain.empty()) { cookie += "; domain="; cookie += domain.data(); } if (secure) { cookie += "; secure"; } if (httponly) { cookie += "; httponly"; } FiberWriteLock lock(this); m_responseCookies[name.data()] = cookie; return true; }
String StringUtil::SqlEncode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_addslashes(input.c_str(), len); return String(ret, len, AttachString); }
String StringUtil::HtmlDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_html_decode(input, len); return String(ret, len, AttachString); }