A PR with a test for FileChannels.contentEquals is available here: https://github.com/apache/commons-io/pull/509
On Mon, Nov 6, 2023 at 5:37 PM Elliotte Rusty Harold <elh...@ibiblio.org> wrote: > Can you turn this into a PR against HEAD that adds a unit test that > fails? That would be fairly conclusive proof. It's better if you don't > send a fix, at least at first. That makes it easier to verify the bug. > > On Mon, Nov 6, 2023 at 10:04 AM Stephan Markwalder > <step...@markwalder.net> wrote: > > > > Hi, > > > > I think I have found a bug in the new FileChannels.contentEquals(...) in > > Commons IO 2.15.0 which then affects > RandomAccessFiles.contentEquals(...), > > PathUtils.fileContentEquals(...), FileUtils.contentEquals(...), and maybe > > more methods. But before opening an issue in ASF JIRA, I would like to > > present my findings here. > > > > My current working hypothesis: > > If two files have the exact same size and the exact same content in the > > last 8192 bytes (value of IOUtils.DEFAULT_BUFFER_SIZE), then all of the > > above methods will return true, even if the content of the files is > > different before the last 8192 bytes. > > > > Here is some example code: > > > > // create two files with same size but different content > > // (3 different bytes followed by 8192 equal bytes) > > File file1 = new File("file1.txt"); > > File file2 = new File("file2.txt"); > > > > String sameContent = StringUtils.repeat("x", 8192); > > > > String content1 = "ABC" + sameContent; > > String content2 = "XYZ" + sameContent; > > FileUtils.writeStringToFile(file1, content1, StandardCharsets.US_ASCII); > > FileUtils.writeStringToFile(file2, content2, StandardCharsets.US_ASCII); > > > > > > // compare files > > boolean equals = FileUtils.contentEquals(file1, file2); > > System.out.println(equals); > > > > > > I would expect this to print "false" as the first 3 bytes are different, > > but the code prints "true". I tested with Eclipse Temurin 11.0.1, 17.0.7, > > and 21.0.1, all on MacOS. > > > > I'm not an expert on FileChannels, but I think the problem has something > to > > do with the call to method FileChannel.read(ByteBuffer) in > > org.apache.commons.io.channels.FileChannels. Before the call to this > > method, the buffer is at position 0. After this call, the buffer is at > > position 8192. With a limit of 8192, this means that there are 0 > remaining > > bytes to be compared in ByteBuffer.equals(...). Maybe there should be a > > call to ByteBuffer.rewind() or ByteBuffer.position(0) after the read so > > that the position is set back to 0 before comparing the content of the > > buffers? But as stated before, I'm not an expert on this topic. I'm also > > not sure whether my hypothesis is 100% accurate. But this has been my > > conclusion after some experiments. > > > > Best regards, > > Ste > > > > -- > Elliotte Rusty Harold > elh...@ibiblio.org > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > >