Skip to content

Race condition in nameWithoutExtension #677

@alex-aua

Description

@alex-aua

There is a race condition in nameWithoutExtension that may lead to the function sometimes returning the filename with its extension instead of the name without extension.

Details: we have observed an occasional flicker in one of our unit tests. The code under test is trying to find a "free" filename, using code like the following:

    val baseName    = file.nameWithoutExtension(includeAll = true)
    val extension   = file.extension(includeDot = true, includeAll = true).getOrElse("")
    val postfix     = s"_1"
    val adaptedName = s"$baseName$postfix$extension"

In the test we sometimes observe a flicker: given input file myfile.~df, instead of the expected file name myfile_1.~df the adaptedName would unexpectedly be myfile.~df_1.~df

Unfortunately, the issue was very hard to reproduce. Given that we rarely observe the issue, and that the code is basically just the above four lines, I now believe that the issue is a race in hasExtension:

  def hasExtension: Boolean =
    (isRegularFile || notExists) && name.contains(".")

If the file does not yet exist when isRegularFile is called, is then created, and thus exists when notExists is called, we will return false here. The call to file.extension, however, will correctly return the extension which will in turn lead to the unexpected adaptedName.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions