1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
8 #include "js/Wrapper.h"
9 #include "vm/WellKnownAtom.h"  // js_*_str
10 
11 #include "vm/JSObject-inl.h"
12 
13 using namespace js;
14 
getOwnPropertyDescriptor(JSContext * cx,HandleObject wrapper,HandleId id,MutableHandle<mozilla::Maybe<PropertyDescriptor>> desc) const15 bool OpaqueCrossCompartmentWrapper::getOwnPropertyDescriptor(
16     JSContext* cx, HandleObject wrapper, HandleId id,
17     MutableHandle<mozilla::Maybe<PropertyDescriptor>> desc) const {
18   desc.reset();
19   return true;
20 }
21 
defineProperty(JSContext * cx,HandleObject wrapper,HandleId id,Handle<PropertyDescriptor> desc,ObjectOpResult & result) const22 bool OpaqueCrossCompartmentWrapper::defineProperty(
23     JSContext* cx, HandleObject wrapper, HandleId id,
24     Handle<PropertyDescriptor> desc, ObjectOpResult& result) const {
25   return result.succeed();
26 }
27 
ownPropertyKeys(JSContext * cx,HandleObject wrapper,MutableHandleIdVector props) const28 bool OpaqueCrossCompartmentWrapper::ownPropertyKeys(
29     JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const {
30   return true;
31 }
32 
delete_(JSContext * cx,HandleObject wrapper,HandleId id,ObjectOpResult & result) const33 bool OpaqueCrossCompartmentWrapper::delete_(JSContext* cx, HandleObject wrapper,
34                                             HandleId id,
35                                             ObjectOpResult& result) const {
36   return result.succeed();
37 }
38 
enumerate(JSContext * cx,HandleObject proxy,MutableHandleIdVector props) const39 bool OpaqueCrossCompartmentWrapper::enumerate(
40     JSContext* cx, HandleObject proxy, MutableHandleIdVector props) const {
41   return BaseProxyHandler::enumerate(cx, proxy, props);
42 }
43 
getPrototype(JSContext * cx,HandleObject proxy,MutableHandleObject protop) const44 bool OpaqueCrossCompartmentWrapper::getPrototype(
45     JSContext* cx, HandleObject proxy, MutableHandleObject protop) const {
46   protop.set(nullptr);
47   return true;
48 }
49 
setPrototype(JSContext * cx,HandleObject proxy,HandleObject proto,ObjectOpResult & result) const50 bool OpaqueCrossCompartmentWrapper::setPrototype(JSContext* cx,
51                                                  HandleObject proxy,
52                                                  HandleObject proto,
53                                                  ObjectOpResult& result) const {
54   return result.succeed();
55 }
56 
getPrototypeIfOrdinary(JSContext * cx,HandleObject proxy,bool * isOrdinary,MutableHandleObject protop) const57 bool OpaqueCrossCompartmentWrapper::getPrototypeIfOrdinary(
58     JSContext* cx, HandleObject proxy, bool* isOrdinary,
59     MutableHandleObject protop) const {
60   *isOrdinary = false;
61   return true;
62 }
63 
setImmutablePrototype(JSContext * cx,HandleObject proxy,bool * succeeded) const64 bool OpaqueCrossCompartmentWrapper::setImmutablePrototype(
65     JSContext* cx, HandleObject proxy, bool* succeeded) const {
66   *succeeded = false;
67   return true;
68 }
69 
preventExtensions(JSContext * cx,HandleObject wrapper,ObjectOpResult & result) const70 bool OpaqueCrossCompartmentWrapper::preventExtensions(
71     JSContext* cx, HandleObject wrapper, ObjectOpResult& result) const {
72   return result.failCantPreventExtensions();
73 }
74 
isExtensible(JSContext * cx,HandleObject wrapper,bool * extensible) const75 bool OpaqueCrossCompartmentWrapper::isExtensible(JSContext* cx,
76                                                  HandleObject wrapper,
77                                                  bool* extensible) const {
78   *extensible = true;
79   return true;
80 }
81 
has(JSContext * cx,HandleObject wrapper,HandleId id,bool * bp) const82 bool OpaqueCrossCompartmentWrapper::has(JSContext* cx, HandleObject wrapper,
83                                         HandleId id, bool* bp) const {
84   return BaseProxyHandler::has(cx, wrapper, id, bp);
85 }
86 
get(JSContext * cx,HandleObject wrapper,HandleValue receiver,HandleId id,MutableHandleValue vp) const87 bool OpaqueCrossCompartmentWrapper::get(JSContext* cx, HandleObject wrapper,
88                                         HandleValue receiver, HandleId id,
89                                         MutableHandleValue vp) const {
90   return BaseProxyHandler::get(cx, wrapper, receiver, id, vp);
91 }
92 
set(JSContext * cx,HandleObject wrapper,HandleId id,HandleValue v,HandleValue receiver,ObjectOpResult & result) const93 bool OpaqueCrossCompartmentWrapper::set(JSContext* cx, HandleObject wrapper,
94                                         HandleId id, HandleValue v,
95                                         HandleValue receiver,
96                                         ObjectOpResult& result) const {
97   return BaseProxyHandler::set(cx, wrapper, id, v, receiver, result);
98 }
99 
call(JSContext * cx,HandleObject wrapper,const CallArgs & args) const100 bool OpaqueCrossCompartmentWrapper::call(JSContext* cx, HandleObject wrapper,
101                                          const CallArgs& args) const {
102   RootedValue v(cx, ObjectValue(*wrapper));
103   ReportIsNotFunction(cx, v);
104   return false;
105 }
106 
construct(JSContext * cx,HandleObject wrapper,const CallArgs & args) const107 bool OpaqueCrossCompartmentWrapper::construct(JSContext* cx,
108                                               HandleObject wrapper,
109                                               const CallArgs& args) const {
110   RootedValue v(cx, ObjectValue(*wrapper));
111   ReportIsNotFunction(cx, v);
112   return false;
113 }
114 
hasOwn(JSContext * cx,HandleObject wrapper,HandleId id,bool * bp) const115 bool OpaqueCrossCompartmentWrapper::hasOwn(JSContext* cx, HandleObject wrapper,
116                                            HandleId id, bool* bp) const {
117   return BaseProxyHandler::hasOwn(cx, wrapper, id, bp);
118 }
119 
getOwnEnumerablePropertyKeys(JSContext * cx,HandleObject wrapper,MutableHandleIdVector props) const120 bool OpaqueCrossCompartmentWrapper::getOwnEnumerablePropertyKeys(
121     JSContext* cx, HandleObject wrapper, MutableHandleIdVector props) const {
122   return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, wrapper, props);
123 }
124 
getBuiltinClass(JSContext * cx,HandleObject wrapper,ESClass * cls) const125 bool OpaqueCrossCompartmentWrapper::getBuiltinClass(JSContext* cx,
126                                                     HandleObject wrapper,
127                                                     ESClass* cls) const {
128   *cls = ESClass::Other;
129   return true;
130 }
131 
isArray(JSContext * cx,HandleObject obj,JS::IsArrayAnswer * answer) const132 bool OpaqueCrossCompartmentWrapper::isArray(JSContext* cx, HandleObject obj,
133                                             JS::IsArrayAnswer* answer) const {
134   *answer = JS::IsArrayAnswer::NotArray;
135   return true;
136 }
137 
hasInstance(JSContext * cx,HandleObject wrapper,MutableHandleValue v,bool * bp) const138 bool OpaqueCrossCompartmentWrapper::hasInstance(JSContext* cx,
139                                                 HandleObject wrapper,
140                                                 MutableHandleValue v,
141                                                 bool* bp) const {
142   *bp = false;
143   return true;
144 }
145 
className(JSContext * cx,HandleObject proxy) const146 const char* OpaqueCrossCompartmentWrapper::className(JSContext* cx,
147                                                      HandleObject proxy) const {
148   return "Opaque";
149 }
150 
fun_toString(JSContext * cx,HandleObject proxy,bool isToSource) const151 JSString* OpaqueCrossCompartmentWrapper::fun_toString(JSContext* cx,
152                                                       HandleObject proxy,
153                                                       bool isToSource) const {
154   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
155                             JSMSG_INCOMPATIBLE_PROTO, js_Function_str,
156                             js_toString_str, "object");
157   return nullptr;
158 }
159 
160 const OpaqueCrossCompartmentWrapper OpaqueCrossCompartmentWrapper::singleton;
161