diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-13 22:53:43 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-18 11:24:07 -0300 |
| commit | b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7 (patch) | |
| tree | e09137afe8a7670adec497adcae39266644a3566 | |
| parent | d93459dcf4250dd025a1baa802a6243516b7395d (diff) | |
| download | luarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.tar.gz luarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.tar.bz2 luarocks-b2ac4f3a9b780f6bde413dc1b5463654bb8be8d7.zip | |
tar: compatibility improvement tweaks
| -rw-r--r-- | src/luarocks/tools/tar.lua | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua index 9ff8d04a..7828c517 100644 --- a/src/luarocks/tools/tar.lua +++ b/src/luarocks/tools/tar.lua | |||
| @@ -28,12 +28,14 @@ end | |||
| 28 | local function octal_to_number(octal) | 28 | local function octal_to_number(octal) |
| 29 | local exp = 0 | 29 | local exp = 0 |
| 30 | local number = 0 | 30 | local number = 0 |
| 31 | octal = octal:gsub("%s", "") | ||
| 31 | for i = #octal,1,-1 do | 32 | for i = #octal,1,-1 do |
| 32 | local digit = tonumber(octal:sub(i,i)) | 33 | local digit = tonumber(octal:sub(i,i)) |
| 33 | if digit then | 34 | if not digit then |
| 34 | number = number + (digit * 8^exp) | 35 | break |
| 35 | exp = exp + 1 | ||
| 36 | end | 36 | end |
| 37 | number = number + (digit * 8^exp) | ||
| 38 | exp = exp + 1 | ||
| 37 | end | 39 | end |
| 38 | return number | 40 | return number |
| 39 | end | 41 | end |
| @@ -41,10 +43,12 @@ end | |||
| 41 | local function checksum_header(block) | 43 | local function checksum_header(block) |
| 42 | local sum = 256 | 44 | local sum = 256 |
| 43 | for i = 1,148 do | 45 | for i = 1,148 do |
| 44 | sum = sum + block:byte(i) | 46 | local b = block:byte(i) or 0 |
| 47 | sum = sum + b | ||
| 45 | end | 48 | end |
| 46 | for i = 157,500 do | 49 | for i = 157,500 do |
| 47 | sum = sum + block:byte(i) | 50 | local b = block:byte(i) or 0 |
| 51 | sum = sum + b | ||
| 48 | end | 52 | end |
| 49 | return sum | 53 | return sum |
| 50 | end | 54 | end |
| @@ -71,12 +75,12 @@ local function read_header_block(block) | |||
| 71 | header.devmajor = octal_to_number(nullterm(block:sub(330,337))) | 75 | header.devmajor = octal_to_number(nullterm(block:sub(330,337))) |
| 72 | header.devminor = octal_to_number(nullterm(block:sub(338,345))) | 76 | header.devminor = octal_to_number(nullterm(block:sub(338,345))) |
| 73 | header.prefix = block:sub(346,500) | 77 | header.prefix = block:sub(346,500) |
| 74 | if header.magic ~= "ustar " and header.magic ~= "ustar\0" then | 78 | -- if header.magic ~= "ustar " and header.magic ~= "ustar\0" then |
| 75 | return false, "Invalid header magic "..header.magic | 79 | -- return false, ("Invalid header magic %6x"):format(bestring_to_number(header.magic)) |
| 76 | end | 80 | -- end |
| 77 | if header.version ~= "00" and header.version ~= " \0" then | 81 | -- if header.version ~= "00" and header.version ~= " \0" then |
| 78 | return false, "Unknown version "..header.version | 82 | -- return false, "Unknown version "..header.version |
| 79 | end | 83 | -- end |
| 80 | if not checksum_header(block) == header.chksum then | 84 | if not checksum_header(block) == header.chksum then |
| 81 | return false, "Failed header checksum" | 85 | return false, "Failed header checksum" |
| 82 | end | 86 | end |
| @@ -87,20 +91,26 @@ function tar.untar(filename, destdir) | |||
| 87 | assert(type(filename) == "string") | 91 | assert(type(filename) == "string") |
| 88 | assert(type(destdir) == "string") | 92 | assert(type(destdir) == "string") |
| 89 | 93 | ||
| 90 | local tar_handle = io.open(filename, "r") | 94 | local tar_handle = io.open(filename, "rb") |
| 91 | if not tar_handle then return nil, "Error opening file "..filename end | 95 | if not tar_handle then return nil, "Error opening file "..filename end |
| 92 | 96 | ||
| 93 | local long_name, long_link_name | 97 | local long_name, long_link_name |
| 98 | local ok, err | ||
| 94 | while true do | 99 | while true do |
| 95 | local block | 100 | local block |
| 96 | repeat | 101 | repeat |
| 97 | block = tar_handle:read(blocksize) | 102 | block = tar_handle:read(blocksize) |
| 98 | until (not block) or checksum_header(block) > 256 | 103 | until (not block) or checksum_header(block) > 256 |
| 99 | if not block then break end | 104 | if not block then break end |
| 100 | local header, err = read_header_block(block) | 105 | if #block < blocksize then |
| 106 | ok, err = nil, "Invalid block size -- corrupted file?" | ||
| 107 | break | ||
| 108 | end | ||
| 109 | local header | ||
| 110 | header, err = read_header_block(block) | ||
| 101 | if not header then | 111 | if not header then |
| 102 | util.printerr(err) | 112 | ok = false |
| 103 | return nil, err | 113 | break |
| 104 | end | 114 | end |
| 105 | 115 | ||
| 106 | local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size) | 116 | local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size) |
| @@ -120,22 +130,33 @@ function tar.untar(filename, destdir) | |||
| 120 | end | 130 | end |
| 121 | end | 131 | end |
| 122 | local pathname = dir.path(destdir, header.name) | 132 | local pathname = dir.path(destdir, header.name) |
| 133 | pathname = fs.absolute_name(pathname) | ||
| 123 | if header.typeflag == "directory" then | 134 | if header.typeflag == "directory" then |
| 124 | local ok, err = fs.make_dir(pathname) | 135 | ok, err = fs.make_dir(pathname) |
| 125 | if not ok then return nil, err end | 136 | if not ok then |
| 137 | break | ||
| 138 | end | ||
| 126 | elseif header.typeflag == "file" then | 139 | elseif header.typeflag == "file" then |
| 127 | local dirname = dir.dir_name(pathname) | 140 | local dirname = dir.dir_name(pathname) |
| 128 | if dirname ~= "" then | 141 | if dirname ~= "" then |
| 129 | local ok, err = fs.make_dir(dirname) | 142 | ok, err = fs.make_dir(dirname) |
| 130 | if not ok then return nil, err end | 143 | if not ok then |
| 144 | break | ||
| 145 | end | ||
| 146 | end | ||
| 147 | local file_handle | ||
| 148 | file_handle, err = io.open(pathname, "wb") | ||
| 149 | if not file_handle then | ||
| 150 | ok = nil | ||
| 151 | break | ||
| 131 | end | 152 | end |
| 132 | local file_handle = io.open(pathname, "wb") | ||
| 133 | file_handle:write(file_data) | 153 | file_handle:write(file_data) |
| 134 | file_handle:close() | 154 | file_handle:close() |
| 135 | fs.set_time(pathname, header.mtime) | 155 | fs.set_time(pathname, header.mtime) |
| 136 | -- TODO Use fs.set_permissions | 156 | if header.mode:match("[75]") then |
| 137 | if fs.chmod then | 157 | fs.set_permissions(pathname, "exec", "all") |
| 138 | fs.chmod(pathname, header.mode) | 158 | else |
| 159 | fs.set_permissions(pathname, "read", "all") | ||
| 139 | end | 160 | end |
| 140 | end | 161 | end |
| 141 | --[[ | 162 | --[[ |
| @@ -146,7 +167,7 @@ function tar.untar(filename, destdir) | |||
| 146 | --]] | 167 | --]] |
| 147 | end | 168 | end |
| 148 | tar_handle:close() | 169 | tar_handle:close() |
| 149 | return true | 170 | return ok, err |
| 150 | end | 171 | end |
| 151 | 172 | ||
| 152 | return tar | 173 | return tar |
