String f_exec(const String& command, VRefParam output /* = null */, VRefParam return_var /* = null */) { ShellExecContext ctx; FILE *fp = ctx.exec(command.c_str()); if (!fp) return ""; StringBuffer sbuf; sbuf.read(fp); Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray(); int ret = ctx.exit(); if (WIFEXITED(ret)) ret = WEXITSTATUS(ret); return_var = ret; int count = lines.size(); if (count > 0 && lines[count - 1].toString().empty()) { count--; // remove explode()'s last empty line } if (!output.is(KindOfArray)) { output = Array(ArrayData::Create()); } for (int i = 0; i < count; i++) { output.append(lines[i]); } if (!count || lines.empty()) { return String(); } return f_rtrim(lines[count - 1].toString()); }
String f_system(const String& command, VRefParam return_var /* = null */) { ShellExecContext ctx; FILE *fp = ctx.exec(command.c_str()); if (!fp) return ""; StringBuffer sbuf; if (fp) { sbuf.read(fp); } Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray(); int ret = ctx.exit(); if (WIFEXITED(ret)) ret = WEXITSTATUS(ret); return_var = ret; int count = lines.size(); if (count > 0 && lines[count - 1].toString().empty()) { count--; // remove explode()'s last empty line } for (int i = 0; i < count; i++) { echo(lines[i].toString()); echo("\n"); } if (!count || lines.empty()) { return String(); } return f_rtrim(lines[count - 1].toString()); }
void HHVM_FUNCTION(header, const String& str, bool replace /* = true */, int http_response_code /* = 0 */) { if (HHVM_FN(headers_sent)()) { raise_warning("Cannot modify header information - headers already sent"); } String header = f_rtrim(str); // new line safety check // NOTE: PHP actually allows "\n " and "\n\t" to fall through. Is that bad // for security? if (header.find('\n') >= 0 || header.find('\r') >= 0) { raise_warning("Header may not contain more than a single header, " "new line detected"); return; } Transport *transport = g_context->getTransport(); if (transport && header.size()) { const char *header_line = header.data(); // handle single line of status code if (header.size() >= 5 && strncasecmp(header_line, "HTTP/", 5) == 0) { int code = 200; const char *reason = nullptr; for (const char *ptr = header_line; *ptr; ptr++) { if (*ptr == ' ' && *(ptr + 1) != ' ') { code = atoi(ptr + 1); for (ptr++; *ptr; ptr++) { if (*ptr == ' ' && *(ptr + 1) != ' ') { reason = ptr + 1; break; } } break; } } if (code) { transport->setResponse(code, reason); } return; } const char *colon_offset = strchr(header_line, ':'); String newHeader; if (colon_offset) { if (!strncasecmp(header_line, "Content-Type", colon_offset - header_line)) { const char *ptr = colon_offset+1, *mimetype = NULL; while (*ptr == ' ') ptr++; mimetype = ptr; if (strncmp(mimetype, "text/", 5) == 0 && strstr(mimetype, "charset=") == NULL) { newHeader = header + ";charset=utf-8"; } } } if (replace) { transport->replaceHeader(newHeader.empty() ? header : newHeader); } else { transport->addHeader(newHeader.empty() ? header : newHeader); } if (http_response_code) { transport->setResponse(http_response_code, "explicit_header_response_code"); } } }
bool TestExtString::test_rtrim() { VS(f_rtrim(" abc "), " abc"); return Count(true); }