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
ec218b42
Commit
ec218b42
authored
Jul 07, 2014
by
Sebastian Lackner
Committed by
Alexandre Julliard
Jul 09, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Decrease accuracy if scaling is not possible in VarDecAdd.
parent
04f11ee5
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
59 additions
and
21 deletions
+59
-21
vartype.c
dlls/oleaut32/tests/vartype.c
+5
-5
vartype.c
dlls/oleaut32/vartype.c
+54
-16
No files found.
dlls/oleaut32/tests/vartype.c
View file @
ec218b42
...
...
@@ -4419,7 +4419,7 @@ static void test_VarDecAdd(void)
todo_wine
EXPECTDEC64
(
0
,
0
,
0x2d3c8750
,
0xbd670354
,
0xb0000000
);
SETDEC
(
l
,
3
,
128
,
0
,
123456
);
SETDEC64
(
r
,
0
,
0
,
0xFFFFFFFF
,
0xFFFFFFFF
,
0xFFFFFFFF
);
MATH2
(
VarDecAdd
);
todo_wine
EXPECTDEC64
(
0
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFF84
);
MATH2
(
VarDecAdd
);
EXPECTDEC64
(
0
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFF84
);
SETDEC
(
l
,
3
,
0
,
0
,
123456
);
SETDEC64
(
r
,
0
,
0
,
0xFFFFFFFF
,
0xFFFFFFFF
,
0xFFFFFFFF
);
MATH2
(
VarDecAdd
);
ok
(
hres
==
DISP_E_OVERFLOW
,
"Expected overflow, got (%d,%d,%d,(%8x,%8x)x) hres 0x%08x
\n
"
,
...
...
@@ -4434,13 +4434,13 @@ static void test_VarDecAdd(void)
S
(
U
(
out
)).
scale
,
S
(
U
(
out
)).
sign
,
out
.
Hi32
,
S1
(
U1
(
out
)).
Mid32
,
S1
(
U1
(
out
)).
Lo32
,
hres
);
SETDEC
(
l
,
6
,
0
,
0
,
123456
);
SETDEC64
(
r
,
0
,
0
,
0xFFFFFFFF
,
0xFFFFFFFF
,
0xFFFFFFFF
);
MATH2
(
VarDecAdd
);
todo_wine
EXPECTDEC64
(
0
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFFFF
);
MATH2
(
VarDecAdd
);
EXPECTDEC64
(
0
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFFFF
);
SETDEC
(
l
,
3
,
128
,
0
,
123456
);
SETDEC64
(
r
,
0
,
0
,
0x19999999
,
0x99999999
,
0x99999999
);
MATH2
(
VarDecAdd
);
todo_wine
EXPECTDEC64
(
1
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFB27
);
MATH2
(
VarDecAdd
);
EXPECTDEC64
(
1
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFB27
);
SETDEC
(
l
,
3
,
128
,
0
,
123567
);
SETDEC64
(
r
,
0
,
0
,
0x19999999
,
0x99999999
,
0x99999999
);
MATH2
(
VarDecAdd
);
todo_wine
EXPECTDEC64
(
1
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFB26
);
MATH2
(
VarDecAdd
);
EXPECTDEC64
(
1
,
0
,
-
1
,
0xFFFFFFFF
,
0xFFFFFB26
);
/* Promotes to the highest scale, so here the results are in the scale of 2 */
SETDEC
(
l
,
2
,
0
,
0
,
0
);
SETDEC
(
r
,
0
,
0
,
0
,
0
);
MATH2
(
VarDecAdd
);
EXPECTDEC
(
2
,
0
,
0
,
0
);
...
...
@@ -4663,7 +4663,7 @@ static void test_VarDecCmp(void)
SETDEC
(
out
,
0
,
DECIMAL_NEG
,
-
1
,
-
1
);
SETDEC
(
l
,
0
,
DECIMAL_NEG
,
-
1
,
-
1
);
MATH1
(
VarDecCmp
);
EXPECT_EQ
;
SETDEC
(
l
,
3
,
0
,
0
,
123456
);
SETDEC64
(
out
,
0
,
0
,
0xFFFFFFFF
,
0xFFFFFFFF
,
0xFFFFFFFF
);
MATH1
(
VarDecCmp
);
todo_wine
EXPECT_LT
;
MATH1
(
VarDecCmp
);
EXPECT_LT
;
}
static
void
test_VarDecCmpR8
(
void
)
...
...
dlls/oleaut32/vartype.c
View file @
ec218b42
...
...
@@ -4164,6 +4164,8 @@ static HRESULT VARIANT_DI_FromR4(float source, VARIANT_DI * dest);
static
HRESULT
VARIANT_DI_FromR8
(
double
source
,
VARIANT_DI
*
dest
);
static
void
VARIANT_DIFromDec
(
const
DECIMAL
*
from
,
VARIANT_DI
*
to
);
static
void
VARIANT_DecFromDI
(
const
VARIANT_DI
*
from
,
DECIMAL
*
to
);
static
unsigned
char
VARIANT_int_divbychar
(
DWORD
*
p
,
unsigned
int
n
,
unsigned
char
divisor
);
static
BOOL
VARIANT_int_iszero
(
const
DWORD
*
p
,
unsigned
int
n
);
/************************************************************************
* VarDecFromR4 (OLEAUT32.193)
...
...
@@ -4439,12 +4441,13 @@ HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL* pDecOut)
/* Make two DECIMALS the same scale; used by math functions below */
static
HRESULT
VARIANT_DecScale
(
const
DECIMAL
**
ppDecLeft
,
const
DECIMAL
**
ppDecRight
,
DECIMAL
*
pDecOut
)
DECIMAL
pDecOut
[
2
]
)
{
static
DECIMAL
scaleFactor
;
unsigned
char
remainder
;
DECIMAL
decTemp
;
VARIANT_DI
di
;
int
scaleAmount
,
i
;
HRESULT
hRet
=
S_OK
;
if
(
DEC_SIGN
(
*
ppDecLeft
)
&
~
DECIMAL_NEG
||
DEC_SIGN
(
*
ppDecRight
)
&
~
DECIMAL_NEG
)
return
E_INVALIDARG
;
...
...
@@ -4459,27 +4462,62 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
if
(
scaleAmount
>
0
)
{
decTemp
=
*
(
*
ppDecRight
);
/* Left is bigger - scale the right hand side */
*
ppDecRight
=
pDecOut
;
*
ppDecRight
=
&
pDecOut
[
0
]
;
}
else
{
decTemp
=
*
(
*
ppDecLeft
);
/* Right is bigger - scale the left hand side */
*
ppDecLeft
=
pDecOut
;
i
=
scaleAmount
=
-
scaleAmount
;
*
ppDecLeft
=
&
pDecOut
[
0
]
;
i
=
-
scaleAmount
;
}
if
(
DEC_SCALE
(
&
decTemp
)
+
scaleAmount
>
DEC_MAX_SCALE
)
return
DISP_E_OVERFLOW
;
/* Can't scale up */
/* Multiply up the value to be scaled by the correct amount (if possible) */
while
(
i
>
0
&&
SUCCEEDED
(
VarDecMul
(
&
decTemp
,
&
scaleFactor
,
&
pDecOut
[
0
])))
{
decTemp
=
pDecOut
[
0
];
i
--
;
}
/* Multiply up the value to be scaled by the correct amount */
while
(
SUCCEEDED
(
hRet
)
&&
i
--
)
if
(
!
i
)
{
/* Note we are multiplying by a value with a scale of 0, so we don't recurse */
hRet
=
VarDecMul
(
&
decTemp
,
&
scaleFactor
,
pDecOut
);
decTemp
=
*
pDecOut
;
DEC_SCALE
(
&
pDecOut
[
0
])
+=
(
scaleAmount
>
0
)
?
scaleAmount
:
(
-
scaleAmount
);
return
S_OK
;
/* Same scale */
}
DEC_SCALE
(
pDecOut
)
+=
scaleAmount
;
/* Set the new scale */
return
hRet
;
/* Scaling further not possible, reduce accuracy of other argument */
pDecOut
[
0
]
=
decTemp
;
if
(
scaleAmount
>
0
)
{
DEC_SCALE
(
&
pDecOut
[
0
])
+=
scaleAmount
-
i
;
VARIANT_DIFromDec
(
*
ppDecLeft
,
&
di
);
*
ppDecLeft
=
&
pDecOut
[
1
];
}
else
{
DEC_SCALE
(
&
pDecOut
[
0
])
+=
(
-
scaleAmount
)
-
i
;
VARIANT_DIFromDec
(
*
ppDecRight
,
&
di
);
*
ppDecRight
=
&
pDecOut
[
1
];
}
di
.
scale
-=
i
;
remainder
=
0
;
while
(
i
--
>
0
&&
!
VARIANT_int_iszero
(
di
.
bitsnum
,
sizeof
(
di
.
bitsnum
)
/
sizeof
(
DWORD
)))
{
remainder
=
VARIANT_int_divbychar
(
di
.
bitsnum
,
sizeof
(
di
.
bitsnum
)
/
sizeof
(
DWORD
),
10
);
if
(
remainder
>
0
)
WARN
(
"losing significant digits (remainder %u)...
\n
"
,
remainder
);
}
/* round up the result - native oleaut32 does this */
if
(
remainder
>=
5
)
{
for
(
remainder
=
1
,
i
=
0
;
i
<
sizeof
(
di
.
bitsnum
)
/
sizeof
(
DWORD
)
&&
remainder
;
i
++
)
{
ULONGLONG
digit
=
di
.
bitsnum
[
i
]
+
1
;
remainder
=
(
digit
>
0xFFFFFFFF
)
?
1
:
0
;
di
.
bitsnum
[
i
]
=
digit
&
0xFFFFFFFF
;
}
}
VARIANT_DecFromDI
(
&
di
,
&
pDecOut
[
1
]);
return
S_OK
;
}
/* Add two unsigned 32 bit values with overflow */
...
...
@@ -4554,9 +4592,9 @@ static inline int VARIANT_DecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRig
HRESULT
WINAPI
VarDecAdd
(
const
DECIMAL
*
pDecLeft
,
const
DECIMAL
*
pDecRight
,
DECIMAL
*
pDecOut
)
{
HRESULT
hRet
;
DECIMAL
scaled
;
DECIMAL
scaled
[
2
]
;
hRet
=
VARIANT_DecScale
(
&
pDecLeft
,
&
pDecRight
,
&
scaled
);
hRet
=
VARIANT_DecScale
(
&
pDecLeft
,
&
pDecRight
,
scaled
);
if
(
SUCCEEDED
(
hRet
))
{
...
...
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