Skip to content

Commit

Permalink
fix: re-use file descriptor for jpeg check
Browse files Browse the repository at this point in the history
  • Loading branch information
3rd committed Feb 23, 2024
1 parent 2cb0a10 commit 402ff91
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions lua/image/utils/magic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,57 @@ local image_signatures = {
XML = "<?xml",
}

local function read_file_header(path, numBytes)
local file, err = io.open(path, "rb")
if not file then return nil, "Failed to open file: " .. err end
local content = file:read(numBytes)
file:close()
local function read_file_header(file, num_bytes)
if not file then return nil end
local current_pos = file:seek()
file:seek("set", 0)
local content = file:read(num_bytes)
file:seek("set", current_pos)
return content and { content:byte(1, #content) } or nil
end

local function has_jpeg_end_signature(path)
local file, _ = io.open(path, "rb")
local function has_jpeg_end_signature(file)
if not file then return false end
local size = file:seek("end")
if size < 2 then
file:close()
return false
end
if size < 2 then return false end
file:seek("set", size - 2)
local end_signature = file:read(2)
file:close()
return end_signature == "\xFF\xD9", nil
end

local function is_image(path)
local file, _ = io.open(path, "rb")
if not file then return false end

local max_bytes = 9
local header, err = read_file_header(path, max_bytes)
if not header then return false, err end
local header, _ = read_file_header(file, max_bytes)
if not header then
file:close()
return false
end

local is_image_flag = false
for _, signature in pairs(image_signatures) do
local bytes = { signature:byte(1, #signature) }
local match = true
for i = 1, #bytes do
if header[i] == bytes[i] then
if signature == image_signatures.JPEG then
if has_jpeg_end_signature(path) then return true, nil end
else
return true
end
if header[i] ~= bytes[i] then
match = false
break
end
end
if match then
if signature == image_signatures.JPEG then
is_image_flag = has_jpeg_end_signature(file)
else
is_image_flag = true
end
break
end
end

return false
file:close()
return is_image_flag
end

return {
Expand Down

0 comments on commit 402ff91

Please sign in to comment.