1 // Copyright 2014 The PDFium Authors 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 #ifndef FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_ 8 #define FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_ 9 10 #include <stdint.h> 11 12 #include <functional> 13 #include <optional> 14 15 #include "core/fxcrt/bytestring.h" 16 #include "core/fxcrt/unowned_ptr.h" 17 #include "core/fxcrt/widetext_buffer.h" 18 #include "fxjs/xfa/fxjse.h" 19 #include "v8/include/cppgc/persistent.h" 20 #include "v8/include/v8-forward.h" 21 #include "v8/include/v8-persistent-handle.h" 22 23 class CFXJSE_Context; 24 class CXFA_Document; 25 26 namespace cppgc { 27 class Heap; 28 } // namespace cppgc 29 30 class CFXJSE_FormCalcContext final : public CFXJSE_HostObject { 31 public: 32 CFXJSE_FormCalcContext(v8::Isolate* pIsolate, 33 CFXJSE_Context* pScriptContext, 34 CXFA_Document* pDoc); 35 ~CFXJSE_FormCalcContext() override; 36 37 // CFXJSE_HostObject: 38 CFXJSE_FormCalcContext* AsFormCalcContext() override; 39 40 static void Abs(CFXJSE_HostObject* pThis, 41 const v8::FunctionCallbackInfo<v8::Value>& info); 42 static void Avg(CFXJSE_HostObject* pThis, 43 const v8::FunctionCallbackInfo<v8::Value>& info); 44 static void Ceil(CFXJSE_HostObject* pThis, 45 const v8::FunctionCallbackInfo<v8::Value>& info); 46 static void Count(CFXJSE_HostObject* pThis, 47 const v8::FunctionCallbackInfo<v8::Value>& info); 48 static void Floor(CFXJSE_HostObject* pThis, 49 const v8::FunctionCallbackInfo<v8::Value>& info); 50 static void Max(CFXJSE_HostObject* pThis, 51 const v8::FunctionCallbackInfo<v8::Value>& info); 52 static void Min(CFXJSE_HostObject* pThis, 53 const v8::FunctionCallbackInfo<v8::Value>& info); 54 static void Mod(CFXJSE_HostObject* pThis, 55 const v8::FunctionCallbackInfo<v8::Value>& info); 56 static void Round(CFXJSE_HostObject* pThis, 57 const v8::FunctionCallbackInfo<v8::Value>& info); 58 static void Sum(CFXJSE_HostObject* pThis, 59 const v8::FunctionCallbackInfo<v8::Value>& info); 60 static void Date(CFXJSE_HostObject* pThis, 61 const v8::FunctionCallbackInfo<v8::Value>& info); 62 static void Date2Num(CFXJSE_HostObject* pThis, 63 const v8::FunctionCallbackInfo<v8::Value>& info); 64 static void DateFmt(CFXJSE_HostObject* pThis, 65 const v8::FunctionCallbackInfo<v8::Value>& info); 66 static void IsoDate2Num(CFXJSE_HostObject* pThis, 67 const v8::FunctionCallbackInfo<v8::Value>& info); 68 static void IsoTime2Num(CFXJSE_HostObject* pThis, 69 const v8::FunctionCallbackInfo<v8::Value>& info); 70 static void LocalDateFmt(CFXJSE_HostObject* pThis, 71 const v8::FunctionCallbackInfo<v8::Value>& info); 72 static void LocalTimeFmt(CFXJSE_HostObject* pThis, 73 const v8::FunctionCallbackInfo<v8::Value>& info); 74 static void Num2Date(CFXJSE_HostObject* pThis, 75 const v8::FunctionCallbackInfo<v8::Value>& info); 76 static void Num2GMTime(CFXJSE_HostObject* pThis, 77 const v8::FunctionCallbackInfo<v8::Value>& info); 78 static void Num2Time(CFXJSE_HostObject* pThis, 79 const v8::FunctionCallbackInfo<v8::Value>& info); 80 static void Time(CFXJSE_HostObject* pThis, 81 const v8::FunctionCallbackInfo<v8::Value>& info); 82 static void Time2Num(CFXJSE_HostObject* pThis, 83 const v8::FunctionCallbackInfo<v8::Value>& info); 84 static void TimeFmt(CFXJSE_HostObject* pThis, 85 const v8::FunctionCallbackInfo<v8::Value>& info); 86 87 static ByteString Local2IsoDate(CFXJSE_HostObject* pThis, 88 ByteStringView bsDate, 89 ByteStringView bsFormat, 90 ByteStringView bsLocale); 91 static ByteString IsoDate2Local(CFXJSE_HostObject* pThis, 92 ByteStringView bsDate, 93 ByteStringView bsFormat, 94 ByteStringView bsLocale); 95 static ByteString IsoTime2Local(CFXJSE_HostObject* pThis, 96 ByteStringView bsTime, 97 ByteStringView bsFormat, 98 ByteStringView bsLocale); 99 static ByteString GetLocalDateFormat(CFXJSE_HostObject* pThis, 100 int32_t iStyle, 101 ByteStringView bsLocale, 102 bool bStandard); 103 static ByteString GetLocalTimeFormat(CFXJSE_HostObject* pThis, 104 int32_t iStyle, 105 ByteStringView bsLocale, 106 bool bStandard); 107 static ByteString GetStandardDateFormat(CFXJSE_HostObject* pThis, 108 int32_t iStyle, 109 ByteStringView bsLocale); 110 static ByteString GetStandardTimeFormat(CFXJSE_HostObject* pThis, 111 int32_t iStyle, 112 ByteStringView bsLocale); 113 static ByteString Num2AllTime(CFXJSE_HostObject* pThis, 114 int32_t iTime, 115 ByteStringView bsFormat, 116 ByteStringView bsLocale, 117 bool bGM); 118 119 static void Apr(CFXJSE_HostObject* pThis, 120 const v8::FunctionCallbackInfo<v8::Value>& info); 121 static void CTerm(CFXJSE_HostObject* pThis, 122 const v8::FunctionCallbackInfo<v8::Value>& info); 123 static void FV(CFXJSE_HostObject* pThis, 124 const v8::FunctionCallbackInfo<v8::Value>& info); 125 static void IPmt(CFXJSE_HostObject* pThis, 126 const v8::FunctionCallbackInfo<v8::Value>& info); 127 static void NPV(CFXJSE_HostObject* pThis, 128 const v8::FunctionCallbackInfo<v8::Value>& info); 129 static void Pmt(CFXJSE_HostObject* pThis, 130 const v8::FunctionCallbackInfo<v8::Value>& info); 131 static void PPmt(CFXJSE_HostObject* pThis, 132 const v8::FunctionCallbackInfo<v8::Value>& info); 133 static void PV(CFXJSE_HostObject* pThis, 134 const v8::FunctionCallbackInfo<v8::Value>& info); 135 static void Rate(CFXJSE_HostObject* pThis, 136 const v8::FunctionCallbackInfo<v8::Value>& info); 137 static void Term(CFXJSE_HostObject* pThis, 138 const v8::FunctionCallbackInfo<v8::Value>& info); 139 static void Choose(CFXJSE_HostObject* pThis, 140 const v8::FunctionCallbackInfo<v8::Value>& info); 141 static void Exists(CFXJSE_HostObject* pThis, 142 const v8::FunctionCallbackInfo<v8::Value>& info); 143 static void HasValue(CFXJSE_HostObject* pThis, 144 const v8::FunctionCallbackInfo<v8::Value>& info); 145 static void Oneof(CFXJSE_HostObject* pThis, 146 const v8::FunctionCallbackInfo<v8::Value>& info); 147 static void Within(CFXJSE_HostObject* pThis, 148 const v8::FunctionCallbackInfo<v8::Value>& info); 149 static void If(CFXJSE_HostObject* pThis, 150 const v8::FunctionCallbackInfo<v8::Value>& info); 151 static void Eval(CFXJSE_HostObject* pThis, 152 const v8::FunctionCallbackInfo<v8::Value>& info); 153 static void Ref(CFXJSE_HostObject* pThis, 154 const v8::FunctionCallbackInfo<v8::Value>& info); 155 static void UnitType(CFXJSE_HostObject* pThis, 156 const v8::FunctionCallbackInfo<v8::Value>& info); 157 static void UnitValue(CFXJSE_HostObject* pThis, 158 const v8::FunctionCallbackInfo<v8::Value>& info); 159 160 static void At(CFXJSE_HostObject* pThis, 161 const v8::FunctionCallbackInfo<v8::Value>& info); 162 static void Concat(CFXJSE_HostObject* pThis, 163 const v8::FunctionCallbackInfo<v8::Value>& info); 164 static void Decode(CFXJSE_HostObject* pThis, 165 const v8::FunctionCallbackInfo<v8::Value>& info); 166 static void Encode(CFXJSE_HostObject* pThis, 167 const v8::FunctionCallbackInfo<v8::Value>& info); 168 static void Format(CFXJSE_HostObject* pThis, 169 const v8::FunctionCallbackInfo<v8::Value>& info); 170 static void Left(CFXJSE_HostObject* pThis, 171 const v8::FunctionCallbackInfo<v8::Value>& info); 172 static void Len(CFXJSE_HostObject* pThis, 173 const v8::FunctionCallbackInfo<v8::Value>& info); 174 static void Lower(CFXJSE_HostObject* pThis, 175 const v8::FunctionCallbackInfo<v8::Value>& info); 176 static void Ltrim(CFXJSE_HostObject* pThis, 177 const v8::FunctionCallbackInfo<v8::Value>& info); 178 static void Parse(CFXJSE_HostObject* pThis, 179 const v8::FunctionCallbackInfo<v8::Value>& info); 180 static void Replace(CFXJSE_HostObject* pThis, 181 const v8::FunctionCallbackInfo<v8::Value>& info); 182 static void Right(CFXJSE_HostObject* pThis, 183 const v8::FunctionCallbackInfo<v8::Value>& info); 184 static void Rtrim(CFXJSE_HostObject* pThis, 185 const v8::FunctionCallbackInfo<v8::Value>& info); 186 static void Space(CFXJSE_HostObject* pThis, 187 const v8::FunctionCallbackInfo<v8::Value>& info); 188 static void Str(CFXJSE_HostObject* pThis, 189 const v8::FunctionCallbackInfo<v8::Value>& info); 190 static void Stuff(CFXJSE_HostObject* pThis, 191 const v8::FunctionCallbackInfo<v8::Value>& info); 192 static void Substr(CFXJSE_HostObject* pThis, 193 const v8::FunctionCallbackInfo<v8::Value>& info); 194 static void Uuid(CFXJSE_HostObject* pThis, 195 const v8::FunctionCallbackInfo<v8::Value>& info); 196 static void Upper(CFXJSE_HostObject* pThis, 197 const v8::FunctionCallbackInfo<v8::Value>& info); 198 static void WordNum(CFXJSE_HostObject* pThis, 199 const v8::FunctionCallbackInfo<v8::Value>& info); 200 201 static void Get(CFXJSE_HostObject* pThis, 202 const v8::FunctionCallbackInfo<v8::Value>& info); 203 static void Post(CFXJSE_HostObject* pThis, 204 const v8::FunctionCallbackInfo<v8::Value>& info); 205 static void Put(CFXJSE_HostObject* pThis, 206 const v8::FunctionCallbackInfo<v8::Value>& info); 207 static void assign_value_operator( 208 CFXJSE_HostObject* pThis, 209 const v8::FunctionCallbackInfo<v8::Value>& info); 210 static void logical_or_operator( 211 CFXJSE_HostObject* pThis, 212 const v8::FunctionCallbackInfo<v8::Value>& info); 213 static void logical_and_operator( 214 CFXJSE_HostObject* pThis, 215 const v8::FunctionCallbackInfo<v8::Value>& info); 216 static void equality_operator( 217 CFXJSE_HostObject* pThis, 218 const v8::FunctionCallbackInfo<v8::Value>& info); 219 static void notequality_operator( 220 CFXJSE_HostObject* pThis, 221 const v8::FunctionCallbackInfo<v8::Value>& info); 222 static bool fm_ref_equal(CFXJSE_HostObject* pThis, 223 const v8::FunctionCallbackInfo<v8::Value>& info); 224 static void less_operator(CFXJSE_HostObject* pThis, 225 const v8::FunctionCallbackInfo<v8::Value>& info); 226 static void lessequal_operator( 227 CFXJSE_HostObject* pThis, 228 const v8::FunctionCallbackInfo<v8::Value>& info); 229 static void greater_operator(CFXJSE_HostObject* pThis, 230 const v8::FunctionCallbackInfo<v8::Value>& info); 231 static void greaterequal_operator( 232 CFXJSE_HostObject* pThis, 233 const v8::FunctionCallbackInfo<v8::Value>& info); 234 static void plus_operator(CFXJSE_HostObject* pThis, 235 const v8::FunctionCallbackInfo<v8::Value>& info); 236 static void minus_operator(CFXJSE_HostObject* pThis, 237 const v8::FunctionCallbackInfo<v8::Value>& info); 238 static void multiple_operator( 239 CFXJSE_HostObject* pThis, 240 const v8::FunctionCallbackInfo<v8::Value>& info); 241 static void divide_operator(CFXJSE_HostObject* pThis, 242 const v8::FunctionCallbackInfo<v8::Value>& info); 243 static void positive_operator( 244 CFXJSE_HostObject* pThis, 245 const v8::FunctionCallbackInfo<v8::Value>& info); 246 static void negative_operator( 247 CFXJSE_HostObject* pThis, 248 const v8::FunctionCallbackInfo<v8::Value>& info); 249 static void logical_not_operator( 250 CFXJSE_HostObject* pThis, 251 const v8::FunctionCallbackInfo<v8::Value>& info); 252 static void dot_accessor(CFXJSE_HostObject* pThis, 253 const v8::FunctionCallbackInfo<v8::Value>& info); 254 static void dotdot_accessor(CFXJSE_HostObject* pThis, 255 const v8::FunctionCallbackInfo<v8::Value>& info); 256 static void eval_translation(CFXJSE_HostObject* pThis, 257 const v8::FunctionCallbackInfo<v8::Value>& info); 258 static void is_fm_object(CFXJSE_HostObject* pThis, 259 const v8::FunctionCallbackInfo<v8::Value>& info); 260 static void is_fm_array(CFXJSE_HostObject* pThis, 261 const v8::FunctionCallbackInfo<v8::Value>& info); 262 static void get_fm_value(CFXJSE_HostObject* pThis, 263 const v8::FunctionCallbackInfo<v8::Value>& info); 264 static void get_fm_jsobj(CFXJSE_HostObject* pThis, 265 const v8::FunctionCallbackInfo<v8::Value>& info); 266 static void fm_var_filter(CFXJSE_HostObject* pThis, 267 const v8::FunctionCallbackInfo<v8::Value>& info); 268 static void concat_fm_object(CFXJSE_HostObject* pThis, 269 const v8::FunctionCallbackInfo<v8::Value>& info); 270 271 static std::optional<WideTextBuffer> Translate(cppgc::Heap* pHeap, 272 WideStringView wsFormcalc); 273 274 v8::Local<v8::Value> GlobalPropertyGetter(); GetIsolate()275 v8::Isolate* GetIsolate() const { return m_pIsolate; } GetDocument()276 CXFA_Document* GetDocument() const { return m_pDocument.Get(); } 277 278 private: 279 friend class FormCalcContextTest_GenerateSomExpression_Test; 280 friend class FormCalcContextTest_IsIsoDateFormat_Test; 281 friend class FormCalcContextTest_IsIsoTimeFormat_Test; 282 283 static ByteString GenerateSomExpression(ByteStringView bsName, 284 int32_t iIndexFlags, 285 int32_t iIndexValue, 286 bool bIsStar); 287 288 static void DotAccessorCommon(CFXJSE_HostObject* pThis, 289 const v8::FunctionCallbackInfo<v8::Value>& info, 290 bool bDotAccessor); 291 292 static bool IsIsoDateTimeFormat(ByteStringView bsData, 293 int32_t* pYear, 294 int32_t* pMonth, 295 int32_t* pDay); 296 297 static bool IsIsoDateFormat(ByteStringView bsData, 298 int32_t* pYear, 299 int32_t* pMonth, 300 int32_t* pDay); 301 302 static bool IsIsoTimeFormat(ByteStringView bsData); 303 304 static int32_t DateString2Num(ByteStringView bsDate); 305 306 bool ApplyToExpansion( 307 std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn, 308 const v8::FunctionCallbackInfo<v8::Value>& info, 309 bool bStrict); 310 311 bool ApplyToArray(v8::Isolate* pIsolate, 312 std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn, 313 v8::Local<v8::Array> pArray); 314 315 void ApplyToObject(v8::Isolate* pIsolate, 316 std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn, 317 v8::Local<v8::Object> pObject); 318 319 void ThrowArgumentMismatchException() const; 320 void ThrowNoDefaultPropertyException(ByteStringView name) const; 321 void ThrowCompilerErrorException() const; 322 void ThrowDivideByZeroException() const; 323 void ThrowServerDeniedException() const; 324 void ThrowPropertyNotInObjectException(ByteStringView name, 325 ByteStringView exp) const; 326 void ThrowParamCountMismatchException(ByteStringView method) const; 327 void ThrowException(ByteStringView str) const; 328 329 UnownedPtr<v8::Isolate> const m_pIsolate; 330 v8::Global<v8::Value> m_Value; 331 cppgc::WeakPersistent<CXFA_Document> const m_pDocument; 332 }; 333 334 #endif // FXJS_XFA_CFXJSE_FORMCALC_CONTEXT_H_ 335