wintrust: Use helper function for setting confidence in SoftpubCheckCert.
[wine] / dlls / jscript / global.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 static const WCHAR NaNW[] = {'N','a','N',0};
27 static const WCHAR InfinityW[] = {'I','n','f','i','n','i','t','y',0};
28 static const WCHAR ArrayW[] = {'A','r','r','a','y',0};
29 static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0};
30 static const WCHAR DateW[] = {'D','a','t','e',0};
31 static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
32 static const WCHAR NumberW[] = {'N','u','m','b','e','r',0};
33 static const WCHAR ObjectW[] = {'O','b','j','e','c','t',0};
34 static const WCHAR StringW[] = {'S','t','r','i','n','g',0};
35 static const WCHAR RegExpW[] = {'R','e','g','E','x','p',0};
36 static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0};
37 static const WCHAR VBArrayW[] = {'V','B','A','r','r','a','y',0};
38 static const WCHAR EnumeratorW[] = {'E','n','u','m','e','r','a','t','o','r',0};
39 static const WCHAR escapeW[] = {'e','s','c','a','p','e',0};
40 static const WCHAR evalW[] = {'e','v','a','l',0};
41 static const WCHAR isNaNW[] = {'i','s','N','a','N',0};
42 static const WCHAR isFiniteW[] = {'i','s','F','i','n','i','t','e',0};
43 static const WCHAR parseIntW[] = {'p','a','r','s','e','I','n','t',0};
44 static const WCHAR parseFloatW[] = {'p','a','r','s','e','F','l','o','a','t',0};
45 static const WCHAR unescapeW[] = {'u','n','e','s','c','a','p','e',0};
46 static const WCHAR GetObjectW[] = {'G','e','t','O','b','j','e','c','t',0};
47 static const WCHAR ScriptEngineW[] = {'S','c','r','i','p','t','E','n','g','i','n','e',0};
48 static const WCHAR ScriptEngineMajorVersionW[] =
49     {'S','c','r','i','p','t','E','n','g','i','n','e','M','a','j','o','r','V','e','r','s','i','o','n',0};
50 static const WCHAR ScriptEngineMinorVersionW[] =
51     {'S','c','r','i','p','t','E','n','g','i','n','e','M','i','n','o','r','V','e','r','s','i','o','n',0};
52 static const WCHAR ScriptEngineBuildVersionW[] =
53     {'S','c','r','i','p','t','E','n','g','i','n','e','B','u','i','l','d','V','e','r','s','i','o','n',0};
54 static const WCHAR CollectGarbageW[] = {'C','o','l','l','e','c','t','G','a','r','b','a','g','e',0};
55 static const WCHAR MathW[] = {'M','a','t','h',0};
56
57 static HRESULT constructor_call(DispatchEx *constr, LCID lcid, WORD flags, DISPPARAMS *dp,
58         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
59 {
60     if(flags != DISPATCH_PROPERTYGET)
61         return jsdisp_call_value(constr, lcid, flags, dp, retv, ei, sp);
62
63     V_VT(retv) = VT_DISPATCH;
64     V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(constr);
65     IDispatchEx_AddRef(_IDispatchEx_(constr));
66     return S_OK;
67 }
68
69 static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
70         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
71 {
72     FIXME("\n");
73     return E_NOTIMPL;
74 }
75
76 static HRESULT JSGlobal_Infinity(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
77         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
78 {
79     FIXME("\n");
80     return E_NOTIMPL;
81 }
82
83 static HRESULT JSGlobal_Array(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
84         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
85 {
86     TRACE("\n");
87
88     return constructor_call(dispex->ctx->array_constr, lcid, flags, dp, retv, ei, sp);
89 }
90
91 static HRESULT JSGlobal_Boolean(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
92         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
93 {
94     TRACE("\n");
95
96     return constructor_call(dispex->ctx->bool_constr, lcid, flags, dp, retv, ei, sp);
97 }
98
99 static HRESULT JSGlobal_Date(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
100         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
101 {
102     FIXME("\n");
103     return E_NOTIMPL;
104 }
105
106 static HRESULT JSGlobal_Function(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
107         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
108 {
109     TRACE("\n");
110
111     return constructor_call(dispex->ctx->function_constr, lcid, flags, dp, retv, ei, sp);
112 }
113
114 static HRESULT JSGlobal_Number(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
115         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
116 {
117     TRACE("\n");
118
119     return constructor_call(dispex->ctx->number_constr, lcid, flags, dp, retv, ei, sp);
120 }
121
122 static HRESULT JSGlobal_Object(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
123         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
124 {
125     TRACE("\n");
126
127     return constructor_call(dispex->ctx->object_constr, lcid, flags, dp, retv, ei, sp);
128 }
129
130 static HRESULT JSGlobal_String(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
131         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
132 {
133     TRACE("\n");
134
135     return constructor_call(dispex->ctx->string_constr, lcid, flags, dp, retv, ei, sp);
136 }
137
138 static HRESULT JSGlobal_RegExp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
139         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
140 {
141     TRACE("\n");
142
143     return constructor_call(dispex->ctx->regexp_constr, lcid, flags, dp, retv, ei, sp);
144 }
145
146 static HRESULT JSGlobal_ActiveXObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
147         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
148 {
149     FIXME("\n");
150     return E_NOTIMPL;
151 }
152
153 static HRESULT JSGlobal_VBArray(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
154         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
155 {
156     FIXME("\n");
157     return E_NOTIMPL;
158 }
159
160 static HRESULT JSGlobal_Enumerator(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
161         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
162 {
163     FIXME("\n");
164     return E_NOTIMPL;
165 }
166
167 static HRESULT JSGlobal_escape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
168         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
169 {
170     FIXME("\n");
171     return E_NOTIMPL;
172 }
173
174 /* ECMA-262 3rd Edition    15.1.2.1 */
175 static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
176         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
177 {
178     parser_ctx_t *parser_ctx;
179     VARIANT *arg;
180     HRESULT hres;
181
182     TRACE("\n");
183
184     if(!arg_cnt(dp)) {
185         if(retv)
186             V_VT(retv) = VT_EMPTY;
187         return S_OK;
188     }
189
190     arg = get_arg(dp, 0);
191     if(V_VT(arg) != VT_BSTR) {
192         if(retv) {
193             V_VT(retv) = VT_EMPTY;
194             return VariantCopy(retv, arg);
195         }
196         return S_OK;
197     }
198
199     if(!dispex->ctx->exec_ctx) {
200         FIXME("No active exec_ctx\n");
201         return E_UNEXPECTED;
202     }
203
204     TRACE("parsing %s\n", debugstr_w(V_BSTR(arg)));
205     hres = script_parse(dispex->ctx, V_BSTR(arg), &parser_ctx);
206     if(FAILED(hres)) {
207         FIXME("parse failed: %08x\n", hres);
208         return hres;
209     }
210
211     hres = exec_source(dispex->ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv);
212     parser_release(parser_ctx);
213
214     return hres;
215 }
216
217 static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
218         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
219 {
220     FIXME("\n");
221     return E_NOTIMPL;
222 }
223
224 static HRESULT JSGlobal_isFinite(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
225         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
226 {
227     FIXME("\n");
228     return E_NOTIMPL;
229 }
230
231 static INT char_to_int(WCHAR c)
232 {
233     if('0' <= c && c <= '9')
234         return c - '0';
235     if('a' <= c && c <= 'z')
236         return c - 'a' + 10;
237     if('A' <= c && c <= 'Z')
238         return c - 'A' + 10;
239     return 100;
240 }
241
242 static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
243         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
244 {
245     DOUBLE ret = 0.0;
246     INT radix=10, i;
247     WCHAR *ptr;
248     BOOL neg = FALSE;
249     BSTR str;
250     HRESULT hres;
251
252     if(!arg_cnt(dp)) {
253         FIXME("NAN\n");
254         return E_NOTIMPL;
255     }
256
257     if(arg_cnt(dp) >= 2) {
258         hres = to_int32(dispex->ctx, get_arg(dp, 1), ei, &radix);
259         if(FAILED(hres))
260             return hres;
261
262         if(!radix) {
263             radix = 10;
264         }else if(radix < 2 || radix > 36) {
265             WARN("radix %d out of range\n", radix);
266             return E_FAIL;
267         }
268     }
269
270     hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &str);
271     if(FAILED(hres))
272         return hres;
273
274     for(ptr = str; isspaceW(*ptr); ptr++);
275
276     switch(*ptr) {
277     case '+':
278         ptr++;
279         break;
280     case '-':
281         neg = TRUE;
282         ptr++;
283         break;
284     case '0':
285         ptr++;
286         if(*ptr == 'x' || *ptr == 'X') {
287             radix = 16;
288             ptr++;
289         }
290     }
291
292     while(*ptr) {
293         i = char_to_int(*ptr++);
294         if(i > radix)
295             break;
296
297         ret = ret*radix + i;
298     }
299
300     SysFreeString(str);
301
302     if(neg)
303         ret = -ret;
304
305     if(retv)
306         num_set_val(retv, ret);
307     return S_OK;
308 }
309
310 static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
311         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
312 {
313     FIXME("\n");
314     return E_NOTIMPL;
315 }
316
317 static HRESULT JSGlobal_unescape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
318         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
319 {
320     FIXME("\n");
321     return E_NOTIMPL;
322 }
323
324 static HRESULT JSGlobal_GetObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
325         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
326 {
327     FIXME("\n");
328     return E_NOTIMPL;
329 }
330
331 static HRESULT JSGlobal_ScriptEngine(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
332         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
333 {
334     FIXME("\n");
335     return E_NOTIMPL;
336 }
337
338 static HRESULT JSGlobal_ScriptEngineMajorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
339         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
340 {
341     FIXME("\n");
342     return E_NOTIMPL;
343 }
344
345 static HRESULT JSGlobal_ScriptEngineMinorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
346         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
347 {
348     FIXME("\n");
349     return E_NOTIMPL;
350 }
351
352 static HRESULT JSGlobal_ScriptEngineBuildVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
353         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
354 {
355     FIXME("\n");
356     return E_NOTIMPL;
357 }
358
359 static HRESULT JSGlobal_CollectGarbage(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
360         VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
361 {
362     FIXME("\n");
363     return E_NOTIMPL;
364 }
365
366 static const builtin_prop_t JSGlobal_props[] = {
367     {ActiveXObjectW,             JSGlobal_ActiveXObject,             PROPF_METHOD},
368     {ArrayW,                     JSGlobal_Array,                     PROPF_CONSTR},
369     {BooleanW,                   JSGlobal_Boolean,                   PROPF_CONSTR},
370     {CollectGarbageW,            JSGlobal_CollectGarbage,            PROPF_METHOD},
371     {DateW,                      JSGlobal_Date,                      PROPF_CONSTR},
372     {EnumeratorW,                JSGlobal_Enumerator,                PROPF_METHOD},
373     {FunctionW,                  JSGlobal_Function,                  PROPF_CONSTR},
374     {GetObjectW,                 JSGlobal_GetObject,                 PROPF_METHOD},
375     {InfinityW,                  JSGlobal_Infinity,                  0},
376 /*  {MathW,                      JSGlobal_Math,                      0},  */
377     {NaNW,                       JSGlobal_NaN,                       0},
378     {NumberW,                    JSGlobal_Number,                    PROPF_CONSTR},
379     {ObjectW,                    JSGlobal_Object,                    PROPF_CONSTR},
380     {RegExpW,                    JSGlobal_RegExp,                    PROPF_CONSTR},
381     {ScriptEngineW,              JSGlobal_ScriptEngine,              PROPF_METHOD},
382     {ScriptEngineBuildVersionW,  JSGlobal_ScriptEngineBuildVersion,  PROPF_METHOD},
383     {ScriptEngineMajorVersionW,  JSGlobal_ScriptEngineMajorVersion,  PROPF_METHOD},
384     {ScriptEngineMinorVersionW,  JSGlobal_ScriptEngineMinorVersion,  PROPF_METHOD},
385     {StringW,                    JSGlobal_String,                    PROPF_CONSTR},
386     {VBArrayW,                   JSGlobal_VBArray,                   PROPF_METHOD},
387     {escapeW,                    JSGlobal_escape,                    PROPF_METHOD},
388     {evalW,                      JSGlobal_eval,                      PROPF_METHOD|1},
389     {isFiniteW,                  JSGlobal_isFinite,                  PROPF_METHOD},
390     {isNaNW,                     JSGlobal_isNaN,                     PROPF_METHOD},
391     {parseFloatW,                JSGlobal_parseFloat,                PROPF_METHOD},
392     {parseIntW,                  JSGlobal_parseInt,                  PROPF_METHOD|2},
393     {unescapeW,                  JSGlobal_unescape,                  PROPF_METHOD}
394 };
395
396 static const builtin_info_t JSGlobal_info = {
397     JSCLASS_GLOBAL,
398     {NULL, NULL, 0},
399     sizeof(JSGlobal_props)/sizeof(*JSGlobal_props),
400     JSGlobal_props,
401     NULL,
402     NULL
403 };
404
405 static HRESULT init_constructors(script_ctx_t *ctx)
406 {
407     HRESULT hres;
408
409     hres = init_function_constr(ctx);
410     if(FAILED(hres))
411         return hres;
412
413     hres = create_array_constr(ctx, &ctx->array_constr);
414     if(FAILED(hres))
415         return hres;
416
417     hres = create_bool_constr(ctx, &ctx->bool_constr);
418     if(FAILED(hres))
419         return hres;
420
421     hres = create_number_constr(ctx, &ctx->number_constr);
422     if(FAILED(hres))
423         return hres;
424
425     hres = create_object_constr(ctx, &ctx->object_constr);
426     if(FAILED(hres))
427         return hres;
428
429     hres = create_regexp_constr(ctx, &ctx->regexp_constr);
430     if(FAILED(hres))
431         return hres;
432
433     hres = create_string_constr(ctx, &ctx->string_constr);
434     if(FAILED(hres))
435         return hres;
436
437     return S_OK;
438 }
439
440 HRESULT init_global(script_ctx_t *ctx)
441 {
442     DispatchEx *math;
443     VARIANT var;
444     HRESULT hres;
445
446     if(ctx->global)
447         return S_OK;
448
449     hres = init_constructors(ctx);
450     if(FAILED(hres))
451         return hres;
452
453     hres = create_dispex(ctx, &JSGlobal_info, NULL, &ctx->global);
454     if(FAILED(hres))
455         return hres;
456
457     hres = create_math(ctx, &math);
458     if(FAILED(hres))
459         return hres;
460
461     V_VT(&var) = VT_DISPATCH;
462     V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(math);
463     hres = jsdisp_propput_name(ctx->global, MathW, ctx->lcid, &var, NULL/*FIXME*/, NULL/*FIXME*/);
464     jsdisp_release(math);
465
466     return hres;
467 }