-
Notifications
You must be signed in to change notification settings - Fork 135
Race condition in nameWithoutExtension #677
Description
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.