• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "fxjs/cfx_v8.h"
8 
9 #include "core/fxcrt/fx_memory.h"
10 #include "third_party/base/allocator/partition_allocator/partition_alloc.h"
11 
CFX_V8(v8::Isolate * isolate)12 CFX_V8::CFX_V8(v8::Isolate* isolate) : m_pIsolate(isolate) {}
13 
14 CFX_V8::~CFX_V8() = default;
15 
GetObjectProperty(v8::Local<v8::Object> pObj,ByteStringView bsUTF8PropertyName)16 v8::Local<v8::Value> CFX_V8::GetObjectProperty(
17     v8::Local<v8::Object> pObj,
18     ByteStringView bsUTF8PropertyName) {
19   if (pObj.IsEmpty())
20     return v8::Local<v8::Value>();
21   v8::Local<v8::Value> val;
22   if (!pObj->Get(m_pIsolate->GetCurrentContext(), NewString(bsUTF8PropertyName))
23            .ToLocal(&val))
24     return v8::Local<v8::Value>();
25   return val;
26 }
27 
GetObjectPropertyNames(v8::Local<v8::Object> pObj)28 std::vector<WideString> CFX_V8::GetObjectPropertyNames(
29     v8::Local<v8::Object> pObj) {
30   if (pObj.IsEmpty())
31     return std::vector<WideString>();
32 
33   v8::Local<v8::Array> val;
34   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
35   if (!pObj->GetPropertyNames(context).ToLocal(&val))
36     return std::vector<WideString>();
37 
38   std::vector<WideString> result;
39   for (uint32_t i = 0; i < val->Length(); ++i) {
40     result.push_back(ToWideString(val->Get(context, i).ToLocalChecked()));
41   }
42 
43   return result;
44 }
45 
PutObjectProperty(v8::Local<v8::Object> pObj,ByteStringView bsUTF8PropertyName,v8::Local<v8::Value> pPut)46 bool CFX_V8::PutObjectProperty(v8::Local<v8::Object> pObj,
47                                ByteStringView bsUTF8PropertyName,
48                                v8::Local<v8::Value> pPut) {
49   ASSERT(!pPut.IsEmpty());
50   if (pObj.IsEmpty())
51     return false;
52 
53   v8::Local<v8::String> name = NewString(bsUTF8PropertyName);
54   return pObj->Set(m_pIsolate->GetCurrentContext(), name, pPut).IsJust();
55 }
56 
DisposeIsolate()57 void CFX_V8::DisposeIsolate() {
58   if (m_pIsolate)
59     m_pIsolate.Release()->Dispose();
60 }
61 
NewArray()62 v8::Local<v8::Array> CFX_V8::NewArray() {
63   return v8::Array::New(GetIsolate());
64 }
65 
NewObject()66 v8::Local<v8::Object> CFX_V8::NewObject() {
67   return v8::Object::New(GetIsolate());
68 }
69 
PutArrayElement(v8::Local<v8::Array> pArray,unsigned index,v8::Local<v8::Value> pValue)70 bool CFX_V8::PutArrayElement(v8::Local<v8::Array> pArray,
71                              unsigned index,
72                              v8::Local<v8::Value> pValue) {
73   ASSERT(!pValue.IsEmpty());
74   if (pArray.IsEmpty())
75     return false;
76   return pArray->Set(m_pIsolate->GetCurrentContext(), index, pValue).IsJust();
77 }
78 
GetArrayElement(v8::Local<v8::Array> pArray,unsigned index)79 v8::Local<v8::Value> CFX_V8::GetArrayElement(v8::Local<v8::Array> pArray,
80                                              unsigned index) {
81   if (pArray.IsEmpty())
82     return v8::Local<v8::Value>();
83   v8::Local<v8::Value> val;
84   if (!pArray->Get(m_pIsolate->GetCurrentContext(), index).ToLocal(&val))
85     return v8::Local<v8::Value>();
86   return val;
87 }
88 
GetArrayLength(v8::Local<v8::Array> pArray)89 unsigned CFX_V8::GetArrayLength(v8::Local<v8::Array> pArray) {
90   if (pArray.IsEmpty())
91     return 0;
92   return pArray->Length();
93 }
94 
NewNumber(int number)95 v8::Local<v8::Number> CFX_V8::NewNumber(int number) {
96   return v8::Int32::New(GetIsolate(), number);
97 }
98 
NewNumber(double number)99 v8::Local<v8::Number> CFX_V8::NewNumber(double number) {
100   return v8::Number::New(GetIsolate(), number);
101 }
102 
NewNumber(float number)103 v8::Local<v8::Number> CFX_V8::NewNumber(float number) {
104   return v8::Number::New(GetIsolate(), number);
105 }
106 
NewBoolean(bool b)107 v8::Local<v8::Boolean> CFX_V8::NewBoolean(bool b) {
108   return v8::Boolean::New(GetIsolate(), b);
109 }
110 
NewString(ByteStringView str)111 v8::Local<v8::String> CFX_V8::NewString(ByteStringView str) {
112   v8::Isolate* pIsolate = m_pIsolate ? GetIsolate() : v8::Isolate::GetCurrent();
113   return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(),
114                                  v8::NewStringType::kNormal, str.GetLength())
115       .ToLocalChecked();
116 }
117 
NewString(WideStringView str)118 v8::Local<v8::String> CFX_V8::NewString(WideStringView str) {
119   // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t
120   // wide-strings isn't handled by v8, so use UTF8 as a common
121   // intermediate format.
122   return NewString(FX_UTF8Encode(str).AsStringView());
123 }
124 
NewNull()125 v8::Local<v8::Value> CFX_V8::NewNull() {
126   return v8::Null(GetIsolate());
127 }
128 
NewUndefined()129 v8::Local<v8::Value> CFX_V8::NewUndefined() {
130   return v8::Undefined(GetIsolate());
131 }
132 
NewDate(double d)133 v8::Local<v8::Date> CFX_V8::NewDate(double d) {
134   return v8::Date::New(m_pIsolate->GetCurrentContext(), d)
135       .ToLocalChecked()
136       .As<v8::Date>();
137 }
138 
ToInt32(v8::Local<v8::Value> pValue)139 int CFX_V8::ToInt32(v8::Local<v8::Value> pValue) {
140   if (pValue.IsEmpty())
141     return 0;
142   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
143   v8::MaybeLocal<v8::Int32> maybe_int32 = pValue->ToInt32(context);
144   if (maybe_int32.IsEmpty())
145     return 0;
146   return maybe_int32.ToLocalChecked()->Value();
147 }
148 
ToBoolean(v8::Local<v8::Value> pValue)149 bool CFX_V8::ToBoolean(v8::Local<v8::Value> pValue) {
150   if (pValue.IsEmpty())
151     return false;
152   return pValue->BooleanValue(m_pIsolate.Get());
153 }
154 
ToDouble(v8::Local<v8::Value> pValue)155 double CFX_V8::ToDouble(v8::Local<v8::Value> pValue) {
156   if (pValue.IsEmpty())
157     return 0.0;
158   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
159   v8::MaybeLocal<v8::Number> maybe_number = pValue->ToNumber(context);
160   if (maybe_number.IsEmpty())
161     return 0.0;
162   return maybe_number.ToLocalChecked()->Value();
163 }
164 
ToWideString(v8::Local<v8::Value> pValue)165 WideString CFX_V8::ToWideString(v8::Local<v8::Value> pValue) {
166   if (pValue.IsEmpty())
167     return WideString();
168   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
169   v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
170   if (maybe_string.IsEmpty())
171     return WideString();
172   v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
173   return WideString::FromUTF8(ByteStringView(*s, s.length()));
174 }
175 
ToByteString(v8::Local<v8::Value> pValue)176 ByteString CFX_V8::ToByteString(v8::Local<v8::Value> pValue) {
177   if (pValue.IsEmpty())
178     return ByteString();
179   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
180   v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
181   if (maybe_string.IsEmpty())
182     return ByteString();
183   v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
184   return ByteString(*s);
185 }
186 
ToObject(v8::Local<v8::Value> pValue)187 v8::Local<v8::Object> CFX_V8::ToObject(v8::Local<v8::Value> pValue) {
188   if (pValue.IsEmpty() || !pValue->IsObject())
189     return v8::Local<v8::Object>();
190   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
191   return pValue->ToObject(context).ToLocalChecked();
192 }
193 
ToArray(v8::Local<v8::Value> pValue)194 v8::Local<v8::Array> CFX_V8::ToArray(v8::Local<v8::Value> pValue) {
195   if (pValue.IsEmpty() || !pValue->IsArray())
196     return v8::Local<v8::Array>();
197   v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
198   return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
199 }
200 
Allocate(size_t length)201 void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
202   if (length > kMaxAllowedBytes)
203     return nullptr;
204   return GetArrayBufferPartitionAllocator().root()->AllocFlags(
205       pdfium::base::PartitionAllocZeroFill, length, "CFX_V8ArrayBuffer");
206 }
207 
AllocateUninitialized(size_t length)208 void* CFX_V8ArrayBufferAllocator::AllocateUninitialized(size_t length) {
209   if (length > kMaxAllowedBytes)
210     return nullptr;
211   return GetArrayBufferPartitionAllocator().root()->Alloc(length,
212                                                           "CFX_V8ArrayBuffer");
213 }
214 
Free(void * data,size_t length)215 void CFX_V8ArrayBufferAllocator::Free(void* data, size_t length) {
216   GetArrayBufferPartitionAllocator().root()->Free(data);
217 }
218