Skip to content

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

Open

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();
        }
    }

Activity

  1. added this to the 2023.3 Release milestone on Mar 28, 2023
  2. removed this from the 2023.3 Release milestone on Mar 29, 2023
  3. tyuldashev commented on Mar 29, 2023

    @tyuldashev
    Collaborator

    Release 2023.3 build where problem is reproducible - https://github.com/UnitTestBot/UTBotJava/actions/runs/4544820135

  4. alisevych commented on Mar 29, 2023

    @alisevych
    MemberAuthor

    Reproducing on this plugin built from main:
    https://github.com/UnitTestBot/UTBotJava/actions/runs/4544669446

  5. moved this from Todo to In Progress in UTBot Javaon Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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