Skip to content

Uncompilable tests with JDK 17 for read Files with set static field of jdk.internal.misc.VM #2062

Open
@alisevych

Description

@alisevych

Description

Tests generated for read Files with JDK 17 are uncompilable.
Class "jdk.internal.misc.VM" is accessed to set static field "initLevel"
The class is not found in JDK 17.

To Reproduce

  1. Run IntelliJ Idea Ultimate 2022.3.3
  2. Install plugin IU built from unit-test-bot/rc2023.3 branch
  3. Open a project with JDK 17
  4. Add the following code
import java.io.File;
import java.nio.file.Files;

public class SecurityCheck {
    public int read(File path) throws IOException {
        byte[] bytes = Files.readAllBytes(path.toPath());
        return bytes.length;
    }
}
  1. Generate tests with Do not mock

Expected behavior

Generated test are supposed to be compiled with project JDK.
Unneeded reflection should be avoided.

Actual behavior

There are tests Class "jdk.internal.misc.VM" is accessed to set static field "initLevel"

Visual proofs (screenshots, logs, images)

The following tests are generated:

 ///region SYMBOLIC EXECUTION: ERROR SUITE for method read(java.io.File)

    /**
     * @utbot.classUnderTest {@link SecurityCheck}
     * @utbot.methodUnderTest {@link SecurityCheck#read(File)}
     * @utbot.invokes {@link File#toPath()}
     * @utbot.throwsException {@link NullPointerException} in: byte[] bytes = Files.readAllBytes(path.toPath());
     */
    @Test(description = "read: bytes = Files.readAllBytes(path.toPath()) : True -> ThrowNullPointerException")
    public void testRead_FileToPath() throws IOException {
        SecurityCheck securityCheck = new SecurityCheck();
        
        /* This test fails because method [org.example.SecurityCheck.read] produces [java.lang.NullPointerException]
            org.example.SecurityCheck.read(SecurityCheck.java:19) */
        securityCheck.read(null);
    }

    /**
     * @utbot.classUnderTest {@link SecurityCheck}
     * @utbot.methodUnderTest {@link SecurityCheck#read(File)}
     * @utbot.invokes {@link File#toPath()}
     * @utbot.throwsException {@link NullPointerException} in: byte[] bytes = Files.readAllBytes(path.toPath());
     */
    @Test(description = "read: bytes = Files.readAllBytes(path.toPath()) : True -> ThrowNullPointerException")
    public void testRead_FileToPath_1() throws Exception {
        Class vMClazz = Class.forName("jdk.internal.misc.VM");
        int prevInitLevel = ((Integer) getStaticFieldValue(vMClazz, "initLevel"));
        try {
            setStaticField(vMClazz, "initLevel", 2);
            SecurityCheck securityCheck = new SecurityCheck();
            File path = ((File) createInstance("java.io.File"));
            setField(path, "java.io.File", "path", null);
            setField(path, "java.io.File", "filePath", null);
            
            /* This test fails because method [org.example.SecurityCheck.read] produces [java.lang.NullPointerException]
                java.base/java.util.Objects.requireNonNull(Objects.java:208)
                java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:216)
                java.base/java.io.File.toPath(File.java:2387)
                org.example.SecurityCheck.read(SecurityCheck.java:19) */
            securityCheck.read(path);
        } finally {
            setStaticField(jdk.internal.misc.VM.class, "initLevel", prevInitLevel);
        }
    }
    ///endregion

    ///region OTHER: SECURITY for method read(java.io.File)

    @Test(enabled = false, description = "Disabled due to sandbox")
    public void testRead1() throws Exception {
        Class vMClazz = Class.forName("jdk.internal.misc.VM");
        int prevInitLevel = ((Integer) getStaticFieldValue(vMClazz, "initLevel"));
        try {
            setStaticField(vMClazz, "initLevel", 2);
            SecurityCheck securityCheck = new SecurityCheck();
            File path = ((File) createInstance("java.io.File"));
            String string = "C:\\";
            setField(path, "java.io.File", "path", string);
            setField(path, "java.io.File", "filePath", null);
            
            /* This test fails because method [org.example.SecurityCheck.read] produces [java.security.AccessControlException: access denied ("java.io.FilePermission" "C:\" "read")]
                java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:485)
                java.base/java.security.AccessController.checkPermission(AccessController.java:1068)
                java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:416)
                java.base/java.lang.SecurityManager.checkRead(SecurityManager.java:756)
                java.base/sun.nio.fs.WindowsChannelFactory.open(WindowsChannelFactory.java:300)
                java.base/sun.nio.fs.WindowsChannelFactory.newFileChannel(WindowsChannelFactory.java:168)
                java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:231)
                java.base/java.nio.file.Files.newByteChannel(Files.java:380)
                java.base/java.nio.file.Files.newByteChannel(Files.java:432)
                java.base/java.nio.file.Files.readAllBytes(Files.java:3288)
                org.example.SecurityCheck.read(SecurityCheck.java:19) */
        } finally {
            setStaticField(jdk.internal.misc.VM.class, "initLevel", prevInitLevel);
        }
    }
    ///endregion

    ///region OTHER: ERROR SUITE for method read(java.io.File)

    @Test
    public void testRead2() throws Exception {
        Class vMClazz = Class.forName("jdk.internal.misc.VM");
        int prevInitLevel = ((Integer) getStaticFieldValue(vMClazz, "initLevel"));
        try {
            setStaticField(vMClazz, "initLevel", 2);
            SecurityCheck securityCheck = new SecurityCheck();
            File path = ((File) createInstance("java.io.File"));
            String string = "c:\u0000";
            setField(path, "java.io.File", "path", string);
            setField(path, "java.io.File", "filePath", null);
            
            /* This test fails because method [org.example.SecurityCheck.read] produces [java.nio.file.InvalidPathException: Illegal char < > at index 2: c: ]
                java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
                java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
                java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
                java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
                java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
                java.base/java.io.File.toPath(File.java:2387)
                org.example.SecurityCheck.read(SecurityCheck.java:19) */
            securityCheck.read(path);
        } finally {
            setStaticField(jdk.internal.misc.VM.class, "initLevel", prevInitLevel);
        }
    }
    ///endregion

Environment

Windows 10 Pro
IntelliJ IDEA Ultimate 2022.3.3
Maven
JDK 17 (Amazon COrretto)

Additional context

Without - #2061
the following tests were generated:

public void testRead_FileToPath() throws Exception {
        org.mockito.MockedStatic mockedStatic = null;
        try {
            mockedStatic = mockStatic(java.nio.file.Files.class);
            byte[] byteArray = {(byte) 0};
            (mockedStatic.when(() -> java.nio.file.Files.readAllBytes(any()))).thenReturn(byteArray);
            SecurityCheck securityCheck = new SecurityCheck();
            File path = ((File) createInstance("java.io.File"));
            Path pathMock = mock(Path.class);
            setField(path, "java.io.File", "filePath", pathMock);

            int actual = securityCheck.read(path);

            assertEquals(1, actual);
        } finally {
            mockedStatic.close();
        }
    }

Metadata

Metadata

Labels

comp-symbolic-engineIssue is related to the symbolic execution enginectg-bugIssue is a bug

Type

No type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions