Variant f_bzopen(CVarRef filename, CStrRef mode) { if (mode != "r" && mode != "w") { raise_warning( "'%s' is not a valid mode for bzopen(). " "Only 'w' and 'r' are supported.", mode.data() ); return false; } BZ2File *bz; if (filename.isString()) { if (filename.asCStrRef().empty()) { raise_warning("filename cannot be empty"); return false; } bz = NEWOBJ(BZ2File)(); bool ret = bz->open(File::TranslatePath(filename.toString()), mode); if (!ret) { raise_warning("%s", Util::safe_strerror(errno).c_str()); return false; } } else { if (!filename.isResource()) { raise_warning("first parameter has to be string or file-resource"); return false; } PlainFile* f = filename.cast<PlainFile>(); if (!f) { return false; } std::string stream_mode = f->getMode(); int stream_mode_len = stream_mode.length(); if (stream_mode_len != 1 && !(stream_mode_len == 2 && stream_mode.find('b') != string::npos)) { raise_warning("cannot use stream opened in mode '%s'", stream_mode.c_str()); return false; } else if (stream_mode_len == 1 && stream_mode[0] != 'r' && stream_mode[0] != 'w' && stream_mode[0] != 'a' && stream_mode[0] != 'x') { raise_warning("cannot use stream opened in mode '%s'", stream_mode.c_str()); return false; } const char rw_mode = stream_mode[0]; if (mode == "r" && rw_mode != 'r') { raise_warning("cannot write to a stream opened in read only mode"); return false; } else if (mode == "w" && rw_mode != 'w' && rw_mode != 'a' && rw_mode != 'x') { raise_warning("cannot read from a stream opened in write only mode"); return false; } bz = NEWOBJ(BZ2File)(f); } Object handle(bz); return handle; }
Object Certificate::Get(CVarRef var) { if (var.isResource()) { return var.toObject(); } if (var.isString() || var.isObject()) { bool file; BIO *in = ReadData(var, &file); if (in == nullptr) return Object(); X509 *cert; /* if (file) { cert = PEM_read_bio_X509(in, NULL, NULL, NULL); } else { cert = (X509 *)PEM_ASN1_read_bio ((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); } */ cert = PEM_read_bio_X509(in, nullptr, nullptr, nullptr); BIO_free(in); if (cert) { return Object(new Certificate(cert)); } } return Object(); }
bool same(CVarRef v1, CResRef v2) { bool null1 = v1.isNull(); bool null2 = v2.isNull(); if (null1 && null2) return true; if (null1 || null2) return false; if (!v1.isResource()) return false; auto const rd = v1.getResourceData(); return rd == v2.get(); }
static int php_posix_get_fd(CVarRef fd) { int nfd; if (fd.isResource()) { File *f = fd.toObject().getTyped<File>(); if (!f) { return false; } nfd = f->fd(); } else { nfd = fd.toInt32(); } return nfd; }
bool f_stream_is_local(CVarRef stream_or_url) { if (stream_or_url.isString()) { auto wrapper = Stream::getWrapperFromURI(stream_or_url.asCStrRef()); return wrapper->m_isLocal; } else if (stream_or_url.isResource()) { File* file = dynamic_cast<File*>(stream_or_url.asCResRef().get()); if (!file) { raise_warning("supplied resource is not a valid stream resource"); return false; } return file->m_isLocal; } // Zend returns true for random data types... return true; }
Variant Array::rvalAt(CVarRef key, bool error /* = false */, bool isKey /* = false */) const { if (!m_px) return null_variant; switch (key.m_type) { case KindOfNull: return m_px->get(empty_string, error); case KindOfBoolean: case KindOfByte: case KindOfInt16: case KindOfInt32: case KindOfInt64: return m_px->get(key.m_data.num, error); case KindOfDouble: return m_px->get((int64)key.m_data.dbl, error); case KindOfStaticString: case KindOfString: { int64 n; if (!isKey && key.m_data.pstr->isStrictlyInteger(n)) { return m_px->get(n, error); } else { return m_px->get(key.asCStrRef(), error); } } case KindOfArray: throw_bad_type_exception("Invalid type used as key"); break; case KindOfObject: if (key.isResource()) { return m_px->get(key.toInt64(), error); } throw_bad_type_exception("Invalid type used as key"); break; case KindOfVariant: return rvalAt(*(key.m_data.pvar), error, isKey); default: ASSERT(false); break; } return null_variant; }
CVarRef Array::rvalAtRef(CVarRef key, ACCESSPARAMS_IMPL) const { if (!m_px) return null_variant; switch (key.m_type) { case KindOfUninit: case KindOfNull: return m_px->get(empty_string, flags & AccessFlags::Error); case KindOfBoolean: case KindOfInt32: case KindOfInt64: return m_px->get(key.m_data.num, flags & AccessFlags::Error); case KindOfDouble: return m_px->get((int64)key.m_data.dbl, flags & AccessFlags::Error); case KindOfStaticString: case KindOfString: { int64 n; if (!(flags & AccessFlags::Key) && key.m_data.pstr->isStrictlyInteger(n)) { return m_px->get(n, flags & AccessFlags::Error); } else { return m_px->get(key.asCStrRef(), flags & AccessFlags::Error); } } case KindOfArray: throw_bad_type_exception("Invalid type used as key"); break; case KindOfObject: if (key.isResource()) { return m_px->get(key.toInt64(), flags & AccessFlags::Error); } throw_bad_type_exception("Invalid type used as key"); break; case KindOfVariant: return rvalAtRef(*(key.m_data.pvar), flags); default: ASSERT(false); break; } return null_variant; }
bool f_is_object(CVarRef var) { return var.is(KindOfObject) && !var.isResource(); }
bool f_is_resource(CVarRef v) { return v.isResource(); }
bool setOption(long option, CVarRef value) { if (m_cp == NULL) { return false; } m_error_no = CURLE_OK; switch (option) { case CURLOPT_INFILESIZE: case CURLOPT_VERBOSE: case CURLOPT_HEADER: case CURLOPT_NOPROGRESS: case CURLOPT_NOBODY: case CURLOPT_FAILONERROR: case CURLOPT_UPLOAD: case CURLOPT_POST: case CURLOPT_FTPLISTONLY: case CURLOPT_FTPAPPEND: case CURLOPT_NETRC: case CURLOPT_PUT: case CURLOPT_TIMEOUT: #if LIBCURL_VERSION_NUM >= 0x071002 case CURLOPT_TIMEOUT_MS: #endif case CURLOPT_FTP_USE_EPSV: case CURLOPT_LOW_SPEED_LIMIT: case CURLOPT_SSLVERSION: case CURLOPT_LOW_SPEED_TIME: case CURLOPT_RESUME_FROM: case CURLOPT_TIMEVALUE: case CURLOPT_TIMECONDITION: case CURLOPT_TRANSFERTEXT: case CURLOPT_HTTPPROXYTUNNEL: case CURLOPT_FILETIME: case CURLOPT_MAXREDIRS: case CURLOPT_MAXCONNECTS: case CURLOPT_CLOSEPOLICY: case CURLOPT_FRESH_CONNECT: case CURLOPT_FORBID_REUSE: case CURLOPT_CONNECTTIMEOUT: #if LIBCURL_VERSION_NUM >= 0x071002 case CURLOPT_CONNECTTIMEOUT_MS: #endif case CURLOPT_SSL_VERIFYHOST: case CURLOPT_SSL_VERIFYPEER: //case CURLOPT_DNS_USE_GLOBAL_CACHE: not thread-safe when set to true case CURLOPT_NOSIGNAL: case CURLOPT_PROXYTYPE: case CURLOPT_BUFFERSIZE: case CURLOPT_HTTPGET: case CURLOPT_HTTP_VERSION: case CURLOPT_CRLF: case CURLOPT_DNS_CACHE_TIMEOUT: case CURLOPT_PROXYPORT: case CURLOPT_FTP_USE_EPRT: case CURLOPT_HTTPAUTH: case CURLOPT_PROXYAUTH: case CURLOPT_FTP_CREATE_MISSING_DIRS: case CURLOPT_FTPSSLAUTH: case CURLOPT_FTP_SSL: case CURLOPT_UNRESTRICTED_AUTH: case CURLOPT_PORT: case CURLOPT_AUTOREFERER: case CURLOPT_COOKIESESSION: case CURLOPT_TCP_NODELAY: case CURLOPT_IPRESOLVE: case CURLOPT_FOLLOWLOCATION: m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, value.toInt64()); break; case CURLOPT_RETURNTRANSFER: m_write.method = value.toBoolean() ? PHP_CURL_RETURN : PHP_CURL_STDOUT; break; case CURLOPT_BINARYTRANSFER: m_write.type = value.toBoolean() ? PHP_CURL_BINARY : PHP_CURL_ASCII; break; case CURLOPT_PRIVATE: case CURLOPT_URL: case CURLOPT_PROXY: case CURLOPT_USERPWD: case CURLOPT_PROXYUSERPWD: case CURLOPT_RANGE: case CURLOPT_CUSTOMREQUEST: case CURLOPT_USERAGENT: case CURLOPT_FTPPORT: case CURLOPT_COOKIE: case CURLOPT_REFERER: case CURLOPT_INTERFACE: case CURLOPT_KRB4LEVEL: case CURLOPT_EGDSOCKET: case CURLOPT_CAINFO: case CURLOPT_CAPATH: case CURLOPT_SSL_CIPHER_LIST: case CURLOPT_SSLKEY: case CURLOPT_SSLKEYTYPE: case CURLOPT_SSLKEYPASSWD: case CURLOPT_SSLENGINE: case CURLOPT_SSLENGINE_DEFAULT: case CURLOPT_SSLCERTTYPE: case CURLOPT_ENCODING: case CURLOPT_COOKIEJAR: case CURLOPT_SSLCERT: case CURLOPT_RANDOM_FILE: case CURLOPT_COOKIEFILE: { String svalue = value.toString(); #if LIBCURL_VERSION_NUM >= 0x071100 /* Strings passed to libcurl as 'char *' arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */ m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, svalue.c_str()); #else char *copystr = strndup(svalue.data(), svalue.size()); m_to_free->str.push_back(copystr); m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, copystr); #endif if (option == CURLOPT_URL) m_url = value; } break; case CURLOPT_FILE: case CURLOPT_INFILE: case CURLOPT_WRITEHEADER: case CURLOPT_STDERR: { if (!value.isResource()) { return false; } Resource obj = value.toResource(); if (obj.isNull() || obj.getTyped<File>(true) == NULL) { return false; } switch (option) { case CURLOPT_FILE: m_write.fp = obj; m_write.method = PHP_CURL_FILE; break; case CURLOPT_WRITEHEADER: m_write_header.fp = obj; m_write_header.method = PHP_CURL_FILE; break; case CURLOPT_INFILE: m_read.fp = obj; m_emptyPost = false; break; default: { if (obj.getTyped<PlainFile>(true) == NULL) { return false; } FILE *fp = obj.getTyped<PlainFile>()->getStream(); if (!fp) { return false; } m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, fp); break; } } } break; case CURLOPT_WRITEFUNCTION: m_write.callback = value; m_write.method = PHP_CURL_USER; break; case CURLOPT_READFUNCTION: m_read.callback = value; m_read.method = PHP_CURL_USER; m_emptyPost = false; break; case CURLOPT_HEADERFUNCTION: m_write_header.callback = value; m_write_header.method = PHP_CURL_USER; break; case CURLOPT_POSTFIELDS: m_emptyPost = false; if (value.is(KindOfArray) || value.is(KindOfObject)) { Array arr = value.toArray(); curl_httppost *first = NULL; curl_httppost *last = NULL; for (ArrayIter iter(arr); iter; ++iter) { String key = iter.first().toString(); String val = iter.second().toString(); const char *postval = val.data(); /* The arguments after _NAMELENGTH and _CONTENTSLENGTH * must be explicitly cast to long in curl_formadd * use since curl needs a long not an int. */ if (*postval == '@') { ++postval; m_error_no = (CURLcode)curl_formadd (&first, &last, CURLFORM_COPYNAME, key.data(), CURLFORM_NAMELENGTH, (long)key.size(), CURLFORM_FILE, postval, CURLFORM_END); } else { m_error_no = (CURLcode)curl_formadd (&first, &last, CURLFORM_COPYNAME, key.data(), CURLFORM_NAMELENGTH, (long)key.size(), CURLFORM_COPYCONTENTS, postval, CURLFORM_CONTENTSLENGTH,(long)val.size(), CURLFORM_END); } } if (m_error_no != CURLE_OK) { return false; } m_to_free->post.push_back(first); m_error_no = curl_easy_setopt(m_cp, CURLOPT_HTTPPOST, first); } else { String svalue = value.toString(); #if LIBCURL_VERSION_NUM >= 0x071100 /* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */ m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE, svalue.size()); m_error_no = curl_easy_setopt(m_cp, CURLOPT_COPYPOSTFIELDS, svalue.c_str()); #else char *post = strndup(svalue.data(), svalue.size()); m_to_free->str.push_back(post); m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDS, post); m_error_no = curl_easy_setopt(m_cp, CURLOPT_POSTFIELDSIZE, svalue.size()); #endif } break; case CURLOPT_HTTPHEADER: case CURLOPT_QUOTE: case CURLOPT_HTTP200ALIASES: case CURLOPT_POSTQUOTE: if (value.is(KindOfArray) || value.is(KindOfObject)) { Array arr = value.toArray(); curl_slist *slist = NULL; for (ArrayIter iter(arr); iter; ++iter) { String key = iter.first().toString(); String val = iter.second().toString(); slist = curl_slist_append(slist, val.c_str()); if (!slist) { raise_warning("Could not build curl_slist"); return false; } } m_to_free->slist.push_back(slist); m_error_no = curl_easy_setopt(m_cp, (CURLoption)option, slist); } else { raise_warning("You must pass either an object or an array with " "the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, " "CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE " "arguments"); return false; } break; case CURLINFO_HEADER_OUT: if (value.toInt64() == 1) { curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, curl_debug); curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, (void *)this); curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 1); } else { curl_easy_setopt(m_cp, CURLOPT_DEBUGFUNCTION, NULL); curl_easy_setopt(m_cp, CURLOPT_DEBUGDATA, NULL); curl_easy_setopt(m_cp, CURLOPT_VERBOSE, 0); } break; case CURLOPT_FB_TLS_VER_MAX: { int64_t val = value.toInt64(); if (value.isInteger() && (val == CURLOPT_FB_TLS_VER_MAX_1_0 || val == CURLOPT_FB_TLS_VER_MAX_1_1 || val == CURLOPT_FB_TLS_VER_MAX_NONE)) { m_opts.set(int64_t(option), value); } else { raise_warning("You must pass CURLOPT_FB_TLS_VER_MAX_1_0, " "CURLOPT_FB_TLS_VER_MAX_1_1 or " "CURLOPT_FB_TLS_VER_MAX_NONE with " "CURLOPT_FB_TLS_VER_MAX"); } } break; case CURLOPT_FB_TLS_CIPHER_SPEC: if (value.isString() && !value.toString().empty()) { m_opts.set(int64_t(option), value); } else { raise_warning("CURLOPT_FB_TLS_CIPHER_SPEC requires a non-empty string"); } break; default: m_error_no = CURLE_FAILED_INIT; throw_invalid_argument("option: %ld", option); break; } m_opts.set(int64_t(option), value); return m_error_no == CURLE_OK; }