Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug in VARDESC (#1644) #1645

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

stmuecke
Copy link

No description provided.

Copy link
Contributor

@dbwiddis dbwiddis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick fix. Can you add a change log entry please?

(Also Checkstyle doesn't like your indentation; is it tabs? :) )

@stmuecke
Copy link
Author

I have amended the commit with a change log entry and with spaces instead of tabs :)

@stmuecke stmuecke force-pushed the master branch 2 times, most recently from 7206769 to bfc7610 Compare December 15, 2024 06:06
@stmuecke stmuecke requested a review from dbwiddis December 15, 2024 06:08
@stmuecke
Copy link
Author

Is just discovered the same problem in TYPEDESC. Do you want me to update this pull request or open another one?

@matthiasblaesing
Copy link
Member

@stmuecke go ahead and update this PR.

@stmuecke
Copy link
Author

Should I force-push it as previously, or what's the proper way to do it? (Sorry, I am new to collaboration on GitHub.)

@matthiasblaesing
Copy link
Member

@stmuecke to my experience there is no general rule. But given the size of the changes I say, just update in place.

@stmuecke stmuecke force-pushed the master branch 2 times, most recently from 2c7161a to 933fc64 Compare December 15, 2024 19:55
@dbwiddis
Copy link
Contributor

Should I force-push it as previously, or what's the proper way to do it? (Sorry, I am new to collaboration on GitHub.)

Most GitHub repos use "squash and merge" to make PRs a single commit anyway. Squashing it yourself gives you a bit better control over the commit messages, although I also think most maintainers are happy enough with any contribution they're not going to be overly picky about it.

Separate commits are useful in the review phase when there are more complex changes but when the changes are confined to a single class per "commit" there's not really any need.

Copy link
Member

@matthiasblaesing matthiasblaesing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minimal nitpick.

case Variant.VT_CARRAY :
_typedesc.setType("lpadesc");
break;
case Variant.VT_USERDEFINED :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be the default? the hreftype is safe to read in any situation as it is just a plain DWORD and thus won't cause further reads. For the VARDESC this is implicitly done and I think it would be right here too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be safe to read, but it sets the union's type to a value that doesn't apply. I consider this to be incorrect. But maybe my idea of unions is wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem I see is, that if you don't set the type, it might be already be set to one of the other types, which would result in an invalid read. It is the responsibility of the calling code to only read the value of the union if it makes sense, but we need to protect from invalid reads.

@matthiasblaesing
Copy link
Member

When you update, would you mind rebasing your change onto current master? The merge of #1642 created a merge conflict as both changes touch the same region in CHANGES.md.

@stmuecke
Copy link
Author

Default case added and rebased onto master.

@matthiasblaesing
Copy link
Member

Could you please check this error reported by appveyor (runs Windows Unittests):

    [junit] Testsuite: com.sun.jna.platform.win32.COM.TypeLibUtilTest
    [junit] Tests run: 4, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.078 sec
    [junit] 
    [junit] Testcase: testGetTypeInfo(com.sun.jna.platform.win32.COM.TypeLibUtilTest):	Caused an ERROR
    [junit] Invalid memory access
    [junit] java.lang.Error: Invalid memory access
    [junit] 	at com.sun.jna.Native.getShort(Native Method)
    [junit] 	at com.sun.jna.Pointer.getShort(Pointer.java:568)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:378)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:647)
    [junit] 	at com.sun.jna.platform.win32.OaIdl$TYPEDESC.read(OaIdl.java:1701)
    [junit] 	at com.sun.jna.Structure.autoRead(Structure.java:2335)
    [junit] 	at com.sun.jna.Structure.conditionalAutoRead(Structure.java:583)
    [junit] 	at com.sun.jna.Structure.updateStructureByReference(Structure.java:711)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:367)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Union.readField(Union.java:223)
    [junit] 	at com.sun.jna.Structure.read(Structure.java:612)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:370)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Structure.read(Structure.java:612)
    [junit] 	at com.sun.jna.platform.win32.OaIdl$TYPEDESC.read(OaIdl.java:1715)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:370)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Structure.read(Structure.java:612)
    [junit] 	at com.sun.jna.Pointer.readArray(Pointer.java:504)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:450)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Structure.read(Structure.java:612)
    [junit] 	at com.sun.jna.Structure.autoRead(Structure.java:2335)
    [junit] 	at com.sun.jna.Structure.conditionalAutoRead(Structure.java:583)
    [junit] 	at com.sun.jna.Structure.updateStructureByReference(Structure.java:711)
    [junit] 	at com.sun.jna.Pointer.getValue(Pointer.java:367)
    [junit] 	at com.sun.jna.Structure.readField(Structure.java:753)
    [junit] 	at com.sun.jna.Structure.read(Structure.java:612)
    [junit] 	at com.sun.jna.platform.win32.OaIdl$FUNCDESC.<init>(OaIdl.java:1318)
    [junit] 	at com.sun.jna.platform.win32.COM.TypeInfoUtil.getFuncDesc(TypeInfoUtil.java:113)
    [junit] 	at com.sun.jna.platform.win32.COM.TypeLibUtilTest.testGetTypeInfo(TypeLibUtilTest.java:77)
    [junit] 
    [junit] 
    [junit] Test com.sun.jna.platform.win32.COM.TypeLibUtilTest FAILED
    [junit] Testsuite: com.sun.jna.platform.win32.COM.WbemcliTest
    [junit] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.596 sec
    [junit] 
    [junit] Testsuite: com.sun.jna.platform.win32.COM.util.ComEventCallbacks2_Test
    [junit] Tests run: 3, Failures: 0, Errors: 0, Skipped: 3, Time elapsed: 0.578 sec

The error is reproducible locally.

@stmuecke
Copy link
Author

I can reproduce the error, but it is evasive. I have written a TypeLibDumper class which causes the same invalid memory access as the unit test, but only under certain circumstances. The invalid access happens at type index 21 (IShellFolderViewDual3), function index 16 (CurrentViewMode). When I skip functions 0-15, the invalid memory access doesn't happen. It also doesn't happen when I dump the whole typelib, only when I skip types 0 to 20. Thus, the bug should be somewhere else. I have currently no idea how to track it down. Any suggestions?

@stmuecke
Copy link
Author

Here's a minimal reproducible example:

public class InvalidMemoryAccessBug {
    public static void main(String[] args) {
        TypeLibUtil libUtil = new TypeLibUtil("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", 1, 0); // C:\Windows\SysWOW64\shell32.dll
        int typeIndex = 21;
        
        ITypeInfo typeInfo = libUtil.getTypeInfo(typeIndex);
        TypeInfoUtil util = new TypeInfoUtil(typeInfo);
        TYPEATTR attr = util.getTypeAttr();

        for (int i = 11; i < attr.cFuncs.intValue(); i++) {
            System.out.println("Function " + i);
            FUNCDESC func = util.getFuncDesc(i);
            TypeInfoDoc funcDoc = util.getDocumentation(func.memid);
            util.ReleaseFuncDesc(func);
        }
    }
}

The bug will not exhibit if one of the following changes is made:

  • Comment the getDocumentation line
  • Comment the ReleaseFuncDesc line
  • Change start value of i to one of [1, 2, 4, 5, 6, 7, 8, 12, 13, ..., 27]

@stmuecke
Copy link
Author

The error in the unit test can also be reproduced with JNA 5.15.0 and therefore has nothing to do with the changes in this PR. I suggest you accept and close this PR and issue #1644, and we open a new issue for the unit test error.

@dbwiddis
Copy link
Contributor

The error in the unit test can also be reproduced with JNA 5.15.0 and therefore has nothing to do with the changes in this PR. I suggest you accept and close this PR and issue #1644, and we open a new issue for the unit test error.

I concur. Will let @matthiasblaesing make the final determination

@matthiasblaesing
Copy link
Member

Where does this:

The error in the unit test can also be reproduced with JNA 5.15.0 and therefore has nothing to do with the changes in this PR

come from? I never saw errors in TypeLibUtilTest before and now I see them. The problems are not flaky, they are reproducible. i.e. I can run the unittest on master multiple times and get no error, but on this PR I get the error.

So merging, would break currently working code.

This does not mean, that I think this PR in itself introduces the issue but it changes the problem front.

@dbwiddis
Copy link
Contributor

I never saw errors in TypeLibUtilTest before and now I see them.

I agree we shouldn't merge code that breaks CI (even if it just "fixes" a problem that hid a bug elsewhere).

I missed that AppVeyor isn't included in the "checks" on this PR, which all passed and I didn't realize didn't include Windows. Do we know why that is? Also see #1596 which I had to visit to hunt down your appveyor runs.

As far as diagnosing a possible cause:

  • Seems it's only failing on VS2015 and not VS2019.
  • Stack trace points to this line reading FUNCDESC which has ELEMDESC as its penultimate field; that has a TYPEDESC as its first field, which contains a _TYPEDESC Union as its first element and VARTYPE as its second element; and it's failing on an attempted read of that second element (a USHORT).

@stmuecke
Copy link
Author

I have been trying to get closer to the root issue, and my impression so far is that something is going wrong on the native side. Using my typelib dumper, I compared the data I get with and without the error. There is a discrepancy in the data returned by GetFuncDesc even before the error occurs. When I start my dumping loop at type index 0, everything is okay. When I start at type index 20, the functions at indexes 11 and 15 contain different data in lprgelemdescParam. Then at index 16 there's the illegal access error. Where does the wrong data come from? Is there some code messing up the native data structures? My native-fu is currently not sufficient, but I am learning :) I will probably get more inventive and will try to surface the problem in other dlls.

Here's a snippet from the console output, with "BEFORE" and "AFTER" showing the raw memory backing the FUNCDESC structures. The hypens in the memory dumps represent padding bytes. (BTW, it would be nice to be able to access StructField; I used reflection to access the memory layout information.)

    Function 14:
    [...] // not shown here
AFTER:
Address: bcbbc8
07 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
20 BC BC 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 70 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 09 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --
    
    Function 15:
BEFORE:
Address: bcbbc8
08 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
20 BC BC 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 78 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 03 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --
        memid: 1610743816 (0x60020008)
        lprgscode: null
        lprgelemdescParam: [
            ELEMDESC {tdesc: #TYPEDESC {vt: VT_PTR, TYPEDESC {vt: VT_VARIANT } }, PARAMDESC {pparamdescex: null, wParamFlags: 1} }
        ]
        funckind: FUNC_DISPATCH
        invkind: INVOKE_PROPERTYGET
        callconv: CC_STDCALL
        cParams: 0
        cParamsOpt: 0
        oVft: 120
        cScodes: 0
        elemdescFunc: ELEMDESC {tdesc: TYPEDESC {vt: VT_I4 }, PARAMDESC {pparamdescex: null, wParamFlags: 0} }
        wFuncFlags: 0
        
        TypeInfoDoc:
            name: ViewOptions
            docString: Returns the view options for showing a folder.
            helpContext: 0
            helpFile: 
AFTER:
Address: bcbbc8
08 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
20 BC BC 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 78 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 03 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --

Here's the output when the error occurs shortly afterwards:

    Function 14:
    [...] // not shown here
AFTER:
Address: 866488
07 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
E0 64 86 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 70 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 09 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --

    Function 15:
BEFORE:
Address: 85c538
08 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
90 C5 85 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 78 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 03 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --
        memid: 1610743816 (0x60020008)
        lprgscode: null
        lprgelemdescParam: [
            ELEMDESC {tdesc: TYPEDESC {vt: VT_UINT }, PARAMDESC {pparamdescex: null, wParamFlags: 1} }
        ]
        funckind: FUNC_DISPATCH
        invkind: INVOKE_PROPERTYGET
        callconv: CC_STDCALL
        cParams: 0
        cParamsOpt: 0
        oVft: 120
        cScodes: 0
        elemdescFunc: ELEMDESC {tdesc: TYPEDESC {vt: VT_I4 }, PARAMDESC {pparamdescex: null, wParamFlags: 0} }
        wFuncFlags: 0
        
        TypeInfoDoc:
            name: ViewOptions
            docString: Returns the view options for showing a folder.
            helpContext: 0
            helpFile: 
AFTER:
Address: 85c538
08 00 02 60 -- -- -- -- 00 00 00 00 00 00 00 00
90 C5 85 00 00 00 00 00 04 00 00 00 02 00 00 00
04 00 00 00 00 00 00 00 78 00 00 00 -- -- -- --
00 00 00 00 -- -- -- -- 03 00 -- -- -- -- -- --
00 00 00 00 00 00 00 00 00 00 -- -- -- -- -- --
00 00 -- -- -- -- -- --

Notice how in the first snippet the pointer values for FUNCDESC are both bcbbc8 for Function 14 and 15 (from which I assume that the exact same memory is being reused after ReleaseFuncDesc), while in the second snippet the FUNCDESC pointers have different values, namely, 866488 and then 85c538.

In the first snippet the FUNCDESC contains 20 BC BC 00 00 00 00 00 for the params reference for both Function 14 and Function 15, while in the second snippet the reference changes from E0 64 86 00 00 00 00 00 to 90 C5 85 00 00 00 00 00 between Function 14 and 15.

In the first snippet we get a VT_PTR param while in the second we get a VT_UINT param. How can that be?

I'll continue to dig around. Any hints are appreciated.

@dbwiddis
Copy link
Contributor

Can you explain how this differing output is generated and what it means that the #TYPEDESC {vt: VT_PTR, part is missing in the second run?

- ELEMDESC {tdesc: #TYPEDESC {vt: VT_PTR, TYPEDESC {vt: VT_VARIANT } }
+ ELEMDESC {tdesc: TYPEDESC {vt: VT_UINT }

@stmuecke
Copy link
Author

stmuecke commented Dec 19, 2024

I just print out the information in the structures. For VT_UINT there is no more interesting information, while for VT_PTR the nested _TYPEDESC contains a reference to another TYPEDESC which is printed inline. Ignore the hashtag before TYPEDESC. This was only temporary to make things easier to find.

@stmuecke
Copy link
Author

@matthiasblaesing Please run the following snippet on unmodified JNA 5.15.0 and compare the results with master. See how much better it works with the fixes in place. Run it a few times on master. There are occasional totally random errors.

import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import com.sun.jna.platform.win32.OaIdl.FUNCDESC;
import com.sun.jna.platform.win32.OaIdl.TLIBATTR;
import com.sun.jna.platform.win32.OaIdl.TYPEATTR;
import com.sun.jna.platform.win32.OaIdl.VARDESC;
import com.sun.jna.platform.win32.COM.TypeInfoUtil;
import com.sun.jna.platform.win32.COM.TypeLibUtil;

public class RandomErrors {

    static Set<String> includedFilenames = new HashSet<>();

    public static void main(String[] args) {
        String[] filenames = {"accessibilitycpl.dll", "activeds.tlb", "adprovider.dll", "amcompat.tlb", "apds.dll", "AppIdPolicyEngineApi.dll",
                "atl.dll", "atl100.dll", "atl110.dll", "AuditPolicyGPInterop.dll", "azroles.dll", "bcdsrv.dll", "capiprovider.dll", "catsrvut.dll",
                "cdosys.dll", "certcli.dll", "certenc.dll", "CertEnroll.dll", "certmgr.dll", "cic.dll", "clbcatq.dll", "cngprovider.dll",
                "comrepl.dll", "comsnap.dll", "comsvcs.dll", "connect.dll", "correngine.dll", "cryptext.dll", "DefaultPrinterProvider.dll",
                "DevicePairing.dll", "DevicePairingProxy.dll", "DfsShlEx.dll", "DiagCpl.dll", "dmocx.dll", "DMRServer.dll", "dnshc.dll",
                "dot3dlg.dll", "dot3hc.dll", "dpapiprovider.dll", "dskquota.dll", "dtsh.dll", "dxtmsft.dll", "dxtrans.dll", "EditionUpgradeHelper.dll",
                "EditionUpgradeManagerObj.dll", "EhStorAPI.dll", "EhStorShell.dll", "es.dll", "eventcls.dll", "expsrv.dll", "findnetprinters.dll",
                "FirewallAPI.dll", "FirewallControlPanel.dll", "fphc.dll", "FXSCOM.dll", "FXSCOMEX.dll", "gpprefcl.dll", "Groupinghc.dll",
                "HelpPaneProxy.dll", "hnetcfg.dll", "iasads.dll", "iasdatastore.dll", "iashlpr.dll", "iasnap.dll", "iasrad.dll", "iassam.dll",
                "iassdo.dll", "iassvcs.dll", "icsvc.dll", "ieframe.dll", "iepeers.dll", "igdDiag.dll", "imapi2.dll", "imapi2fs.dll", "inetcomm.dll",
                "InkEd.dll", "InkObjCore.dll", "ipnathlp.dll", "JavaScriptCollectionAgent.dll", "jscript.dll", "L2SecHC.dll", "LocationApi.dll",
                "MbaeApi.dll", "mmcndmgr.dll", "msaatext.dll", "msdatsrc.tlb", "msdtcuiu.dll", "msdxm.tlb", "msfeeds.dll", "msftedit.dll", "mshtml.tlb",
                "mshtmled.dll", "msi.dll", "msjtes40.dll", "MsraLegacy.tlb", "MsRdpWebAccess.dll", "mssitlb.dll", "mssrch.dll", "mstscax.dll",
                "msvbvm60.dll", "MSVidCtl.dll", "mswmdm.dll", "msxml3.dll", "msxml4.dll", "msxml6.dll", "mycomput.dll", "NaturalLanguage6.dll",
                "ndfapi.dll", "ndishc.dll", "netcenter.dll", "netcorehc.dll", "netprofm.dll", "NetworkCollectionAgent.dll", "nlahc.dll", "odbcconf.dll",
                "officecsp.dll", "oleacc.dll", "oleprn.dll", "pla.dll", "PNPXAssoc.dll", "PNPXAssocPrx.dll", "Pnrphc.dll", "PortableDeviceApi.dll",
                "PortableDeviceClassExtension.dll", "PortableDeviceConnectApi.dll", "PortableDeviceTypes.dll", "PrintConfig.dll", "printui.dll",
                "prnntfy.dll", "provcore.dll", "psisdecd.dll", "pstorec.dll", "puiapi.dll", "puiobj.dll", "qedit.dll", "quartz.dll", "rasdiag.dll",
                "rasgcw.dll", "rdpcorets.dll", "rdpencom.dll", "RdpRelayTransport.dll", "rdpsharercom.dll", "rdpviewerax.dll", "RegCtrl.dll",
                "rendezvousSession.tlb", "riched20.dll", "RoamingSecurity.dll", "RotMgr.dll", "scripto.dll", "scrobj.dll", "scrrun.dll", "sdiageng.dll",
                "sdohlp.dll", "Sens.dll", "shdocvw.dll", "shell32.dll", "shgina.dll", "signdrv.dll", "simpdata.tlb", "SMBHelperClass.dll", "SmiEngine.dll",
                "sppcomapi.dll", "sppwmi.dll", "SRH.dll", "srm.dll", "stclient.dll", "stdole2.tlb", "stdole32.tlb", "swprv.dll", "SysFxUI.dll",
                "TabbtnEx.dll", "tapi3.dll", "taskschd.dll", "termmgr.dll", "TransportDSA.dll", "TSWorkspace.dll", "tvratings.dll", "ucmhc.dll",
                "UIAnimation.dll", "UIAutomationCore.dll", "uicom.dll", "upnp.dll", "usbmon.dll", "VAN.dll", "vbscript.dll", "WaaSMedicPS.dll",
                "wavemsp.dll", "WfHC.dll", "wiaaut.dll", "wiascanprofiles.dll", "win32spl.dll", "wincredprovider.dll", "windowslivelogin.dll",
                "winethc.dll", "winhttpcom.dll", "WinMsoIrmProtector.dll", "WinOpcIrmProtector.dll", "WinSATAPI.dll", "wisp.dll", "wkspbrokerAx.dll",
                "WLanConn.dll", "wlandlg.dll", "WLanHC.dll", "wlanpref.dll", "wlanui.dll", "wlidcli.dll", "wlidprov.dll", "wmdmlog.dll", "WMNetMgr.dll",
                "wmp.dll", "wmpdxm.dll", "wmpshell.dll", "WorkFoldersShell.dll", "workfolderssvc.dll", "WPDSp.dll", "wscapi.dll", "wshcon.dll",
                "wshext.dll", "WsmAuto.dll", "wuapi.dll", "wvc.dll", "WWanAPI.dll", "WWanHC.dll", "xwizards.dll", "xwreg.dll", "xwtpdui.dll", "xwtpw32.dll"};
        includedFilenames.addAll(Arrays.asList(filenames));
        processDir(new File("C:\\Windows\\System32"));
        processDir(new File("C:\\Windows\\SysWOW64"));
        System.out.println("Finished.");
    }

    protected static void processDir(File dir) {
        for (File file : dir.listFiles()) {
            if (includedFilenames.contains(file.getName())) {
                processFile(file);
            }
        }
    }

    protected static void processFile(File file) {
        try {
            System.out.println(file);
            TypeLibUtil libUtil = new TypeLibUtil(file.toString());

            // Lib attributes
            TLIBATTR libAttr = libUtil.getLibAttr();
            libUtil.ReleaseTLibAttr(libAttr);

            // Types
            int count = libUtil.getTypeInfoCount();
            System.out.println("Type count: " + count);
            for (int i = 0; i < count; i++) {
                TypeInfoUtil typeUtil = libUtil.getTypeInfoUtil(i);

                // Type attributes
                TYPEATTR typeAttr = typeUtil.getTypeAttr();
                typeUtil.ReleaseTypeAttr(typeAttr);

                // Functions
                for (int j = 0; j < typeAttr.cFuncs.intValue(); j++) {
                    FUNCDESC funcDesc = typeUtil.getFuncDesc(j);
                    typeUtil.ReleaseFuncDesc(funcDesc);
                }

                // Variables
                for (int j = 0; j < typeAttr.cVars.intValue(); j++) {
                    VARDESC varDesc = typeUtil.getVarDesc(j);
                    typeUtil.ReleaseVarDesc(varDesc);
                }
            }

            libUtil.getTypelib().Release();

        } catch (Throwable e) {
            e.printStackTrace(System.out);
        }
    }

}

@stmuecke
Copy link
Author

JNA 15.5.0 gives me 192 errors. JNA master plus fixes gives me 0 to 3 errors.

@matthiasblaesing
Copy link
Member

matthiasblaesing commented Dec 21, 2024

@stmuecke I get your point, the situation is improved for some situations. BUT it comes with a hefty price, because code that worked before now blows up. Consider the situation reversed: You are using JNA 5.15.0, your code works. No you upgrade to 5.16.0, now you get a segfault. What would you say?
It could be, that the code in the unittest is wrong, that would change the situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants