[security][CVE-2022-27809] Builtins should always take int64_t, not int
[hiphop-php.git] / hphp / runtime / vm / decl-provider.cpp
blob77c452d8bd20edf1c60f832df033a3f90a20bc40
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/autoload-handler.h"
18 #include "hphp/runtime/base/runtime-option.h"
19 #include "hphp/runtime/vm/decl-provider.h"
21 namespace HPHP {
23 TRACE_SET_MOD(unit_parse);
25 namespace {
27 // Helper to return DeclProviderResult::Missing
28 DeclProviderResult missing() {
29 return DeclProviderResult{DeclProviderResult::Tag::Missing, {}};
32 // Helper to return DeclProviderResult::Decls
33 DeclProviderResult decls(const Decls* decls) {
34 DeclProviderResult r;
35 r.tag = DeclProviderResult::Tag::Decls;
36 r.decl_provider_decls_result._0 = decls;
37 return r;
40 } // namespace {}
42 std::unique_ptr<HhvmDeclProvider>
43 HhvmDeclProvider::create(const RepoOptionsFlags& options) {
44 if (!RuntimeOption::EvalEnableDecl) {
45 return {nullptr};
47 if (!AutoloadHandler::s_instance) {
48 // It is not safe to autoinit AutoloadHandler outside a normal request.
49 return {nullptr};
51 auto map = AutoloadHandler::s_instance->getAutoloadMap();
52 if (!map || !map->isNative()) {
53 // Either compiling systemlib.php with no autoload map initialized yet,
54 // or AutoloadHandler was not configured with a native AutoloadMap.
55 return {nullptr};
58 // Create the DeclProvider.
59 // This will only cache entries it sees during this invocation of
60 // the compiler. Hackc should have a per-session cache indexed by symbol,
61 // and this file-to-decls cache should span sessions.
62 auto decl_flags = options.getDeclFlags();
63 auto aliased_namespaces = options.getAliasedNamespacesConfig();
64 return std::make_unique<HhvmDeclProvider>(
65 decl_flags, aliased_namespaces, map
69 HhvmDeclProvider::HhvmDeclProvider(
70 int32_t flags,
71 std::string const& aliased_namespaces,
72 AutoloadMap* map
74 : m_opts{hackc_create_direct_decl_parse_options(flags, aliased_namespaces)}
75 , m_map{map}
78 // Called by hackc, potentially on a different thread.
79 DeclProviderResult HhvmDeclProvider::getDecl(
80 AutoloadMap::KindOf kind,
81 std::string_view symbol
82 ) {
83 // TODO(T110866581): symbol should be normalized by hackc
84 std::string_view sym(normalizeNS(symbol));
85 ITRACE(3, "DP lookup {}\n", sym);
87 // Lookup the file where sym is defined in the autoload map.
88 auto filename_opt = m_map->getFile(kind, sym);
89 if (filename_opt) {
90 auto filename = filename_opt->native();
91 auto result = m_cache.find(filename);
93 if (result != m_cache.end()) {
94 ITRACE(3, "DP found cached decls for {} in {}\n", sym, filename);
95 return decls(&(*result->second.decls));
98 // Nothing cached: Load file, parse decls.
99 std::ifstream s(filename);
100 std::string text {
101 std::istreambuf_iterator<char>(s), std::istreambuf_iterator<char>()
104 DeclResult decl_result = hackc_direct_decl_parse(*m_opts, filename, text);
105 ITRACE(3, "DP parsed {} in {}\n", sym, filename);
107 // Insert decl_result into the cache, return DeclResult::decls,
108 // a pointer to rust decls in m_cache.
109 auto [it, _] = m_cache.insert({filename, std::move(decl_result)});
110 return decls(&(*it->second.decls));
112 ITRACE(4, "DP {}: getFile() returned None\n", sym);
113 return missing();
116 extern "C" {
118 DeclProviderResult hhvm_decl_provider_get_decl(
119 void* provider, int symbol_kind, char const* symbol, size_t len
121 try {
122 // Unsafe: if `symbol_kind` is out of range the result of this cast is UB.
123 HPHP::AutoloadMap::KindOf kind {
124 static_cast<HPHP::AutoloadMap::KindOf>(symbol_kind)
126 return ((HhvmDeclProvider*)provider)->getDecl(
127 kind, std::string_view(symbol, len)
129 } catch(...) {
130 not_reached();
134 } //extern "C"
135 }//namespace HPHP