Skip to content

Commit 4419bad

Browse files
author
Lauri Wiljami Ahonen
committed
Fix bug in VARDESC, TYPEDESC, and FUNCDESC causing illegal memory access. The types contained an array that might be zero-sized, but JNA tried to read at least one item.
1 parent 37995de commit 4419bad

File tree

3 files changed

+446
-16
lines changed

3 files changed

+446
-16
lines changed

CHANGES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Features
1212

1313
Bug Fixes
1414
---------
15-
15+
* [#1644](https://github.com/java-native-access/jna/issues/1644): Fix bug in VARDESC and TYPEDESC causing an illegal memory access - [@lwahonen](https://github.com/lwahonen)
1616

1717
Release 5.18.1
1818
==============

contrib/platform/src/com/sun/jna/platform/win32/OaIdl.java

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,15 @@ public static class SAFEARRAY extends Structure implements Closeable {
553553

554554
public static class ByReference extends SAFEARRAY implements
555555
Structure.ByReference {
556+
557+
public ByReference() {
558+
super();
559+
}
560+
561+
public ByReference(Pointer pointer) {
562+
super(pointer);
563+
}
564+
556565
}
557566

558567
public USHORT cDims;
@@ -1316,12 +1325,46 @@ public FUNCDESC() {
13161325
public FUNCDESC(Pointer pointer) {
13171326
super(pointer);
13181327
this.read();
1328+
}
1329+
1330+
@Override
1331+
public void read() {
1332+
// Read cParams first to know the correct array size for lprgelemdescParam
1333+
readField("cParams");
1334+
int paramCount = this.cParams.shortValue();
1335+
1336+
// Read most fields except lprgelemdescParam
1337+
for (String field : new String[]{
1338+
"memid", "lprgscode", "funckind", "invkind",
1339+
"callconv", "cParamsOpt", "oVft", "cScodes", "elemdescFunc", "wFuncFlags"}) {
1340+
readField(field);
1341+
}
13191342

1320-
if (this.cParams.shortValue() > 1) {
1321-
this.lprgelemdescParam.elemDescArg = new ELEMDESC[this.cParams
1322-
.shortValue()];
1323-
this.lprgelemdescParam.read();
1343+
// Handle lprgelemdescParam specially based on paramCount
1344+
if (paramCount > 0) {
1345+
readField("lprgelemdescParam");
1346+
if (this.lprgelemdescParam != null) {
1347+
this.lprgelemdescParam.elemDescArg = new ELEMDESC[paramCount];
1348+
this.lprgelemdescParam.read();
1349+
}
13241350
}
1351+
// When paramCount=0, don't read lprgelemdescParam to avoid reading garbage
1352+
}
1353+
1354+
@Override
1355+
public void write() {
1356+
// Write most fields except lprgelemdescParam
1357+
for (String field : new String[]{
1358+
"memid", "lprgscode", "funckind", "invkind",
1359+
"callconv", "cParams", "cParamsOpt", "oVft", "cScodes", "elemdescFunc", "wFuncFlags"}) {
1360+
writeField(field);
1361+
}
1362+
1363+
// Handle lprgelemdescParam specially based on cParams
1364+
if (this.cParams != null && this.cParams.shortValue() > 0) {
1365+
writeField("lprgelemdescParam");
1366+
}
1367+
// When cParams=0, don't write lprgelemdescParam
13251368
}
13261369
}
13271370

@@ -1398,14 +1441,10 @@ public static class ByReference extends _VARDESC implements
13981441
public VARIANT.ByReference lpvarValue;
13991442

14001443
public _VARDESC() {
1401-
setType("lpvarValue");
1402-
this.read();
14031444
}
14041445

14051446
public _VARDESC(Pointer pointer) {
14061447
super(pointer);
1407-
setType("lpvarValue");
1408-
this.read();
14091448
}
14101449

14111450
/**
@@ -1431,9 +1470,17 @@ public VARDESC() {
14311470

14321471
public VARDESC(Pointer pointer) {
14331472
super(pointer);
1434-
this._vardesc.setType("lpvarValue");
14351473
this.read();
14361474
}
1475+
1476+
@Override
1477+
public void read() {
1478+
readField("varkind");
1479+
if (_vardesc != null) {
1480+
_vardesc.setType(varkind.value == VARKIND.VAR_CONST ? "lpvarValue" : "oInst");
1481+
}
1482+
super.read();
1483+
}
14371484
}
14381485

14391486
@FieldOrder({"tdesc", "_elemdesc"})
@@ -1654,14 +1701,10 @@ public static class _TYPEDESC extends Union {
16541701
public HREFTYPE hreftype;
16551702

16561703
public _TYPEDESC() {
1657-
this.setType("hreftype");
1658-
this.read();
16591704
}
16601705

16611706
public _TYPEDESC(Pointer pointer) {
16621707
super(pointer);
1663-
this.setType("hreftype");
1664-
this.read();
16651708
}
16661709

16671710
public TYPEDESC.ByReference getLptdesc() {
@@ -1687,18 +1730,44 @@ public HREFTYPE getHreftype() {
16871730
public VARTYPE vt;
16881731

16891732
public TYPEDESC() {
1690-
this.read();
16911733
}
16921734

16931735
public TYPEDESC(Pointer pointer) {
16941736
super(pointer);
1695-
this.read();
16961737
}
16971738

16981739
public TYPEDESC(_TYPEDESC _typedesc, VARTYPE vt) {
16991740
this._typedesc = _typedesc;
17001741
this.vt = vt;
17011742
}
1743+
1744+
@Override
1745+
public void read() {
1746+
Pointer p = getPointer();
1747+
if (p == null) {
1748+
return;
1749+
}
1750+
1751+
// Read vt first to determine the correct union type
1752+
readField("vt");
1753+
1754+
// Set the union type based on vt discriminator
1755+
switch (vt.intValue()) {
1756+
case Variant.VT_PTR:
1757+
case Variant.VT_SAFEARRAY:
1758+
_typedesc.setType("lptdesc");
1759+
break;
1760+
case Variant.VT_CARRAY:
1761+
_typedesc.setType("lpadesc");
1762+
break;
1763+
case Variant.VT_USERDEFINED:
1764+
default:
1765+
_typedesc.setType("hreftype");
1766+
break;
1767+
}
1768+
1769+
super.read();
1770+
}
17021771
}
17031772

17041773
@FieldOrder({"dwReserved", "wIDLFlags"})

0 commit comments

Comments
 (0)