OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 Google Inc. All rights reserved. | 2 * Copyright (c) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "core/inspector/ScriptArguments.h" | 32 #include "core/inspector/ScriptArguments.h" |
33 | 33 |
34 #include "bindings/core/v8/ScriptValue.h" | 34 #include "bindings/core/v8/ScriptValue.h" |
35 #include "bindings/core/v8/V8Binding.h" | 35 #include "bindings/core/v8/V8Binding.h" |
| 36 #include "wtf/Vector.h" |
| 37 #include "wtf/text/StringBuilder.h" |
36 #include <v8.h> | 38 #include <v8.h> |
37 | 39 |
38 namespace WebCore { | 40 namespace WebCore { |
39 | 41 |
| 42 namespace { |
| 43 |
| 44 static const unsigned maxArrayItemsLimit = 10000; |
| 45 static const unsigned maxStackDepthLimit = 32; |
| 46 |
| 47 class V8ValueStringBuilder { |
| 48 public: |
| 49 static String toString(v8::Handle<v8::Value> value, v8::Isolate* isolate) |
| 50 { |
| 51 V8ValueStringBuilder builder(isolate); |
| 52 if (!builder.append(value)) |
| 53 return String(); |
| 54 return builder.toString(); |
| 55 } |
| 56 |
| 57 private: |
| 58 enum { |
| 59 IgnoreNull = 1 << 0, |
| 60 IgnoreUndefined = 1 << 1, |
| 61 }; |
| 62 |
| 63 V8ValueStringBuilder(v8::Isolate* isolate) |
| 64 : m_arrayLimit(maxArrayItemsLimit) |
| 65 , m_isolate(isolate) |
| 66 { |
| 67 } |
| 68 |
| 69 bool append(v8::Handle<v8::Value> value, unsigned ignoreOptions = 0) |
| 70 { |
| 71 if (value.IsEmpty()) |
| 72 return true; |
| 73 if ((ignoreOptions & IgnoreNull) && value->IsNull()) |
| 74 return true; |
| 75 if ((ignoreOptions & IgnoreUndefined) && value->IsUndefined()) |
| 76 return true; |
| 77 if (value->IsString()) |
| 78 return append(v8::Handle<v8::String>::Cast(value)); |
| 79 if (value->IsStringObject()) |
| 80 return append(v8::Handle<v8::StringObject>::Cast(value)->ValueOf()); |
| 81 if (value->IsSymbol()) |
| 82 return append(v8::Handle<v8::Symbol>::Cast(value)); |
| 83 if (value->IsSymbolObject()) |
| 84 return append(v8::Handle<v8::SymbolObject>::Cast(value)->ValueOf()); |
| 85 if (value->IsNumberObject()) { |
| 86 m_builder.appendNumber(v8::Handle<v8::NumberObject>::Cast(value)->Va
lueOf()); |
| 87 return true; |
| 88 } |
| 89 if (value->IsBooleanObject()) { |
| 90 m_builder.append(v8::Handle<v8::BooleanObject>::Cast(value)->ValueOf
() ? "true" : "false"); |
| 91 return true; |
| 92 } |
| 93 if (value->IsArray()) |
| 94 return append(v8::Handle<v8::Array>::Cast(value)); |
| 95 if (toDOMWindow(value, m_isolate)) { |
| 96 m_builder.append("[object Window]"); |
| 97 return true; |
| 98 } |
| 99 if (value->IsObject() |
| 100 && !value->IsDate() |
| 101 && !value->IsFunction() |
| 102 && !value->IsNativeError() |
| 103 && !value->IsRegExp()) |
| 104 return append(v8::Handle<v8::Object>::Cast(value)->ObjectProtoToStri
ng()); |
| 105 return append(value->ToString()); |
| 106 } |
| 107 |
| 108 bool append(v8::Handle<v8::Array> array) |
| 109 { |
| 110 if (m_visitedArrays.contains(array)) |
| 111 return true; |
| 112 uint32_t length = array->Length(); |
| 113 if (length > m_arrayLimit) |
| 114 return false; |
| 115 if (m_visitedArrays.size() > maxStackDepthLimit) |
| 116 return false; |
| 117 |
| 118 bool result = true; |
| 119 m_arrayLimit -= length; |
| 120 m_visitedArrays.append(array); |
| 121 for (uint32_t i = 0; i < length; ++i) { |
| 122 if (i) |
| 123 m_builder.append(','); |
| 124 if (!append(array->Get(i), IgnoreNull | IgnoreUndefined)) { |
| 125 result = false; |
| 126 break; |
| 127 } |
| 128 } |
| 129 m_visitedArrays.removeLast(); |
| 130 return result; |
| 131 } |
| 132 |
| 133 bool append(v8::Handle<v8::Symbol> symbol) |
| 134 { |
| 135 m_builder.append("Symbol("); |
| 136 bool result = append(symbol->Name(), IgnoreUndefined); |
| 137 m_builder.append(')'); |
| 138 return result; |
| 139 } |
| 140 |
| 141 bool append(v8::Handle<v8::String> string) |
| 142 { |
| 143 if (m_tryCatch.HasCaught()) |
| 144 return false; |
| 145 if (!string.IsEmpty()) |
| 146 m_builder.append(toCoreString(string)); |
| 147 return true; |
| 148 } |
| 149 |
| 150 String toString() |
| 151 { |
| 152 if (m_tryCatch.HasCaught()) |
| 153 return String(); |
| 154 return m_builder.toString(); |
| 155 } |
| 156 |
| 157 uint32_t m_arrayLimit; |
| 158 v8::Isolate* m_isolate; |
| 159 StringBuilder m_builder; |
| 160 Vector<v8::Handle<v8::Array> > m_visitedArrays; |
| 161 v8::TryCatch m_tryCatch; |
| 162 }; |
| 163 |
| 164 } // namespace |
| 165 |
40 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptArguments) | 166 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptArguments) |
41 | 167 |
42 PassRefPtrWillBeRawPtr<ScriptArguments> ScriptArguments::create(ScriptState* scr
iptState, Vector<ScriptValue>& arguments) | 168 PassRefPtrWillBeRawPtr<ScriptArguments> ScriptArguments::create(ScriptState* scr
iptState, Vector<ScriptValue>& arguments) |
43 { | 169 { |
44 return adoptRefWillBeNoop(new ScriptArguments(scriptState, arguments)); | 170 return adoptRefWillBeNoop(new ScriptArguments(scriptState, arguments)); |
45 } | 171 } |
46 | 172 |
47 ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>&
arguments) | 173 ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>&
arguments) |
48 : m_scriptState(scriptState) | 174 : m_scriptState(scriptState) |
49 { | 175 { |
50 m_arguments.swap(arguments); | 176 m_arguments.swap(arguments); |
51 } | 177 } |
52 | 178 |
53 const ScriptValue &ScriptArguments::argumentAt(size_t index) const | 179 const ScriptValue &ScriptArguments::argumentAt(size_t index) const |
54 { | 180 { |
55 ASSERT(m_arguments.size() > index); | 181 ASSERT(m_arguments.size() > index); |
56 return m_arguments[index]; | 182 return m_arguments[index]; |
57 } | 183 } |
58 | 184 |
59 bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNull
OrUndefined) | 185 bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNull
OrUndefined) |
60 { | 186 { |
61 if (!argumentCount()) | 187 if (!argumentCount()) |
62 return false; | 188 return false; |
63 | 189 |
64 const ScriptValue& value = argumentAt(0); | 190 const ScriptValue& value = argumentAt(0); |
65 ScriptState::Scope scope(m_scriptState.get()); | 191 ScriptState::Scope scope(m_scriptState.get()); |
66 if (checkForNullOrUndefined && (value.isNull() || value.isUndefined())) | 192 if (checkForNullOrUndefined && (value.isNull() || value.isUndefined())) |
67 return false; | 193 return false; |
68 | 194 |
69 // We intentionally ignore an exception that can be thrown in ToString(). | 195 result = V8ValueStringBuilder::toString(value.v8Value(), value.isolate()); |
70 v8::TryCatch block; | |
71 v8::Handle<v8::String> string = value.v8Value()->ToString(); | |
72 result = string.IsEmpty() ? String() : toCoreString(string); | |
73 return true; | 196 return true; |
74 } | 197 } |
75 | 198 |
76 } // namespace WebCore | 199 } // namespace WebCore |
OLD | NEW |