Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8286160

(fs) Files.exists returns unexpected results with C:\pagefile.sys because it's not readable

    XMLWordPrintable

Details

    • b01
    • x86_64
    • windows
    • Verified

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Windows any, Java any (bug is present ever since `Files.exists()` was added)

      A DESCRIPTION OF THE PROBLEM :
      `Files.exists()`, contrary to what documentation says, verifies that file is readable instead of verifying that file exists. Furthermore, in order to verify that, it actually opens file for reading (and immediately closes it).

      The first problem is seen with files that exist but are not readable (due to security or being opened exclusively)
      ----
      In this case, the following results are observed:
         Files.exists() = false
         File.exists() = true

      This is completely unexpected, and documentation doesn't explain this danger.

      For example, on Windows, try with `C:\pagefile.sys`. While this file might sounds a bit exotic, it's just a simplest example. Files that are opened with exclusive access, or that are not accessible to current user, are rather common. I anticipate that on Linux, the same will happen when trying with `/etc/passwd`.

      The second problem is with antivirus
      ----
      By opening the file for read access, JDK triggers the antivirus to check the file.
      In my case, checking timings for checking every file in a local git installation are:
      Files.exists() = 45.2 sec
      File.exists() = 0.8 sec

      Discussion
      ----
      The problem occurs because `Files.exists()` and `File.exists()` are completely different implementations.

      `File.exists()`, at least on Windows, eventually arrives to native `getFinalAttributes()`, which correctly calls `GetFileAttributesExW()`.

      `Files.exists()` however has two paths.
      When links are NOT followed, it eventually arrives to `WindowsFileAttributeViews.get()` and once again calls the good `GetFileAttributesExW()`.
      However, when links are followed (and this is the default!), it goes to `checkAccess()`, with all the problems described above.

      Possible fixes
      ----
      I understand that `Files.exists()` should always only check for file's presence and never for its readability. That is, to be more in line with what is done in `File.exists()`, which even seems to have code to handle symlinks when needed.

      While investigating, I found other people puzzled by this
      ----
      https://stackoverflow.com/questions/57282130
      https://stackoverflow.com/questions/30520179
      https://stackoverflow.com/questions/35087699

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      true, true
      ACTUAL -
      false, true

      ---------- BEGIN SOURCE ----------
      Path path = Paths.get("C:\\pagefile.sys");
      System.out.println("Files.exists() = " + Files.exists(path));
      System.out.println("File.exists() = " + path.toFile().exists());
      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              bpb Brian Burkhalter
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: