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 |