Bug Summary

File:platform/mac/avmshell/../../../shell/DomainClass.cpp
Location:line 178, column 45
Description:Access to field 'vtable' results in a dereference of a null pointer (loaded from variable 'container')

Annotated Source Code

1/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3/* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is [Open Source Virtual Machine.].
17 *
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2006
21 * the Initial Developer. All Rights Reserved.
22 *
23 * Contributor(s):
24 * Adobe AS3 Team
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40
41#include "avmshell.h"
42
43#ifndef AVMSHELL_BUILD1
44#error "This file is only for use with avmshell"
45#endif
46
47namespace avmplus
48{
49 using namespace avmshell;
50
51 DomainObject::DomainObject(VTable *vtable, ScriptObject *delegate)
52 : ScriptObject(vtable, delegate)
53 , domainEnv(delegate->core()->codeContext()->domainEnv())
54 , domainToplevel(delegate->toplevel())
55 {
56 }
57
58 void DomainObject::init(DomainObject* parentDomain)
59 {
60 ShellCore* core = (ShellCore*) this->core();
61
62 DomainEnv* baseDomainEnv = parentDomain ?
63 (DomainEnv*)parentDomain->domainEnv :
64 (DomainEnv*)NULL__null;
65 Domain* baseDomain = baseDomainEnv ?
66 baseDomainEnv->domain() :
67 NULL__null;
68
69 domainToplevel = parentDomain ?
70 (Toplevel*)parentDomain->domainToplevel :
71 core->createShellToplevel();
72
73 Domain* domain = Domain::newDomain(core, baseDomain);
74 domainEnv = DomainEnv::newDomainEnv(core, domain, parentDomain ? (DomainEnv*)parentDomain->domainEnv : (DomainEnv*)NULL__null);
75 }
76
77 Atom DomainObject::loadBytes(ByteArrayObject* b, uint32_t swfVersion)
78 {
79 AvmCore* core = this->core();
80 if (!b)
81 toplevel()->throwTypeError(kNullArgumentError, core->toErrorString("bytes"));
82
83 // parse new bytecode
84 size_t len = b->get_length();
85 ScriptBuffer code = core->newScriptBuffer(len);
86 VMPI_memcpy::memcpy(code.getBuffer(), &b->GetByteArray()[0], len);
87
88 Toplevel* toplevel = domainToplevel;
89 ApiVersion apiVersion = core->getApiVersionFromCallStack();
90
91 // parse constants and attributes.
92 PoolObject* pool = core->parseActionBlock(code,
93 /*start*/0,
94 toplevel,
95 domainEnv->domain(),
96 /*ninit*/NULL__null,
97 apiVersion);
98
99
100 // by default, use the same bugCompatibility as the builtins use
101 const BugCompatibility* bugCompatibility = toplevel->abcEnv()->codeContext()->bugCompatibility();
102 if (swfVersion != 0)
103 {
104 // ...unless specified otherwise.
105 for (int j = 0; j < BugCompatibility::VersionCount; ++j)
106 {
107 if (BugCompatibility::kNames[j] == swfVersion)
108 {
109 bugCompatibility = core->createBugCompatibility((BugCompatibility::Version)j);
110 goto done;
111 }
112 }
113 // if we get here, didn't find a valid name
114 toplevel->throwTypeError(kInvalidArgumentError, core->toErrorString("swfVersion"));
115 }
116done:
117
118 ShellCodeContext* codeContext = new (core->GetGC()) ShellCodeContext(domainEnv, bugCompatibility);
119 return core->handleActionPool(pool, toplevel, codeContext);
120 }
121
122 ScriptObject* DomainObject::finddef(const Multiname& multiname,
123 DomainEnv* domainEnv)
124 {
125 Toplevel* toplevel = this->toplevel();
126
127 ScriptEnv* script = core()->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname);
128 if (script == (ScriptEnv*)BIND_AMBIGUOUS)
129 toplevel->throwReferenceError(kAmbiguousBindingError, multiname);
130
131 if (script == (ScriptEnv*)BIND_NONE)
132 toplevel->throwReferenceError(kUndefinedVarError, multiname);
133
134 if (script->global == NULL__null)
135 {
136 script->initGlobal();
137 script->coerceEnter(script->global->atom());
138 }
139
140 return script->global;
141 }
142
143 ClassClosure* DomainObject::getClass(Stringp name)
144 {
145 Toplevel* toplevel = this->toplevel();
146 AvmCore* core = toplevel->core();
147
148 if (name == NULL__null) {
1
Taking false branch
149 toplevel->throwArgumentError(kNullArgumentError, core->toErrorString("name"));
150 }
151
152
153 // Search for a dot from the end.
154 int dot = name->lastIndexOf(core->cachedChars[(int)'.']);
155
156 // If there is a '.', this is a fully-qualified
157 // class name in a package. Must turn it into
158 // a namespace-qualified multiname.
159 Namespace* ns;
160 Stringp className;
161 if (dot >= 0) {
2
Taking false branch
162 Stringp uri = core->internString(name->substring(0, dot));
163 ns = core->internNamespace(core->newNamespace(uri, Namespace::NS_Public, core->getApiVersionFromCallStack()));
164 className = core->internString(name->substring(dot+1, name->length()));
165 } else {
166 ns = core->findPublicNamespace();
167 className = core->internString(name);
168 }
169
170 Multiname multiname(ns, className);
171
172 ScriptObject *container = finddef(multiname, domainEnv);
173 if (!container) {
3
Taking true branch
174 toplevel->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname));
175 }
176 Atom atom = toplevel->getproperty(container->atom(),
177 &multiname,
178 container->vtable);
4
Access to field 'vtable' results in a dereference of a null pointer (loaded from variable 'container')
179
180 // Note: this used to throw "kClassNotFoundError" if the class wasn't
181 // found; now it throws "kCheckTypeFailedError" (by way of coerceToType).
182 // This probably doesn't matter since this is a shell-only class, and it
183 // gives us a testcase for coerceToType.
184 return toplevel->builtinClasses()->get_ClassClass()->coerceToType(atom);
185 }
186
187 DomainClass::DomainClass(VTable *cvtable)
188 : ClassClosure(cvtable)
189 {
190 createVanillaPrototype();
191 }
192
193 DomainObject* DomainClass::get_currentDomain()
194 {
195 return (DomainObject*) newInstance();
196 }
197
198 int DomainClass::get_MIN_DOMAIN_MEMORY_LENGTH()
199 {
200 return DomainEnv::GLOBAL_MEMORY_MIN_SIZE;
201 }
202
203 ByteArrayObject* DomainObject::get_domainMemory() const
204 {
205 return (ByteArrayObject*)domainEnv->get_globalMemory();
206 }
207
208 void DomainObject::set_domainMemory(ByteArrayObject* mem)
209 {
210 if(!domainEnv->set_globalMemory(mem))
211 toplevel()->throwError(kEndOfFileError);
212 }
213}