File:lines() never ends if the file size is larger than 1024 bytes.

Issue #1377 resolved
AuahDark
created an issue

Consider this code

local file = love.filesystem.newFile("beatmap.txt", "r")
for line in file:lines() do
    -- Do something
end

If the file is somehow bigger than 1024 bytes (and possibly with some different condition), the loop never ends, thus cause infinite loop. I think 1797945 is causing this. If I remember, love.filesystem.lines uses same implementation so I think that one is also affected by this.

I attached test file which caused this problem.

Comments (8)

  1. Bart van Strien

    I've been debugging and it looks like the code that checks if it needs to seek is a bit.. trigger-happy. This doesn't affect love.filesystem.lines at all, and it's not meant to affect closed files but it does. As for open files, it's kind of working as intended.

  2. AuahDark reporter

    Not sure what you mean it affects closed file, but the file is actually open.

    local f = assert(love.filesystem.newFile(this.beatmap_filename, "r"))
    -- ... some other code unrelated to the issue ... --
    -- Load it line by line
    for line in f:lines() do
        if #line > 0 then
            readed_notes_data[#readed_notes_data + 1] = line
        end
    end
    

    After checking the output of File:lines() with interpreter, I got these (still using same exact beatmap.txt file)

    > a = love.filesystem.newFile("beatmap.txt", "r")
    > b = a:lines()
    > b()
    10.45235/L4/False/False/True/0/9.585295/False/0.3919998,1.203201,1.510398,True;
    > b() -- Notice the output of this one
    10.45235/R4/False/False/True/0/9.932116/False/1.313598,0,0,True;
    > b()
    11.3194/L3/False/False/False/0/0/False/1.288,0,0.9983994,True;
    > b()
    3.34252/L3/False/False/False/0/0/False/1.288,0,0.9983994,True;
    > b()
    93.68934/R2/True/False/False/0/0/True/1.001601,1.001601,1.001599,True;
    > b()
    100.6258/L1/True/False/False/0/0/True/0.4175994,0.4096016,1.3056,True;
    > b()
    95.59686/R4/False/False/True/0/95.42345/False/1.313598,0,0,True;
    > b()
    96.81073/R2/True/True/False/96.98414/0/True/1.001601,1.001601,1.001599,True;
    > b()
    96.81073/L4/True/False/False/0/0/False/0.3919998,1.203201,1.510398,True;
    > b()
    97.50437/R4/True/True/False/97.67778/0/False/1.313598,0,0,True;
    > b()
    100.6258/R1/True/False/False/0/0/False/1.5184,0.8192012,0,True;
    > b()
    24.15177/R2/False/False/False/0/0/False/1.001601,1.001601,1.001599,True;
    > b()
    11.66622/L1/False/False/False/0/11.28825/False/0.4175994,0.4096016,1.3056,True;
    > b()
    11.14599/L4/False/False/False/0/11.12575/False/0.3919998,1.203201,1.510398,True;
    > b()
    23.97836/C/False/Fal10.45235/L4/False/False/True/0/9.585295/False/0.3919998,1.203201,1.510398,True;
    > b() -- The output is same as previous one few lines earlier
    10.45235/R4/False/False/True/0/9.932116/False/1.313598,0,0,True;
    
  3. Bart van Strien

    I'll look at it looping again, but the lines iterator for open files is a bit of a.. bad case. Because to act kind of reasonably with surrounding code it needs to seek constantly. I found out while looking into this that it accidentally triggered for closed files (as in File objects) too and have fixed that.

  4. Log in to comment