Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c2b55387
Commit
c2b55387
authored
Feb 01, 2023
by
Gabriel Ivăncescu
Committed by
Alexandre Julliard
Feb 01, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Pass the correct ServiceProvider when invoking external prop.
Signed-off-by:
Gabriel Ivăncescu
<
gabrielopcode@gmail.com
>
parent
9beef3fc
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
167 additions
and
17 deletions
+167
-17
dispex.c
dlls/jscript/dispex.c
+17
-16
jscript.h
dlls/jscript/jscript.h
+7
-1
run.c
dlls/jscript/tests/run.c
+143
-0
No files found.
dlls/jscript/dispex.c
View file @
c2b55387
...
...
@@ -572,9 +572,9 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
TRACE
(
"call %s %p
\n
"
,
debugstr_w
(
prop
->
name
),
get_object
(
prop
->
u
.
val
));
return
disp_call_value
(
This
->
ctx
,
get_object
(
prop
->
u
.
val
),
jsval_disp
(
jsthis
?
jsthis
:
(
IDispatch
*
)
&
This
->
IDispatchEx_iface
),
flags
,
argc
,
argv
,
r
);
return
disp_call_value
_with_caller
(
This
->
ctx
,
get_object
(
prop
->
u
.
val
),
jsval_disp
(
jsthis
?
jsthis
:
(
IDispatch
*
)
&
This
->
IDispatchEx_iface
),
flags
,
argc
,
argv
,
r
,
calle
r
);
}
case
PROP_ACCESSOR
:
case
PROP_IDX
:
{
...
...
@@ -585,9 +585,9 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
return
hres
;
if
(
is_object_instance
(
val
))
{
hres
=
disp_call_value
(
This
->
ctx
,
get_object
(
val
),
jsval_disp
(
jsthis
?
jsthis
:
(
IDispatch
*
)
&
This
->
IDispatchEx_iface
),
flags
,
argc
,
argv
,
r
);
hres
=
disp_call_value
_with_caller
(
This
->
ctx
,
get_object
(
val
),
jsval_disp
(
jsthis
?
jsthis
:
(
IDispatch
*
)
&
This
->
IDispatchEx_iface
),
flags
,
argc
,
argv
,
r
,
calle
r
);
}
else
{
FIXME
(
"invoke %s
\n
"
,
debugstr_jsval
(
val
));
hres
=
E_NOTIMPL
;
...
...
@@ -2364,7 +2364,7 @@ HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_
if
(
!
prop
)
return
DISP_E_MEMBERNOTFOUND
;
return
invoke_prop_func
(
disp
,
to_disp
(
disp
),
prop
,
flags
,
argc
,
argv
,
r
,
NULL
);
return
invoke_prop_func
(
disp
,
to_disp
(
disp
),
prop
,
flags
,
argc
,
argv
,
r
,
&
disp
->
ctx
->
jscaller
->
IServiceProvider_iface
);
}
HRESULT
jsdisp_call_name
(
jsdisp_t
*
disp
,
const
WCHAR
*
name
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
...
...
@@ -2379,10 +2379,11 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned
if
(
!
prop
||
prop
->
type
==
PROP_DELETED
)
return
JS_E_INVALID_PROPERTY
;
return
invoke_prop_func
(
disp
,
to_disp
(
disp
),
prop
,
flags
,
argc
,
argv
,
r
,
NULL
);
return
invoke_prop_func
(
disp
,
to_disp
(
disp
),
prop
,
flags
,
argc
,
argv
,
r
,
&
disp
->
ctx
->
jscaller
->
IServiceProvider_iface
);
}
static
HRESULT
disp_invoke
(
script_ctx_t
*
ctx
,
IDispatch
*
disp
,
DISPID
id
,
WORD
flags
,
DISPPARAMS
*
params
,
VARIANT
*
r
)
static
HRESULT
disp_invoke
(
script_ctx_t
*
ctx
,
IDispatch
*
disp
,
DISPID
id
,
WORD
flags
,
DISPPARAMS
*
params
,
VARIANT
*
r
,
IServiceProvider
*
caller
)
{
IDispatchEx
*
dispex
;
EXCEPINFO
ei
;
...
...
@@ -2391,7 +2392,7 @@ static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD f
memset
(
&
ei
,
0
,
sizeof
(
ei
));
hres
=
IDispatch_QueryInterface
(
disp
,
&
IID_IDispatchEx
,
(
void
**
)
&
dispex
);
if
(
SUCCEEDED
(
hres
))
{
hres
=
IDispatchEx_InvokeEx
(
dispex
,
id
,
ctx
->
lcid
,
flags
,
params
,
r
,
&
ei
,
&
ctx
->
jscaller
->
IServiceProvider_iface
);
hres
=
IDispatchEx_InvokeEx
(
dispex
,
id
,
ctx
->
lcid
,
flags
,
params
,
r
,
&
ei
,
caller
);
IDispatchEx_Release
(
dispex
);
}
else
{
UINT
err
=
0
;
...
...
@@ -2489,7 +2490,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
}
V_VT
(
&
retv
)
=
VT_EMPTY
;
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
flags
,
&
dp
,
ret
?
&
retv
:
NULL
);
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
flags
,
&
dp
,
ret
?
&
retv
:
NULL
,
&
ctx
->
jscaller
->
IServiceProvider_iface
);
for
(
i
=
0
;
i
<
argc
;
i
++
)
VariantClear
(
dp
.
rgvarg
+
argc
-
i
-
1
);
...
...
@@ -2529,8 +2530,8 @@ HRESULT disp_call_name(script_ctx_t *ctx, IDispatch *disp, const WCHAR *name, WO
return
disp_call
(
ctx
,
disp
,
id
,
flags
,
argc
,
argv
,
ret
);
}
HRESULT
disp_call_value
(
script_ctx_t
*
ctx
,
IDispatch
*
disp
,
jsval_t
vthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
HRESULT
disp_call_value
_with_caller
(
script_ctx_t
*
ctx
,
IDispatch
*
disp
,
jsval_t
vthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
,
IServiceProvider
*
calle
r
)
{
VARIANT
buf
[
6
],
retv
,
*
args
=
buf
;
IDispatch
*
jsthis
;
...
...
@@ -2586,7 +2587,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD
if
(
SUCCEEDED
(
hres
))
{
V_VT
(
&
retv
)
=
VT_EMPTY
;
hres
=
disp_invoke
(
ctx
,
disp
,
DISPID_VALUE
,
flags
,
&
dp
,
r
?
&
retv
:
NULL
);
hres
=
disp_invoke
(
ctx
,
disp
,
DISPID_VALUE
,
flags
,
&
dp
,
r
?
&
retv
:
NULL
,
caller
);
}
for
(
i
=
0
;
i
<
argc
;
i
++
)
...
...
@@ -2665,7 +2666,7 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val)
if
(
V_VT
(
&
var
)
==
VT_DISPATCH
)
flags
|=
DISPATCH_PROPERTYPUTREF
;
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
flags
,
&
dp
,
NULL
);
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
flags
,
&
dp
,
NULL
,
&
ctx
->
jscaller
->
IServiceProvider_iface
);
VariantClear
(
&
var
);
}
...
...
@@ -2773,7 +2774,7 @@ HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val
jsdisp_release
(
jsdisp
);
V_VT
(
&
var
)
=
VT_EMPTY
;
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
INVOKE_PROPERTYGET
,
&
dp
,
&
var
);
hres
=
disp_invoke
(
ctx
,
disp
,
id
,
INVOKE_PROPERTYGET
,
&
dp
,
&
var
,
&
ctx
->
jscaller
->
IServiceProvider_iface
);
if
(
SUCCEEDED
(
hres
))
{
hres
=
variant_to_jsval
(
ctx
,
&
var
,
val
);
VariantClear
(
&
var
);
...
...
dlls/jscript/jscript.h
View file @
c2b55387
...
...
@@ -240,7 +240,7 @@ HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,js
HRESULT
disp_call
(
script_ctx_t
*
,
IDispatch
*
,
DISPID
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
HRESULT
disp_call_name
(
script_ctx_t
*
,
IDispatch
*
,
const
WCHAR
*
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
HRESULT
disp_call_value
(
script_ctx_t
*
,
IDispatch
*
,
jsval_t
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
HRESULT
disp_call_value
_with_caller
(
script_ctx_t
*
,
IDispatch
*
,
jsval_t
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
,
IServiceProvider
*
)
DECLSPEC_HIDDEN
;
HRESULT
jsdisp_call_value
(
jsdisp_t
*
,
jsval_t
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
HRESULT
jsdisp_call
(
jsdisp_t
*
,
DISPID
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
HRESULT
jsdisp_call_name
(
jsdisp_t
*
,
const
WCHAR
*
,
WORD
,
unsigned
,
jsval_t
*
,
jsval_t
*
)
DECLSPEC_HIDDEN
;
...
...
@@ -483,6 +483,12 @@ static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
return
((
ctx
->
version
&
0xff
)
<<
28
)
|
flags
;
}
static
inline
HRESULT
disp_call_value
(
script_ctx_t
*
ctx
,
IDispatch
*
disp
,
jsval_t
vthis
,
WORD
flags
,
unsigned
argc
,
jsval_t
*
argv
,
jsval_t
*
r
)
{
return
disp_call_value_with_caller
(
ctx
,
disp
,
vthis
,
flags
,
argc
,
argv
,
r
,
&
ctx
->
jscaller
->
IServiceProvider_iface
);
}
#define FACILITY_JSCRIPT 10
#define MAKE_JSERROR(code) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_JSCRIPT, code)
...
...
dlls/jscript/tests/run.c
View file @
c2b55387
...
...
@@ -114,6 +114,9 @@ DEFINE_EXPECT(testobj_newenum);
DEFINE_EXPECT
(
testobj_getidfail_d
);
DEFINE_EXPECT
(
testobj_tolocalestr_d
);
DEFINE_EXPECT
(
testobj_tolocalestr_i
);
DEFINE_EXPECT
(
test_caller_get
);
DEFINE_EXPECT
(
test_caller_null
);
DEFINE_EXPECT
(
test_caller_obj
);
DEFINE_EXPECT
(
testdestrobj
);
DEFINE_EXPECT
(
enumvariant_next_0
);
DEFINE_EXPECT
(
enumvariant_next_1
);
...
...
@@ -333,6 +336,44 @@ static IEnumVARIANTVtbl testEnumVARIANTVtbl = {
static
IEnumVARIANT
testEnumVARIANT
=
{
&
testEnumVARIANTVtbl
};
static
HRESULT
WINAPI
sp_QueryInterface
(
IServiceProvider
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
if
(
IsEqualGUID
(
&
IID_IUnknown
,
riid
)
||
IsEqualGUID
(
&
IID_IServiceProvider
,
riid
))
{
*
ppv
=
iface
;
return
S_OK
;
}
ok
(
0
,
"unexpected call %s
\n
"
,
wine_dbgstr_guid
(
riid
));
*
ppv
=
NULL
;
return
E_NOTIMPL
;
}
static
ULONG
WINAPI
sp_AddRef
(
IServiceProvider
*
iface
)
{
return
2
;
}
static
ULONG
WINAPI
sp_Release
(
IServiceProvider
*
iface
)
{
return
1
;
}
static
HRESULT
WINAPI
sp_QueryService
(
IServiceProvider
*
iface
,
REFGUID
guidService
,
REFIID
riid
,
void
**
ppv
)
{
ok
(
0
,
"unexpected call %s
\n
"
,
wine_dbgstr_guid
(
guidService
));
*
ppv
=
NULL
;
return
E_NOTIMPL
;
}
static
const
IServiceProviderVtbl
sp_vtbl
=
{
sp_QueryInterface
,
sp_AddRef
,
sp_Release
,
sp_QueryService
};
static
IServiceProvider
sp_obj
=
{
&
sp_vtbl
};
static
HRESULT
WINAPI
DispatchEx_QueryInterface
(
IDispatchEx
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
*
ppv
=
NULL
;
...
...
@@ -629,6 +670,61 @@ static IDispatchExVtbl testObjVtbl = {
static
IDispatchEx
testObj
=
{
&
testObjVtbl
};
static
HRESULT
WINAPI
testcallerobj_InvokeEx
(
IDispatchEx
*
iface
,
DISPID
id
,
LCID
lcid
,
WORD
wFlags
,
DISPPARAMS
*
pdp
,
VARIANT
*
pvarRes
,
EXCEPINFO
*
pei
,
IServiceProvider
*
pspCaller
)
{
ok
(
id
==
DISPID_VALUE
,
"id = %ld
\n
"
,
id
);
ok
(
pdp
!=
NULL
,
"pdp == NULL
\n
"
);
ok
(
pvarRes
!=
NULL
,
"pvarRes == NULL
\n
"
);
ok
(
V_VT
(
pvarRes
)
==
VT_EMPTY
,
"V_VT(pvarRes) = %d
\n
"
,
V_VT
(
pvarRes
));
if
(
wFlags
==
DISPATCH_PROPERTYGET
)
{
CHECK_EXPECT
(
test_caller_get
);
ok
(
!
pdp
->
rgdispidNamedArgs
,
"rgdispidNamedArgs != NULL
\n
"
);
ok
(
!
pdp
->
cNamedArgs
,
"cNamedArgs = %d
\n
"
,
pdp
->
cNamedArgs
);
ok
(
pei
!=
NULL
,
"pei == NULL
\n
"
);
ok
(
pspCaller
!=
NULL
,
"pspCaller == NULL
\n
"
);
ok
(
pspCaller
!=
&
sp_obj
,
"pspCaller == sp_obj
\n
"
);
V_VT
(
pvarRes
)
=
VT_DISPATCH
;
V_DISPATCH
(
pvarRes
)
=
(
IDispatch
*
)
iface
;
}
else
if
(
pspCaller
)
{
CHECK_EXPECT
(
test_caller_obj
);
ok
(
wFlags
==
DISPATCH_METHOD
,
"wFlags = %04x
\n
"
,
wFlags
);
ok
(
pdp
->
rgdispidNamedArgs
!=
NULL
,
"rgdispidNamedArgs == NULL
\n
"
);
ok
(
pdp
->
cNamedArgs
==
1
,
"cNamedArgs = %d
\n
"
,
pdp
->
cNamedArgs
);
ok
(
pspCaller
==
&
sp_obj
,
"pspCaller != sp_obj
\n
"
);
V_VT
(
pvarRes
)
=
VT_I4
;
V_I4
(
pvarRes
)
=
137
;
}
else
{
CHECK_EXPECT
(
test_caller_null
);
ok
(
wFlags
==
DISPATCH_METHOD
,
"wFlags = %04x
\n
"
,
wFlags
);
ok
(
pdp
->
rgdispidNamedArgs
!=
NULL
,
"rgdispidNamedArgs == NULL
\n
"
);
ok
(
pdp
->
cNamedArgs
==
1
,
"cNamedArgs = %d
\n
"
,
pdp
->
cNamedArgs
);
V_VT
(
pvarRes
)
=
VT_I4
;
V_I4
(
pvarRes
)
=
42
;
}
return
S_OK
;
}
static
IDispatchExVtbl
testcallerobj_vtbl
=
{
DispatchEx_QueryInterface
,
DispatchEx_AddRef
,
DispatchEx_Release
,
DispatchEx_GetTypeInfoCount
,
DispatchEx_GetTypeInfo
,
DispatchEx_GetIDsOfNames
,
DispatchEx_Invoke
,
DispatchEx_GetDispID
,
testcallerobj_InvokeEx
,
DispatchEx_DeleteMemberByName
,
DispatchEx_DeleteMemberByDispID
,
DispatchEx_GetMemberProperties
,
DispatchEx_GetMemberName
,
DispatchEx_GetNextDispID
,
DispatchEx_GetNameSpaceParent
};
static
IDispatchEx
testcallerobj
=
{
&
testcallerobj_vtbl
};
static
LONG
test_destr_ref
;
static
ULONG
WINAPI
testDestrObj_AddRef
(
IDispatchEx
*
iface
)
...
...
@@ -3214,6 +3310,7 @@ static void test_script_exprs(void)
static
void
test_invokeex
(
void
)
{
static
DISPID
propput_dispid
=
DISPID_PROPERTYPUT
;
DISPPARAMS
dp
=
{
NULL
},
dp_max
=
{
NULL
};
DISPID
func_id
,
max_id
,
prop_id
;
IActiveScript
*
script
;
...
...
@@ -3442,6 +3539,52 @@ static void test_invokeex(void)
IDispatchEx_Release
(
dispex
);
IActiveScript_Release
(
script
);
/* test InvokeEx with host prop and custom caller */
hres
=
parse_script_expr
(
L"var o = {}; o"
,
&
v
,
&
script
);
ok
(
hres
==
S_OK
,
"parse_script_expr failed: %08lx
\n
"
,
hres
);
ok
(
V_VT
(
&
v
)
==
VT_DISPATCH
,
"V_VT(v) = %d
\n
"
,
V_VT
(
&
v
));
hres
=
IDispatch_QueryInterface
(
V_DISPATCH
(
&
v
),
&
IID_IDispatchEx
,
(
void
**
)
&
dispex
);
ok
(
hres
==
S_OK
,
"Could not get IDispatchEx iface: %08lx
\n
"
,
hres
);
VariantClear
(
&
v
);
str
=
SysAllocString
(
L"caller"
);
hres
=
IDispatchEx_GetDispID
(
dispex
,
str
,
fdexNameEnsure
,
&
func_id
);
SysFreeString
(
str
);
ok
(
hres
==
S_OK
,
"GetDispID failed: %08lx
\n
"
,
hres
);
SET_EXPECT
(
test_caller_get
);
dp
.
cArgs
=
dp
.
cNamedArgs
=
1
;
dp
.
rgvarg
=
&
arg
;
dp
.
rgdispidNamedArgs
=
&
propput_dispid
;
V_VT
(
&
arg
)
=
VT_DISPATCH
;
V_DISPATCH
(
&
arg
)
=
(
IDispatch
*
)
&
testcallerobj
;
hres
=
IDispatchEx_InvokeEx
(
dispex
,
func_id
,
0
,
DISPATCH_PROPERTYPUT
,
&
dp
,
NULL
,
NULL
,
NULL
);
ok
(
hres
==
S_OK
,
"InvokeEx failed: %08lx
\n
"
,
hres
);
todo_wine
CHECK_CALLED
(
test_caller_get
);
SET_EXPECT
(
test_caller_null
);
dp
.
cArgs
=
dp
.
cNamedArgs
=
0
;
dp
.
rgvarg
=
NULL
;
dp
.
rgdispidNamedArgs
=
NULL
;
hres
=
IDispatchEx_InvokeEx
(
dispex
,
func_id
,
0
,
DISPATCH_METHOD
,
&
dp
,
&
v
,
NULL
,
NULL
);
ok
(
hres
==
S_OK
,
"InvokeEx failed: %08lx
\n
"
,
hres
);
ok
(
V_VT
(
&
v
)
==
VT_I4
,
"V_VT(v) = %d
\n
"
,
V_VT
(
&
v
));
ok
(
V_I4
(
&
v
)
==
42
,
"V_I4(v) = %s
\n
"
,
wine_dbgstr_variant
(
&
v
));
CHECK_CALLED
(
test_caller_null
);
V_VT
(
&
v
)
=
VT_EMPTY
;
SET_EXPECT
(
test_caller_obj
);
hres
=
IDispatchEx_InvokeEx
(
dispex
,
func_id
,
0
,
DISPATCH_METHOD
,
&
dp
,
&
v
,
NULL
,
&
sp_obj
);
ok
(
hres
==
S_OK
,
"InvokeEx failed: %08lx
\n
"
,
hres
);
ok
(
V_VT
(
&
v
)
==
VT_I4
,
"V_VT(v) = %d
\n
"
,
V_VT
(
&
v
));
ok
(
V_I4
(
&
v
)
==
137
,
"V_I4(v) = %s
\n
"
,
wine_dbgstr_variant
(
&
v
));
CHECK_CALLED
(
test_caller_obj
);
IDispatchEx_Release
(
dispex
);
IActiveScript_Release
(
script
);
}
static
void
test_destructors
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment