String StringUtil::SqlDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_stripslashes(input, len); return String(ret, len, AttachString); }
bool ini_on_update_long(CStrRef value, void *p) { if (p) { *((int64_t*)p) = value.toInt64(); } return true; }
Variant ZendPack::pack(CStrRef fmt, CArrRef argv) { /* Preprocess format into formatcodes and formatargs */ vector<char> formatcodes; vector<int> formatargs; int argc = argv.size(); const char *format = fmt.c_str(); int formatlen = fmt.size(); int currentarg = 0; for (int i = 0; i < formatlen; ) { char code = format[i++]; int arg = 1; /* Handle format arguments if any */ if (i < formatlen) { char c = format[i]; if (c == '*') { arg = -1; i++; } else if (c >= '0' && c <= '9') { arg = atoi(&format[i]); while (format[i] >= '0' && format[i] <= '9' && i < formatlen) { i++; } } } /* Handle special arg '*' for all codes and check argv overflows */ switch ((int) code) { /* Never uses any args */ case 'x': case 'X': case '@': if (arg < 0) { throw_invalid_argument("Type %c: '*' ignored", code); arg = 1; } break; /* Always uses one arg */ case 'a': case 'A': case 'h': case 'H': if (currentarg >= argc) { throw_invalid_argument("Type %c: not enough arguments", code); return false; } if (arg < 0) { arg = argv[currentarg].toString().size(); } currentarg++; break; /* Use as many args as specified */ case 'c': case 'C': case 's': case 'S': case 'i': case 'I': case 'l': case 'L': case 'n': case 'N': case 'v': case 'V': case 'f': case 'd': if (arg < 0) { arg = argc - currentarg; } currentarg += arg; if (currentarg > argc) { throw_invalid_argument("Type %c: too few arguments", code); return false; } break; default: throw_invalid_argument("Type %c: unknown format code", code); return false; } formatcodes.push_back(code); formatargs.push_back(arg); } if (currentarg < argc) { throw_invalid_argument("%d arguments unused", (argc - currentarg)); } int outputpos = 0, outputsize = 0; /* Calculate output length and upper bound while processing*/ for (int i = 0; i < (int)formatcodes.size(); i++) { int code = (int) formatcodes[i]; int arg = formatargs[i]; switch ((int) code) { case 'h': case 'H': INC_OUTPUTPOS((arg + (arg % 2)) / 2,1); /* 4 bit per arg */ break; case 'a': case 'A': case 'c': case 'C': case 'x': INC_OUTPUTPOS(arg,1); /* 8 bit per arg */ break; case 's': case 'S': case 'n': case 'v': INC_OUTPUTPOS(arg,2); /* 16 bit per arg */ break; case 'i': case 'I': INC_OUTPUTPOS(arg,sizeof(int)); break; case 'l': case 'L': case 'N': case 'V': INC_OUTPUTPOS(arg,4); /* 32 bit per arg */ break; case 'f': INC_OUTPUTPOS(arg,sizeof(float)); break; case 'd': INC_OUTPUTPOS(arg,sizeof(double)); break; case 'X': outputpos -= arg; if (outputpos < 0) { throw_invalid_argument("Type %c: outside of string", code); outputpos = 0; } break; case '@': outputpos = arg; break; } if (outputsize < outputpos) { outputsize = outputpos; } } String s = String(outputsize, ReserveString); char *output = s.mutableSlice().ptr; outputpos = 0; currentarg = 0; /* Do actual packing */ for (int i = 0; i < (int)formatcodes.size(); i++) { int code = (int) formatcodes[i]; int arg = formatargs[i]; String val; const char *s; int slen; switch ((int) code) { case 'a': case 'A': memset(&output[outputpos], (code == 'a') ? '\0' : ' ', arg); val = argv[currentarg++].toString(); s = val.c_str(); slen = val.size(); memcpy(&output[outputpos], s, (slen < arg) ? slen : arg); outputpos += arg; break; case 'h': case 'H': { int nibbleshift = (code == 'h') ? 0 : 4; int first = 1; const char *v; val = argv[currentarg++].toString(); v = val.data(); slen = val.size(); outputpos--; if(arg > slen) { throw_invalid_argument ("Type %c: not enough characters in string", code); arg = slen; } while (arg-- > 0) { char n = *v++; if (n >= '0' && n <= '9') { n -= '0'; } else if (n >= 'A' && n <= 'F') { n -= ('A' - 10); } else if (n >= 'a' && n <= 'f') { n -= ('a' - 10); } else { throw_invalid_argument("Type %c: illegal hex digit %c", code, n); n = 0; } if (first--) { output[++outputpos] = 0; } else { first = 1; } output[outputpos] |= (n << nibbleshift); nibbleshift = (nibbleshift + 4) & 7; } outputpos++; break; } case 'c': case 'C': while (arg-- > 0) { pack(argv[currentarg++], 1, byte_map, &output[outputpos]); outputpos++; } break; case 's': case 'S': case 'n': case 'v': { int *map = machine_endian_short_map; if (code == 'n') { map = big_endian_short_map; } else if (code == 'v') { map = little_endian_short_map; } while (arg-- > 0) { pack(argv[currentarg++], 2, map, &output[outputpos]); outputpos += 2; } break; } case 'i': case 'I': while (arg-- > 0) { pack(argv[currentarg++], sizeof(int), int_map, &output[outputpos]); outputpos += sizeof(int); } break; case 'l': case 'L': case 'N': case 'V': { int *map = machine_endian_int32_map; if (code == 'N') { map = big_endian_int32_map; } else if (code == 'V') { map = little_endian_int32_map; } while (arg-- > 0) { pack(argv[currentarg++], 4, map, &output[outputpos]); outputpos += 4; } break; } case 'f': { float v; while (arg-- > 0) { v = argv[currentarg++].toDouble(); memcpy(&output[outputpos], &v, sizeof(v)); outputpos += sizeof(v); } break; } case 'd': { double v; while (arg-- > 0) { v = argv[currentarg++].toDouble(); memcpy(&output[outputpos], &v, sizeof(v)); outputpos += sizeof(v); } break; } case 'x': memset(&output[outputpos], '\0', arg); outputpos += arg; break; case 'X': outputpos -= arg; if (outputpos < 0) { outputpos = 0; } break; case '@': if (arg > outputpos) { memset(&output[outputpos], '\0', arg - outputpos); } outputpos = arg; break; } } return s.setSize(outputpos); }
CVarRef ArrayData::getNotFound(CStrRef k) { raise_notice("Undefined index: %s", k.data()); return null_variant; }
bool BZ2File::open(CStrRef filename, CStrRef mode) { assert(m_bzFile == nullptr); return m_innerFile->open(filename, mode) && (m_bzFile = BZ2_bzdopen(dup(m_innerFile->fd()), mode.data())); }
int64_t f_furchash_hphp_ext(CStrRef key, int len, int nPart) { len = std::max(std::min(len, key.size()), 0); return furc_hash(key.data(), len, nPart); }
String StringUtil::Base64Decode(CStrRef input, bool strict /* = false */) { int len = input.size(); char *ret = string_base64_decode(input.data(), len, strict); return String(ret, len, AttachString); }
void Debugger::UnregisterSandbox(CStrRef id) { s_debugger.unregisterSandbox(id.get()); }
String StringUtil::HexDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_hex2bin(input, len); return String(ret, len, AttachString); }
String StringUtil::Base64Encode(CStrRef input) { int len = input.size(); char *ret = string_base64_encode(input.data(), len); return String(ret, len, AttachString); }
String StringUtil::QuotedPrintableDecode(CStrRef input) { if (input.empty()) return input; int len = input.size(); char *ret = string_quoted_printable_decode(input, len, false); return String(ret, len, AttachString); }
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, len, (StringHtmlEncoding)flags, am); if (!ret) { raise_error("HtmlEncode called on too large input (%d)", 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, len); return String(ret, len, AttachString); }
bool ini_on_update_real(CStrRef value, void *p) { if (p) { *((double*)p) = value.toDouble(); } return true; }
String StringUtil::ROT13(CStrRef input) { if (input.empty()) return input; return String(string_rot13(input, input.size()), input.size(), AttachString); }
bool ini_on_update_string(CStrRef value, void *p) { if (p) { *((std::string*)p) = std::string(value.data(), value.size()); } return true; }
int64 StringUtil::CRC32(CStrRef input) { return string_crc32(input, input.size()); }
DebuggerProxyPtr Debugger::GetProxy() { CStrRef sandboxId = g_context->getSandboxId(); return s_debugger.findProxy(sandboxId.get()); }
String StringUtil::SHA1(CStrRef input, bool raw /* = false */) { int len; char *ret = string_sha1(input, input.size(), raw, len); return String(ret, len, AttachString); }
bool f_hash_update(CObjRef context, CStrRef data) { HashContext *hash = context.getTyped<HashContext>(); hash->ops->hash_update(hash->context, (unsigned char *)data.data(), data.size()); return true; }
String StringUtil::Reverse(CStrRef input) { if (input.empty()) return input; int len = input.size(); return String(string_reverse(input.data(), len), len, AttachString); }
int64_t f_hphp_murmurhash(CStrRef key, int len, int seed) { len = std::max(std::min(len, key.size()), 0); return murmur_hash_64A(key.data(), len, seed); }
void StringBuffer::append(CStrRef s) { // REGISTER_MUTATED() is called by data() append(s.data(), s.size()); }
Variant ZendPack::unpack(CStrRef fmt, CStrRef data) { const char *format = fmt.c_str(); int formatlen = fmt.size(); const char *input = data.c_str(); int inputlen = data.size(); int inputpos = 0; Array ret; while (formatlen-- > 0) { char type = *(format++); char c; int arg = 1, argb; const char *name; int namelen; int size=0; /* Handle format arguments if any */ if (formatlen > 0) { c = *format; if (c >= '0' && c <= '9') { arg = atoi(format); while (formatlen > 0 && *format >= '0' && *format <= '9') { format++; formatlen--; } } else if (c == '*') { arg = -1; format++; formatlen--; } } /* Get of new value in array */ name = format; argb = arg; while (formatlen > 0 && *format != '/') { formatlen--; format++; } namelen = format - name; if (namelen > 200) namelen = 200; switch ((int) type) { /* Never use any input */ case 'X': size = -1; break; case '@': size = 0; break; case 'a': case 'A': size = arg; arg = 1; break; case 'h': case 'H': size = (arg > 0) ? (arg + (arg % 2)) / 2 : arg; arg = 1; break; /* Use 1 byte of input */ case 'c': case 'C': case 'x': size = 1; break; /* Use 2 bytes of input */ case 's': case 'S': case 'n': case 'v': size = 2; break; /* Use sizeof(int) bytes of input */ case 'i': case 'I': size = sizeof(int); break; /* Use 4 bytes of input */ case 'l': case 'L': case 'N': case 'V': size = 4; break; /* Use sizeof(float) bytes of input */ case 'f': size = sizeof(float); break; /* Use sizeof(double) bytes of input */ case 'd': size = sizeof(double); break; default: throw_invalid_argument("Invalid format type %c", type); return false; } /* Do actual unpacking */ for (int i = 0; i != arg; i++ ) { /* Space for name + number, safe as namelen is ensured <= 200 */ char n[256]; if (arg != 1 || namelen == 0) { /* Need to add element number to name */ snprintf(n, sizeof(n), "%.*s%d", namelen, name, i + 1); } else { /* Truncate name to next format code or end of string */ snprintf(n, sizeof(n), "%.*s", namelen, name); } if (size != 0 && size != -1 && INT_MAX - size + 1 < inputpos) { throw_invalid_argument("Type %c: integer overflow", type); inputpos = 0; } if ((inputpos + size) <= inputlen) { switch ((int) type) { case 'a': case 'A': { char pad = (type == 'a') ? '\0' : ' '; int len = inputlen - inputpos; /* Remaining string */ /* If size was given take minimum of len and size */ if ((size >= 0) && (len > size)) { len = size; } size = len; /* Remove padding chars from unpacked data */ while (--len >= 0) { if (input[inputpos + len] != pad) break; } ret.set(String(n, CopyString), String(input + inputpos, len + 1, CopyString)); break; } case 'h': case 'H': { int len = (inputlen - inputpos) * 2; /* Remaining */ int nibbleshift = (type == 'h') ? 0 : 4; int first = 1; char *buf; int ipos, opos; /* If size was given take minimum of len and size */ if (size >= 0 && len > (size * 2)) { len = size * 2; } if (argb > 0) { len -= argb % 2; } String s = String(len, ReserveString); buf = s.mutableSlice().ptr; for (ipos = opos = 0; opos < len; opos++) { char c = (input[inputpos + ipos] >> nibbleshift) & 0xf; if (c < 10) { c += '0'; } else { c += 'a' - 10; } buf[opos] = c; nibbleshift = (nibbleshift + 4) & 7; if (first-- == 0) { ipos++; first = 1; } } s.setSize(len); ret.set(String(n, CopyString), s); break; } case 'c': case 'C': { int issigned = (type == 'c') ? (input[inputpos] & 0x80) : 0; ret.set(String(n, CopyString), unpack(&input[inputpos], 1, issigned, byte_map)); break; } case 's': case 'S': case 'n': case 'v': { int issigned = 0; int *map = machine_endian_short_map; if (type == 's') { issigned = input[inputpos + (machine_little_endian ? 1 : 0)] & 0x80; } else if (type == 'n') { map = big_endian_short_map; } else if (type == 'v') { map = little_endian_short_map; } ret.set(String(n, CopyString), unpack(&input[inputpos], 2, issigned, map)); break; } case 'i': case 'I': { int32_t v = 0; int issigned = 0; if (type == 'i') { issigned = input[inputpos + (machine_little_endian ? (sizeof(int) - 1) : 0)] & 0x80; } else if (sizeof(int32_t) > 4 && (input[inputpos + machine_endian_int32_map[3]] & 0x80) == 0x80) { v = ~INT_MAX; } v |= unpack(&input[inputpos], sizeof(int), issigned, int_map); if (type == 'i') { ret.set(String(n, CopyString), v); } else { uint64_t u64 = uint32_t(v); ret.set(String(n, CopyString), u64); } break; } case 'l': case 'L': case 'N': case 'V': { int issigned = 0; int *map = machine_endian_int32_map; int32_t v = 0; if (type == 'l' || type == 'L') { issigned = input[inputpos + (machine_little_endian ? 3 : 0)] & 0x80; } else if (type == 'N') { issigned = input[inputpos] & 0x80; map = big_endian_int32_map; } else if (type == 'V') { issigned = input[inputpos + 3] & 0x80; map = little_endian_int32_map; } if (sizeof(int32_t) > 4 && issigned) { v = ~INT_MAX; } v |= unpack(&input[inputpos], 4, issigned, map); if (type == 'l') { ret.set(String(n, CopyString), v); } else { uint64_t u64 = uint32_t(v); ret.set(String(n, CopyString), u64); } break; } case 'f': { float v; memcpy(&v, &input[inputpos], sizeof(float)); ret.set(String(n, CopyString), (double)v); break; } case 'd': { double v; memcpy(&v, &input[inputpos], sizeof(double)); ret.set(String(n, CopyString), v); break; } case 'x': /* Do nothing with input, just skip it */ break; case 'X': if (inputpos < size) { inputpos = -size; i = arg - 1; /* Break out of for loop */ if (arg >= 0) { throw_invalid_argument("Type %c: outside of string", type); } } break; case '@': if (arg <= inputlen) { inputpos = arg; } else { throw_invalid_argument("Type %c: outside of string", type); } i = arg - 1; /* Done, break out of for loop */ break; } inputpos += size; if (inputpos < 0) { if (size != -1) { /* only print warning if not working with * */ throw_invalid_argument("Type %c: outside of string", type); } inputpos = 0; } } else if (arg < 0) { /* Reached end of input for '*' repeater */ break; } else { throw_invalid_argument ("Type %c: not enough input, need %d, have %d", type, size, inputlen - inputpos); return false; } } formatlen--; /* Skip '/' separator, does no harm if inputlen == 0 */ format++; }
bool IniSetting::Get(CStrRef name, String &value) { if (name == s_error_reporting) { value = String((int64_t)g_context->getErrorReportingLevel()); return true; } if (name == s_memory_limit) { int64_t v = g_context->getRequestMemoryMaxBytes(); if (v == INT64_MAX) v = -1; value = String(v); return true; } if (name == s_max_execution_time || name == s_maximum_execution_time) { int64_t timeout = ThreadInfo::s_threadInfo.getNoCheck()-> m_reqInjectionData.getTimeout(); value = String(timeout); return true; } if (name == s_hphp_build_id) { value = String(RuntimeOption::BuildId); return true; } if (name == s_hphp_compiler_version) { value = String(getHphpCompilerVersion()); return true; } if (name == s_hphp_compiler_id) { value = String(getHphpCompilerId()); return true; } if (name == s_arg_separator_output) { value = g_context->getArgSeparatorOutput(); return true; } if (name == s_upload_max_filesize) { int uploadMaxFilesize = VirtualHost::GetUploadMaxFileSize() / (1 << 20); value = String(uploadMaxFilesize) + "M"; return true; } if (name == s_post_max_size) { int postMaxSize = VirtualHost::GetMaxPostSize(); value = String(postMaxSize); return true; } if (name == s_log_errors) { value = g_context->getLogErrors() ? s_1 : s_0; return true; } if (name == s_error_log) { value = g_context->getErrorLog(); return true; } if (name == s_notice_frequency) { value = String((int64_t)RuntimeOption::NoticeFrequency); return true; } if (name == s_warning_frequency) { value = String((int64_t)RuntimeOption::WarningFrequency); return true; } if (name == s_include_path) { value = g_context->getIncludePath(); return true; } DefaultMap::iterator iter = s_global_ini.find(name.data()); if (iter != s_global_ini.end()) { value = iter->second; return true; } return false; }
bool ArrayData::IsValidKey(CStrRef k) { return IsValidKey(k.get()); }
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; }