diff --git a/jacob/docs/ReleaseNotes.html b/jacob/docs/ReleaseNotes.html
index a8a2313..e220cbe 100644
--- a/jacob/docs/ReleaseNotes.html
+++ b/jacob/docs/ReleaseNotes.html
@@ -16,6 +16,17 @@
Tracked Changes
Bugs |
+
+ 3065265 |
+ Bit masking in Variant.getXXXRef() uses wrong mask allowing more than
+ one type to be seen as the requested type. Code that passed in the correct type always worked
+ but invalid types were not always detected.(M4) |
+
+
+ 2935662 |
+ Error handling code crashes because of uninitialized data in Dispatch.cpp
+ Check for NULL fails. pfnDeferredFillIn pointer is not initialized, but it's not NULL.(M4) |
+
2819445 |
SafeArray.fromLongArray fails when using VariantLongInt (M3) |
@@ -32,11 +43,6 @@ Tracked Changes
checked on every object creation for users who run in the standard
all classes in ROT mode. (M2)
-
- 2935662 |
- Error handling code crashes because of uninitialized data in Dispatch.cpp
- Check for NULL fails. pfnDeferredFillIn pointer is not initialized, but it's not NULL. |
-
|
|
diff --git a/jacob/src/com/jacob/com/Variant.java b/jacob/src/com/jacob/com/Variant.java
index 02de337..91ae210 100644
--- a/jacob/src/com/jacob/com/Variant.java
+++ b/jacob/src/com/jacob/com/Variant.java
@@ -137,13 +137,13 @@ public class Variant extends JacobObject {
// VT_CARRARY = 28
// VT_USERDEFINED = 29
- /** what is this? VT_TYPEMASK && VT_BSTR_BLOB */
+ /** what is this? VT_TYPEMASK && VT_BSTR_BLOB 0xfff */
public static final short VariantTypeMask = 4095;
- /** variant's type is array VT_ARRAY */
+ /** variant's type is array VT_ARRAY 0x2000 */
public static final short VariantArray = 8192;
- /** variant's type is a reference (to IDispatch?) VT_BYREF */
+ /** variant's type is a reference (to IDispatch?) VT_BYREF 0x4000 */
public static final short VariantByref = 16384;
/*
@@ -289,6 +289,7 @@ public Variant changeType(short in) {
*
* @return ?? comment says null?
*/
+ @Override
public native Object clone();
/**
@@ -303,6 +304,7 @@ public Variant changeType(short in) {
*
* @see java.lang.Object#finalize()
*/
+ @Override
protected void finalize() {
safeRelease();
}
@@ -331,7 +333,7 @@ public boolean getBoolean() {
* if variant is not of the requested type
*/
public boolean getBooleanRef() {
- if ((this.getvt() & VariantBoolean) == VariantBoolean
+ if ((this.getvt() & VariantTypeMask) == VariantBoolean
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantBooleanRef();
} else {
@@ -365,7 +367,7 @@ public byte getByte() {
* if variant is not of the requested type
*/
public byte getByteRef() {
- if ((this.getvt() & VariantByte) == VariantByte
+ if ((this.getvt() & VariantTypeMask) == VariantByte
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantByteRef();
} else {
@@ -404,7 +406,7 @@ public Currency getCurrency() {
* if variant is not of the requested type
*/
public Currency getCurrencyRef() {
- if ((this.getvt() & VariantCurrency) == VariantCurrency
+ if ((this.getvt() & VariantTypeMask) == VariantCurrency
&& (this.getvt() & VariantByref) == VariantByref) {
return new Currency(getVariantCurrencyRef());
} else {
@@ -438,7 +440,7 @@ public double getDate() {
* if variant is not of the requested type
*/
public double getDateRef() {
- if ((this.getvt() & VariantDate) == VariantDate
+ if ((this.getvt() & VariantTypeMask) == VariantDate
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantDateRef();
} else {
@@ -473,7 +475,7 @@ public BigDecimal getDecimal() {
* if variant is not of the requested type
*/
public BigDecimal getDecimalRef() {
- if ((this.getvt() & VariantDecimal) == VariantDecimal
+ if ((this.getvt() & VariantTypeMask) == VariantDecimal
&& (this.getvt() & VariantByref) == VariantByref) {
return (BigDecimal) (getVariantDecRef());
} else {
@@ -493,7 +495,7 @@ public BigDecimal getDecimalRef() {
* if wrong variant type
*/
public Dispatch getDispatch() {
- if ((this.getvt() & VariantDispatch) == VariantDispatch) {
+ if (this.getvt() == VariantDispatch) {
return toDispatch();
} else {
throw new IllegalStateException(
@@ -511,7 +513,7 @@ public Dispatch getDispatch() {
* if variant is not of the requested type
*/
public Dispatch getDispatchRef() {
- if ((this.getvt() & VariantDispatch) == VariantDispatch
+ if ((this.getvt() & VariantTypeMask) == VariantDispatch
&& (this.getvt() & VariantByref) == VariantByref) {
return toDispatch();
} else {
@@ -544,7 +546,7 @@ public double getDouble() {
* if variant is not of the requested type
*/
public double getDoubleRef() {
- if ((this.getvt() & VariantDouble) == VariantDouble
+ if ((this.getvt() & VariantTypeMask) == VariantDouble
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantDoubleRef();
} else {
@@ -589,7 +591,7 @@ public int getError() {
* if variant is not of the requested type
*/
public int getErrorRef() {
- if ((this.getvt() & VariantError) == VariantError
+ if ((this.getvt() & VariantTypeMask) == VariantError
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantErrorRef();
} else {
@@ -621,7 +623,7 @@ public float getFloat() {
* if variant is not of the requested type
*/
public float getFloatRef() {
- if ((this.getvt() & VariantFloat) == VariantFloat
+ if ((this.getvt() & VariantTypeMask) == VariantFloat
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantFloatRef();
} else {
@@ -659,7 +661,7 @@ public int getInt() {
* if variant is not of the requested type
*/
public int getIntRef() {
- if ((this.getvt() & VariantInt) == VariantInt
+ if ((this.getvt() & VariantTypeMask) == VariantInt
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantIntRef();
} else {
@@ -735,7 +737,7 @@ public long getLong() {
* if variant is not of the requested type
*/
public long getLongRef() {
- if ((this.getvt() & VariantLongInt) == VariantLongInt
+ if ((this.getvt() & VariantTypeMask) == VariantLongInt
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantLongRef();
} else {
@@ -781,7 +783,7 @@ public short getShort() {
* if variant is not of the requested type
*/
public short getShortRef() {
- if ((this.getvt() & VariantShort) == VariantShort
+ if ((this.getvt() & VariantTypeMask) == VariantShort
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantShortRef();
} else {
@@ -815,7 +817,7 @@ public String getString() {
* if variant is not of the requested type
*/
public String getStringRef() {
- if ((this.getvt() & VariantString) == VariantString
+ if ((this.getvt() & VariantTypeMask) == VariantString
&& (this.getvt() & VariantByref) == VariantByref) {
return getVariantStringRef();
} else {
@@ -834,7 +836,7 @@ public String getStringRef() {
* Variant
*/
public Object getVariant() {
- if ((this.getvt() & VariantVariant) == VariantVariant
+ if ((this.getvt() & VariantTypeMask) == VariantVariant
&& (this.getvt() & VariantByref) == VariantByref) {
if (JacobObject.isDebugEnabled()) {
JacobObject.debug("About to call getVariantVariant()");
@@ -1607,8 +1609,8 @@ public void putStringRef(String in) {
* A object that is to be referenced by this variant. If
* objectToBeWrapped is already of type Variant, then it is used.
* If objectToBeWrapped is not Variant then
- * new Variant(objectToBeWrapped)
is called and
- * the result is passed into the com layer
+ * new Variant(objectToBeWrapped)
is called and the
+ * result is passed into the com layer
* @throws IllegalArgumentException
* if inVariant = null or if inVariant is a Varint
*/
@@ -1874,6 +1876,7 @@ private native void putVariantDecRef(int signum, byte scale, int lo,
*
* @see com.jacob.com.JacobObject#safeRelease()
*/
+ @Override
public void safeRelease() {
// The well known constants should not be released.
// Unfortunately this doesn't fix any other classes that are
@@ -2161,6 +2164,7 @@ public short toShort() {
* @throws IllegalStateException
* if there is no underlying windows data structure
*/
+ @Override
public String toString() {
try {
// see if we are in a legal state
diff --git a/jacob/src/com/jacob/com/VariantUtilities.java b/jacob/src/com/jacob/com/VariantUtilities.java
index afaa8bb..1ac652a 100644
--- a/jacob/src/com/jacob/com/VariantUtilities.java
+++ b/jacob/src/com/jacob/com/VariantUtilities.java
@@ -356,7 +356,7 @@ protected static Object variantToObject(Variant sourceData) {
break;
case Variant.VariantTypeMask: // 4095
result = new NotImplementedException(
- "toJavaObject() Not implemented for VariantTypeMask");
+ "toJavaObject() Not implemented for VariantBstrBlob/VariantTypeMask");
break;
case Variant.VariantArray: // 8192
result = new NotImplementedException(
diff --git a/jacob/unittest/com/jacob/com/VariantTest.java b/jacob/unittest/com/jacob/com/VariantTest.java
index ac09e21..2f4c0ba 100644
--- a/jacob/unittest/com/jacob/com/VariantTest.java
+++ b/jacob/unittest/com/jacob/com/VariantTest.java
@@ -648,6 +648,7 @@ public boolean isComplete() {
*
* @see java.lang.Runnable#run()
*/
+ @Override
public void run() {
for (int variantIndex = 0; variantIndex < initialRunSize; variantIndex++) {
try {
@@ -664,4 +665,40 @@ public void run() {
isComplete = true;
}
}
+
+ /**
+ * there was a bitwise masking error that let booleans be seen as dispatch
+ * objects Bug Report SF3065265
+ */
+ public void testGetDispatch() {
+ Variant testVariant = new Variant();
+ testVariant.putBooleanRef(true);
+ try {
+ // throws IllegalStateException if Jacob detects the type
+ // throws some other bad exception if COM blows up failing the
+ // conversion
+ testVariant.getDispatchRef();
+ fail("Should not have converted boolean to dispatch");
+ } catch (IllegalStateException e) {
+ // yeah! can't get dispatch from boolean
+ }
+ }
+
+ /**
+ * there was a bitwise masking error that let booleans be seen as dispatch
+ * objects Bug Report SF3065265
+ */
+ public void testGetError() {
+ Variant testVariant = new Variant();
+ testVariant.putErrorRef(3);
+ try {
+ // throws IllegalStateException if Jacob detects the type
+ // throws some other bad exception if COM blows up failing the
+ // conversion
+ testVariant.getStringRef();
+ fail("Should not have converted error to string");
+ } catch (IllegalStateException e) {
+ // yeah! can't get dispatch from boolean
+ }
+ }
}