void readRelocations( FILE* relocFile, std::set<TCA>* liveStubs, void (*callback)(TransRelocInfo&& tri, void* data), void* data) { std::string line; uint64_t addr; uint64_t end; while (readLine(line, relocFile)) { int n; if (sscanf(line.c_str(), "%" SCNx64 " %" SCNx64 "%n", &addr, &end, &n) >= 2) { auto pos = line.rfind(' '); if (pos == n) { if (liveStubs && !end) { if (!strcmp("NewStub", line.c_str() + pos + 1)) { liveStubs->insert((TCA)addr); } else if (!strcmp("FreeStub", line.c_str() + pos + 1)) { liveStubs->erase((TCA)addr); } } continue; } assert(pos != std::string::npos && pos > n); auto b64 = line.substr(pos + 1); String decoded = string_base64_decode(b64.c_str(), b64.size(), true); BlobDecoder blob(decoded.data(), decoded.size()); TransRelocInfoHelper trih; blob(trih); TransRelocInfo tri(trih.toTRI(code())); tri.start = reinterpret_cast<TCA>(addr); tri.end = reinterpret_cast<TCA>(end); x64::findFixups(tri.start, tri.end, tri.fixups); callback(std::move(tri), data); } } }
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); }
String StringUtil::Base64Decode(const String& input, bool strict /* = false */) { int len = input.size(); return string_base64_decode(input.data(), len, strict); }
File* DataStreamWrapper::open(const String& filename, const String& mode, int options, const Variant& context) { // @todo: check allow_url_include? const char* data = filename.data(); int data_len = filename.length(); bool base64 = false; if (strncmp(data, "data:", sizeof("data:") - 1)) { return nullptr; } data += sizeof("data:") - 1; data_len -= sizeof("data:") - 1; // RFC 2397 specifies 'data:' as the prefix, // but zend's PHP supports 'data://' as well if (data_len >= 2 && data[0] == '/' && data[1] == '/') { data_len -= 2; data += 2; } char* comma = (char*)memchr(data, ',', data_len); if (comma == nullptr) { raise_warning("rfc2397: missing comma"); return nullptr; } if (comma != data) { // we have meta ssize_t meta_len = comma - data; data_len -= meta_len; char* semi = (char*)memchr(data, ';', meta_len); char* slash = (char*)memchr(data, '/', meta_len); if (!slash && !semi) { raise_warning("rfc2397: invalid meta data"); return nullptr; } if (!semi) { // only media type (type/subtype,data) ssize_t media_len = comma - data; meta_len -= media_len; data += media_len; } else if (slash && slash < semi) { // media type + param (type/subtype;param,data) ssize_t media_len = semi - data; meta_len -= media_len; data += media_len; } else { // no media type (;base64,data) if (semi != data // ex. foo;base64,data || meta_len != sizeof(";base64") - 1 // ex. ;something,data || memcmp(data, ";base64", sizeof(";base64") - 1)) { // ex. ;base65,data raise_warning("rfc2397: invalid meta data"); return nullptr; } } assert(data == comma || data == semi); // eat parameters, and figure out if we have ';base64' while (semi && (data == semi)) { data++; meta_len--; char* equals = (char*)memchr(data, '=', meta_len); semi = (char*)memchr(data, ';', meta_len); if (!equals || (semi && semi < data)) { // no equals, so either 'base64' or its bad if (meta_len != sizeof("base64") - 1 || memcmp(data, "base64", sizeof("base64")-1)) { raise_warning("rfc2396: invalid parameter"); return nullptr; } // it's "base64", we're done base64 = true; meta_len -= sizeof("base64") - 1; data += sizeof("base64") - 1; break; } // there's a parameter if (semi) { meta_len -= semi - data + 1; data = semi; } /* else, we're done with meta */ } } data = comma + 1; data_len -= 1; std::unique_ptr<MemFile> file; String decoded; if (base64) { decoded = string_base64_decode(data, data_len, true); if (decoded.isNull()) { raise_warning("unable to decode base64 data"); return nullptr; } } else { decoded = url_decode(data, data_len); } file = std::unique_ptr<MemFile>(NEWOBJ(MemFile)(decoded.data(), decoded.size())); return file.release(); }