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 + } + } }