Beispiel #1
0
bool c_XSLTProcessor::t_setprofiling(const String& filename) {
  if (filename.length() > 0) {
    String translated = File::TranslatePath(filename);
    Stream::Wrapper* w = Stream::getWrapperFromURI(translated);
    if (!w) return false;
    if (w->access(translated, W_OK)) {
      m_profile = translated;
      return true;
    }
  }

  return false;
}
static bool findFileWrapper(const String& file, void* ctx) {
  ResolveIncludeContext* context = (ResolveIncludeContext*)ctx;
  assert(context->path.isNull());

  Stream::Wrapper* w = Stream::getWrapperFromURI(file);
  if (!dynamic_cast<FileStreamWrapper*>(w)) {
    if (w->stat(file, context->s) == 0) {
      context->path = file;
      return true;
    }
  }

  // handle file://
  if (file.substr(0, 7) == s_file_url) {
    return findFileWrapper(file.substr(7), ctx);
  }

  // TranslatePath() will canonicalize the path and also check
  // whether the file is in an allowed directory.
  String translatedPath = File::TranslatePathKeepRelative(file);
  if (file[0] != '/') {
    if (HPHP::Eval::FileRepository::findFile(translatedPath.get(),
                                             context->s)) {
      context->path = translatedPath;
      return true;
    }
    return false;
  }
  if (RuntimeOption::SandboxMode || !RuntimeOption::AlwaysUseRelativePath) {
    if (HPHP::Eval::FileRepository::findFile(translatedPath.get(),
                                             context->s)) {
      context->path = translatedPath;
      return true;
    }
  }
  string server_root(SourceRootInfo::GetCurrentSourceRoot());
  if (server_root.empty()) {
    server_root = string(g_vmContext->getCwd()->data());
    if (server_root.empty() || server_root[server_root.size() - 1] != '/') {
      server_root += "/";
    }
  }
  String rel_path(Util::relativePath(server_root, translatedPath.data()));
  if (HPHP::Eval::FileRepository::findFile(rel_path.get(),
                                           context->s)) {
    context->path = rel_path;
    return true;
  }
  return false;
}
Beispiel #3
0
Resource File::Open(const String& filename, const String& mode,
                    int options /* = 0 */,
                    const Variant& context /* = null */) {
    Stream::Wrapper *wrapper = Stream::getWrapperFromURI(filename);
    if (!wrapper) return Resource();
    Resource rcontext =
        context.isNull() ? g_context->getStreamContext() : context.toResource();
    File *file = wrapper->open(filename, mode, options, rcontext);
    if (file != nullptr) {
        file->m_name = filename.data();
        file->m_mode = mode.data();
        file->m_streamContext = rcontext;
    }
    return Resource(file);
}
Beispiel #4
0
static bool HHVM_METHOD(XSLTProcessor, setProfiling,
                        const String& filename) {
  auto data = Native::data<XSLTProcessorData>(this_);

  if (filename.length() > 0) {
    String translated = File::TranslatePath(filename);
    Stream::Wrapper* w = Stream::getWrapperFromURI(translated);
    if (!w) return false;
    if (w->access(translated, W_OK)) {
      data->m_profile = translated;
      return true;
    }
  }

  return false;
}
PhpFile *FileRepository::checkoutFile(StringData *rname,
                                      const struct stat &s) {
  FileInfo fileInfo;
  PhpFile *ret = nullptr;
  String name(rname);
  bool isPlainFile = File::IsPlainFilePath(name);

  if (isPlainFile) {
    if (rname->data()[0] != '/') {
      name = String(SourceRootInfo::GetCurrentSourceRoot()) + name;
    }
    // Get the common fast path out of the way with as little locking
    // as possible: it's in the map and has not changed on disk
    ParsedFilesMap::const_accessor acc;
    if (s_files.find(acc, name.get()) && !acc->second->isChanged(s)) {
      TRACE(1, "FR fast path hit %s\n", rname->data());
      ret = acc->second->getPhpFile();
      return ret;
    }
  } else {
    // Do the read before we get the repo lock, since it will call into the
    // stream library and will needs its own locks.
    if (isAuthoritativeRepo()) {
      throw FatalErrorException(
        "including urls doesn't work in RepoAuthoritative mode"
      );
    }
    Stream::Wrapper* w = Stream::getWrapperFromURI(name);
    File* f = w->open(name, "r", 0, null_variant);
    if (!f) return nullptr;
    StringBuffer sb;
    sb.read(f);
    fileInfo.m_inputString = sb.detach();
    computeMd5(name.get(), fileInfo);
  }

  TRACE(1, "FR fast path miss: %s\n", rname->data());
  const StringData *n = makeStaticString(name.get());

  PhpFile* toKill = nullptr;
  SCOPE_EXIT {
    // run this after acc is destroyed (and its lock released)
    if (toKill) toKill->decRefAndDelete();
  };
  ParsedFilesMap::accessor acc;
  bool isNew = s_files.insert(acc, n);
  PhpFileWrapper* old = acc->second;
  SCOPE_EXIT {
    // run this just before acc is released
    if (old && old != acc->second) {
      if (old->getPhpFile() != acc->second->getPhpFile()) {
        toKill = old->getPhpFile();
      }
      delete old;
    }
    if (!acc->second) s_files.erase(acc);
  };

  assert(isNew || old); // We don't leave null entries around.
  bool isChanged = !isNew && old->isChanged(s);

  if (isNew || isChanged) {
    if (isPlainFile && !readFile(n, s, fileInfo)) {
      TRACE(1, "File disappeared between stat and FR::readNewFile: %s\n",
            rname->data());
      return nullptr;
    }
    ret = fileInfo.m_phpFile;
    if (isChanged && ret == old->getPhpFile()) {
      // The file changed but had the same contents.
      if (debug && md5Enabled()) {
        ReadLock lock(s_md5Lock);
        assert(s_md5Files.find(ret->getMd5())->second == ret);
      }
      return ret;
    }
  } else if (!isNew) {
    // Somebody might have loaded the file between when we dropped
    // our read lock and got the write lock
    ret = old->getPhpFile();
    return ret;
  }

  // If we get here the file was not in s_files or has changed on disk
  if (!ret) {
    // Try to read Unit from .hhbc repo.
    ret = readHhbc(n->data(), fileInfo);
  }
  if (!ret) {
    if (isAuthoritativeRepo()) {
      raise_error("Tried to parse %s in repo authoritative mode", n->data());
    }
    ret = parseFile(n->data(), fileInfo);
    if (!ret) return nullptr;
  }
  assert(ret != nullptr);

  if (isNew) {
    acc->second = new PhpFileWrapper(s, ret);
    ret->incRef();
    ret->setId(Transl::TargetCache::allocBit());
  } else {
    PhpFile *f = old->getPhpFile();
    if (f != ret) {
      ret->setId(f->getId());
      ret->incRef();
    }
    acc->second = new PhpFileWrapper(s, ret);
  }

  if (md5Enabled()) {
    WriteLock lock(s_md5Lock);
    s_md5Files[ret->getMd5()] = ret;
  }
  return ret;
}
Beispiel #6
0
bool findFileWrapper(const String& file, void* ctx) {
  auto const context = static_cast<ResolveIncludeContext*>(ctx);
  assertx(context->path.isNull());

  Stream::Wrapper* w = Stream::getWrapperFromURI(file);
  if (w && !w->isNormalFileStream()) {
    // Stream wrappers can reenter PHP via user defined callbacks. Roll this
    // operation into a single event
    rqtrace::EventGuard trace{"STREAM_WRAPPER_STAT"};
    rqtrace::DisableTracing disable;

    if (w->stat(file, context->s) == 0) {
      context->path = file;
      return true;
    }
  }

  // handle file://
  if (StringUtil::IsFileUrl(file)) {
    return findFileWrapper(file.substr(7), ctx);
  }

  if (!w) return false;

  auto passW =
    RuntimeOption::RepoAuthoritative ||
    dynamic_cast<FileStreamWrapper*>(w) ||
    !w->isNormalFileStream()
      ? nullptr
      : w;

  // TranslatePath() will canonicalize the path and also check
  // whether the file is in an allowed directory.
  String translatedPath = File::TranslatePathKeepRelative(file);
  if (!FileUtil::isAbsolutePath(file.toCppString())) {
    if (findFile(translatedPath.get(), context->s, context->allow_dir,
                 passW, context->nativeFuncs)) {
      context->path = translatedPath;
      return true;
    }
    return false;
  }
  if (RuntimeOption::SandboxMode || !RuntimeOption::AlwaysUseRelativePath) {
    if (findFile(translatedPath.get(), context->s, context->allow_dir, passW,
                 context->nativeFuncs)) {
      context->path = translatedPath;
      return true;
    }
  }
  std::string server_root(SourceRootInfo::GetCurrentSourceRoot());
  if (server_root.empty()) {
    server_root = std::string(g_context->getCwd().data());
    if (server_root.empty() ||
        FileUtil::isDirSeparator(server_root[server_root.size() - 1])) {
      server_root += FileUtil::getDirSeparator();
    }
  }
  String rel_path(FileUtil::relativePath(server_root, translatedPath.data()));
  if (findFile(rel_path.get(), context->s, context->allow_dir, passW,
               context->nativeFuncs)) {
    context->path = rel_path;
    return true;
  }
  return false;
}