Fix use-after-free bug in RPC handler
[hiphop-php.git] / hphp / compiler / expression / expression_list.h
blob8b91f57421ebabe216060bb9d095d526e8ca864f
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 #ifndef incl_HPHP_EXPRESSION_LIST_H_
18 #define incl_HPHP_EXPRESSION_LIST_H_
20 #include "hphp/compiler/expression/array_pair_expression.h"
21 #include "hphp/compiler/expression/expression.h"
22 #include "hphp/runtime/base/type-variant.h"
23 #include <vector>
25 namespace HPHP {
26 ///////////////////////////////////////////////////////////////////////////////
28 DECLARE_BOOST_TYPES(ExpressionList);
30 struct ExpressionList : Expression {
31 enum ListKind {
32 ListKindParam,
33 ListKindComma,
34 ListKindWrapped,
35 ListKindWrappedNoWarn,
36 ListKindLeft
39 explicit ExpressionList(EXPRESSION_CONSTRUCTOR_PARAMETERS,
40 ListKind kind = ListKindParam);
42 DECLARE_EXPRESSION_VIRTUAL_FUNCTIONS;
43 ExpressionPtr preOptimize(AnalysisResultConstPtr ar) override;
45 void setContext(Context context) override;
46 void setListKind(ListKind kind) { m_kind = kind; }
47 ListKind getListKind() const { return m_kind; }
48 void addElement(ExpressionPtr exp) override;
49 void insertElement(ExpressionPtr exp, int index = 0) override;
50 bool isScalar() const override;
51 int getLocalEffects() const override { return NoEffect; }
52 bool isNoObjectInvolved() const;
53 bool containsDynamicConstant(AnalysisResultPtr ar) const override;
54 void removeElement(int index);
55 void clearElements();
56 bool getScalarValue(Variant &value) override;
57 bool isRefable(bool checkError = false) const override;
58 bool kidUnused(int i) const override;
59 ExpressionPtr listValue() const;
60 bool isLiteralString() const override;
61 std::string getLiteralString() const override;
63 bool isScalarArrayPairs() const;
65 int getCount() const { return m_exps.size();}
66 ExpressionPtr &operator[](int index);
68 void getStrings(std::vector<std::string> &strings);
69 void stripConcat();
71 void markParam(int p);
72 void markParams();
74 void setCollectionElems();
75 void setContainsUnpack() { m_argUnpack = true; };
76 bool containsUnpack() const { return m_argUnpack; }
78 /**
79 * Checks whether the expression list contains only literal strings and
80 * (recursive) arrays of literal strings. Also returns the list of strings
81 * if so.
83 bool flattenLiteralStrings(std::vector<ExpressionPtr> &literals) const;
85 template <typename F> bool getListScalars(F) const;
86 private:
87 void optimize(AnalysisResultConstPtr ar);
88 unsigned int checkLitstrKeys() const;
89 enum class ElemsKind: uint8_t { None, ArrayPairs, Collection };
91 private:
92 std::vector<ExpressionPtr> m_exps;
93 ElemsKind m_elems_kind;
94 bool m_argUnpack;
95 ListKind m_kind;
98 template <typename F>
99 inline bool ExpressionList::getListScalars(F f) const {
100 if (m_elems_kind == ElemsKind::None) {
101 for (const auto ape : m_exps) {
102 Variant v;
103 if (!ape->getScalarValue(v)) return false;
104 if (!f(Variant{}, v)) return false;
106 return true;
108 if (!isScalarArrayPairs()) return false;
109 for (const auto ape : m_exps) {
110 auto exp = dynamic_pointer_cast<ArrayPairExpression>(ape);
111 if (!exp) return false;
112 auto name = exp->getName();
113 auto val = exp->getValue();
114 if (!name) {
115 Variant v;
116 bool ret = val->getScalarValue(v);
117 if (!ret) assert(false);
118 if (!f(Variant{}, v)) return false;
119 } else {
120 Variant n;
121 Variant v;
122 bool ret1 = name->getScalarValue(n);
123 bool ret2 = val->getScalarValue(v);
124 if (!(ret1 && ret2)) return false;
125 if (!f(n, v)) return false;
128 return true;
131 ///////////////////////////////////////////////////////////////////////////////
133 #endif // incl_HPHP_EXPRESSION_LIST_H_