1 |
From 706d73ef3dae4c63db8351990387140d308b243e Mon Sep 17 00:00:00 2001 |
2 |
From: Aric Belsito <lluixhi@×××××.com> |
3 |
Date: Sat, 23 Apr 2016 20:26:39 -0700 |
4 |
Subject: [PATCH] Add p7zip. |
5 |
MIME-Version: 1.0 |
6 |
Content-Type: text/plain; charset=UTF-8 |
7 |
Content-Transfer-Encoding: 8bit |
8 |
|
9 |
The patch used to fix CVE-2015-1038 breaks compilation on musl: |
10 |
|
11 |
../../include_windows ../../UI/Console/ExtractCallbackConsole.cpp |
12 |
In file included from ../../UI/Console/../Common/ArchiveExtractCallback.h:9:0, |
13 |
from ../../UI/Console/ExtractCallbackConsole.h:11, |
14 |
from ../../UI/Console/ExtractCallbackConsole.cpp:5: |
15 |
../../../Windows/FileDir.h:100:3: error: ‘dev_t’ does not name a type |
16 |
dev_t _dev; |
17 |
^ |
18 |
../../../Windows/FileDir.h:101:3: error: ‘ino_t’ does not name a type |
19 |
ino_t _ino; |
20 |
^ |
21 |
../../../../makefile.rules:22: recipe for target 'ExtractCallbackConsole.o' |
22 |
failed |
23 |
--- |
24 |
app-arch/p7zip/Manifest | 2 + |
25 |
app-arch/p7zip/files/9.04-makefile.patch | 19 ++ |
26 |
app-arch/p7zip/files/p7zip-15.14.1-darwin.patch | 11 + |
27 |
.../p7zip/files/p7zip-9.20.1-CVE-2015-1038.patch | 315 +++++++++++++++++++++ |
28 |
app-arch/p7zip/files/p7zip-9.20.1-QA.patch | 17 ++ |
29 |
app-arch/p7zip/files/p7zip-9.20.1-execstack.patch | 24 ++ |
30 |
.../p7zip/files/p7zip-CVE-2015-1038-musl.patch | 14 + |
31 |
app-arch/p7zip/metadata.xml | 14 + |
32 |
app-arch/p7zip/p7zip-15.14.1.ebuild | 160 +++++++++++ |
33 |
app-arch/p7zip/p7zip-9.20.1-r5.ebuild | 156 ++++++++++ |
34 |
10 files changed, 732 insertions(+) |
35 |
create mode 100644 app-arch/p7zip/Manifest |
36 |
create mode 100644 app-arch/p7zip/files/9.04-makefile.patch |
37 |
create mode 100644 app-arch/p7zip/files/p7zip-15.14.1-darwin.patch |
38 |
create mode 100644 app-arch/p7zip/files/p7zip-9.20.1-CVE-2015-1038.patch |
39 |
create mode 100644 app-arch/p7zip/files/p7zip-9.20.1-QA.patch |
40 |
create mode 100644 app-arch/p7zip/files/p7zip-9.20.1-execstack.patch |
41 |
create mode 100644 app-arch/p7zip/files/p7zip-CVE-2015-1038-musl.patch |
42 |
create mode 100644 app-arch/p7zip/metadata.xml |
43 |
create mode 100644 app-arch/p7zip/p7zip-15.14.1.ebuild |
44 |
create mode 100644 app-arch/p7zip/p7zip-9.20.1-r5.ebuild |
45 |
|
46 |
diff --git a/app-arch/p7zip/Manifest b/app-arch/p7zip/Manifest |
47 |
new file mode 100644 |
48 |
index 0000000..c55f590 |
49 |
--- /dev/null |
50 |
+++ b/app-arch/p7zip/Manifest |
51 |
@@ -0,0 +1,2 @@ |
52 |
+DIST p7zip_15.14.1_src_all.tar.bz2 4147911 SHA256 699db4da3621904113e040703220abb1148dfef477b55305e2f14a4f1f8f25d4 SHA512 30d0ef47bd6938cdd5d9d80ec6e7aed972655686a43adb0ae34bb9856ec7cd5a68a05c580352021055cefd6eeceb134ff6402f93686ce46e57f9757798e76abd WHIRLPOOL ace6204d3ab08002b6d5657ae280e22b7e26cdfe0af8099024ad8562a68aa5097a8f09d9d49904a06b9a6942d30fbf3d7a3872661433dd4f76c33dea03ccfb6a |
53 |
+DIST p7zip_9.20.1_src_all.tar.bz2 3835235 SHA256 49557e7ffca08100f9fc687f4dfc5aea703ca207640c76d9dee7b66f03cb4782 SHA512 7bb8a276aaefc4a83364e45633c48527de44c6b1205344f3356db570582f30f81d82a94938c99a7ad193587b584cc1c03219c28249de40018bdaee6c3b2a022a WHIRLPOOL cb20f37d3f796931a9b330728aa7148afe98bbf8a49bb91bfd80e4667c16416206b23bf34298e9ec37825e8b43f92a5710f0cea1f974296d5c17aa2c7b0931f3 |
54 |
diff --git a/app-arch/p7zip/files/9.04-makefile.patch b/app-arch/p7zip/files/9.04-makefile.patch |
55 |
new file mode 100644 |
56 |
index 0000000..93a99cc |
57 |
--- /dev/null |
58 |
+++ b/app-arch/p7zip/files/9.04-makefile.patch |
59 |
@@ -0,0 +1,19 @@ |
60 |
+--- p7zip_9.04/CPP/7zip/Bundles/Format7zFree/makefile.orig 2010-01-04 13:58:54.527887746 +0100 |
61 |
++++ p7zip_9.04/CPP/7zip/Bundles/Format7zFree/makefile 2010-01-04 13:59:10.290868343 +0100 |
62 |
+@@ -247,8 +247,6 @@ |
63 |
+ MyAes.o \ |
64 |
+ Pbkdf2HmacSha1.o \ |
65 |
+ RandGen.o \ |
66 |
+- Rar20Crypto.o \ |
67 |
+- RarAes.o \ |
68 |
+ Sha1.o \ |
69 |
+ WzAes.o \ |
70 |
+ ZipCrypto.o \ |
71 |
+@@ -298,7 +296,6 @@ |
72 |
+ $(HFS_OBJS) \ |
73 |
+ $(ISO_OBJS) \ |
74 |
+ $(NSIS_OBJS) \ |
75 |
+- $(RAR_OBJS) \ |
76 |
+ $(TAR_OBJS) \ |
77 |
+ $(UDF_OBJS) \ |
78 |
+ $(WIM_OBJS) \ |
79 |
diff --git a/app-arch/p7zip/files/p7zip-15.14.1-darwin.patch b/app-arch/p7zip/files/p7zip-15.14.1-darwin.patch |
80 |
new file mode 100644 |
81 |
index 0000000..e7f40f5 |
82 |
--- /dev/null |
83 |
+++ b/app-arch/p7zip/files/p7zip-15.14.1-darwin.patch |
84 |
@@ -0,0 +1,11 @@ |
85 |
+--- p7zip_15.14.1/CPP/myWindows/StdAfx.h |
86 |
++++ p7zip_15.14.1/CPP/myWindows/StdAfx.h |
87 |
+@@ -32,7 +32,7 @@ |
88 |
+ #include <errno.h> |
89 |
+ #include <math.h> |
90 |
+ |
91 |
+-#ifdef __NETWARE__ |
92 |
++#if defined(__NETWARE__) || defined(__MACH__) |
93 |
+ #include <sys/types.h> |
94 |
+ #endif |
95 |
+ |
96 |
diff --git a/app-arch/p7zip/files/p7zip-9.20.1-CVE-2015-1038.patch b/app-arch/p7zip/files/p7zip-9.20.1-CVE-2015-1038.patch |
97 |
new file mode 100644 |
98 |
index 0000000..09dd0f2 |
99 |
--- /dev/null |
100 |
+++ b/app-arch/p7zip/files/p7zip-9.20.1-CVE-2015-1038.patch |
101 |
@@ -0,0 +1,315 @@ |
102 |
+Author: Ben Hutchings <ben@××××××××××××.uk> |
103 |
+Date: Tue, 19 May 2015 02:38:40 +0100 |
104 |
+Description: Delay creation of symlinks to prevent arbitrary file writes (CVE-2015-1038) |
105 |
+Bug: http://sourceforge.net/p/p7zip/bugs/147/ |
106 |
+Bug-Debian: https://bugs.debian.org/774660 |
107 |
+ |
108 |
+Alexander Cherepanov discovered that 7zip is susceptible to a |
109 |
+directory traversal vulnerability. While extracting an archive, it |
110 |
+will extract symlinks and then follow them if they are referenced in |
111 |
+further entries. This can be exploited by a rogue archive to write |
112 |
+files outside the current directory. |
113 |
+ |
114 |
+We have to create placeholder files (which we already do) and delay |
115 |
+creating symlinks until the end of extraction. |
116 |
+ |
117 |
+Due to the possibility of anti-items (deletions) in the archive, it is |
118 |
+possible for placeholders to be deleted and replaced before we create |
119 |
+the symlinks. It's not clear that this can be used for mischief, but |
120 |
+GNU tar guards against similar problems by checking that the placeholder |
121 |
+still exists and is the same inode. XXX It also checks 'birth time' but |
122 |
+this isn't portable. We can probably get away with comparing ctime |
123 |
+since we don't support hard links. |
124 |
+ |
125 |
+--- a/CPP/7zip/UI/Agent/Agent.cpp |
126 |
++++ b/CPP/7zip/UI/Agent/Agent.cpp |
127 |
+@@ -424,6 +424,8 @@ STDMETHODIMP CAgentFolder::Extract(const |
128 |
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; |
129 |
+ UStringVector pathParts; |
130 |
+ CProxyFolder *currentProxyFolder = _proxyFolderItem; |
131 |
++ HRESULT res; |
132 |
++ |
133 |
+ while (currentProxyFolder->Parent) |
134 |
+ { |
135 |
+ pathParts.Insert(0, currentProxyFolder->Name); |
136 |
+@@ -445,8 +447,11 @@ STDMETHODIMP CAgentFolder::Extract(const |
137 |
+ (UInt64)(Int64)-1); |
138 |
+ CUIntVector realIndices; |
139 |
+ GetRealIndices(indices, numItems, realIndices); |
140 |
+- return _agentSpec->GetArchive()->Extract(&realIndices.Front(), |
141 |
++ res = _agentSpec->GetArchive()->Extract(&realIndices.Front(), |
142 |
+ realIndices.Size(), testMode, extractCallback); |
143 |
++ if (res == S_OK && !extractCallbackSpec->CreateSymLinks()) |
144 |
++ res = E_FAIL; |
145 |
++ return res; |
146 |
+ COM_TRY_END |
147 |
+ } |
148 |
+ |
149 |
+--- a/CPP/7zip/UI/Agent/ArchiveFolder.cpp |
150 |
++++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp |
151 |
+@@ -20,6 +20,8 @@ STDMETHODIMP CAgentFolder::CopyTo(const |
152 |
+ CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; |
153 |
+ UStringVector pathParts; |
154 |
+ CProxyFolder *currentProxyFolder = _proxyFolderItem; |
155 |
++ HRESULT res; |
156 |
++ |
157 |
+ while (currentProxyFolder->Parent) |
158 |
+ { |
159 |
+ pathParts.Insert(0, currentProxyFolder->Name); |
160 |
+@@ -46,8 +48,11 @@ STDMETHODIMP CAgentFolder::CopyTo(const |
161 |
+ (UInt64)(Int64)-1); |
162 |
+ CUIntVector realIndices; |
163 |
+ GetRealIndices(indices, numItems, realIndices); |
164 |
+- return _agentSpec->GetArchive()->Extract(&realIndices.Front(), |
165 |
++ res = _agentSpec->GetArchive()->Extract(&realIndices.Front(), |
166 |
+ realIndices.Size(), BoolToInt(false), extractCallback); |
167 |
++ if (res == S_OK && !extractCallbackSpec->CreateSymLinks()) |
168 |
++ res = E_FAIL; |
169 |
++ return res; |
170 |
+ COM_TRY_END |
171 |
+ } |
172 |
+ |
173 |
+--- a/CPP/7zip/UI/Client7z/Client7z.cpp |
174 |
++++ b/CPP/7zip/UI/Client7z/Client7z.cpp |
175 |
+@@ -197,8 +197,11 @@ private: |
176 |
+ COutFileStream *_outFileStreamSpec; |
177 |
+ CMyComPtr<ISequentialOutStream> _outFileStream; |
178 |
+ |
179 |
++ CObjectVector<NWindows::NFile::NDirectory::CDelayedSymLink> _delayedSymLinks; |
180 |
++ |
181 |
+ public: |
182 |
+ void Init(IInArchive *archiveHandler, const UString &directoryPath); |
183 |
++ bool CreateSymLinks(); |
184 |
+ |
185 |
+ UInt64 NumErrors; |
186 |
+ bool PasswordIsDefined; |
187 |
+@@ -392,11 +395,22 @@ STDMETHODIMP CArchiveExtractCallback::Se |
188 |
+ } |
189 |
+ _outFileStream.Release(); |
190 |
+ if (_extractMode && _processedFileInfo.AttribDefined) |
191 |
+- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib); |
192 |
++ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib, &_delayedSymLinks); |
193 |
+ PrintNewLine(); |
194 |
+ return S_OK; |
195 |
+ } |
196 |
+ |
197 |
++bool CArchiveExtractCallback::CreateSymLinks() |
198 |
++{ |
199 |
++ bool success = true; |
200 |
++ |
201 |
++ for (int i = 0; i != _delayedSymLinks.Size(); ++i) |
202 |
++ success &= _delayedSymLinks[i].Create(); |
203 |
++ |
204 |
++ _delayedSymLinks.Clear(); |
205 |
++ |
206 |
++ return success; |
207 |
++} |
208 |
+ |
209 |
+ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) |
210 |
+ { |
211 |
+--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp |
212 |
++++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp |
213 |
+@@ -453,12 +453,24 @@ STDMETHODIMP CArchiveExtractCallback::Se |
214 |
+ NumFiles++; |
215 |
+ |
216 |
+ if (_extractMode && _fi.AttribDefined) |
217 |
+- NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib); |
218 |
++ NFile::NDirectory::MySetFileAttributes(_diskFilePath, _fi.Attrib, &_delayedSymLinks); |
219 |
+ RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted)); |
220 |
+ return S_OK; |
221 |
+ COM_TRY_END |
222 |
+ } |
223 |
+ |
224 |
++bool CArchiveExtractCallback::CreateSymLinks() |
225 |
++{ |
226 |
++ bool success = true; |
227 |
++ |
228 |
++ for (int i = 0; i != _delayedSymLinks.Size(); ++i) |
229 |
++ success &= _delayedSymLinks[i].Create(); |
230 |
++ |
231 |
++ _delayedSymLinks.Clear(); |
232 |
++ |
233 |
++ return success; |
234 |
++} |
235 |
++ |
236 |
+ /* |
237 |
+ STDMETHODIMP CArchiveExtractCallback::GetInStream( |
238 |
+ const wchar_t *name, ISequentialInStream **inStream) |
239 |
+--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h |
240 |
++++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h |
241 |
+@@ -6,6 +6,8 @@ |
242 |
+ #include "Common/MyCom.h" |
243 |
+ #include "Common/Wildcard.h" |
244 |
+ |
245 |
++#include "Windows/FileDir.h" |
246 |
++ |
247 |
+ #include "../../IPassword.h" |
248 |
+ |
249 |
+ #include "../../Common/FileStreams.h" |
250 |
+@@ -83,6 +85,8 @@ class CArchiveExtractCallback: |
251 |
+ UInt64 _packTotal; |
252 |
+ UInt64 _unpTotal; |
253 |
+ |
254 |
++ CObjectVector<NWindows::NFile::NDirectory::CDelayedSymLink> _delayedSymLinks; |
255 |
++ |
256 |
+ void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath); |
257 |
+ HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); |
258 |
+ HRESULT GetUnpackSize(); |
259 |
+@@ -138,6 +142,7 @@ public: |
260 |
+ const UStringVector &removePathParts, |
261 |
+ UInt64 packSize); |
262 |
+ |
263 |
++ bool CreateSymLinks(); |
264 |
+ }; |
265 |
+ |
266 |
+ #endif |
267 |
+--- a/CPP/7zip/UI/Common/Extract.cpp |
268 |
++++ b/CPP/7zip/UI/Common/Extract.cpp |
269 |
+@@ -96,6 +96,9 @@ static HRESULT DecompressArchive( |
270 |
+ else |
271 |
+ result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec); |
272 |
+ |
273 |
++ if (result == S_OK && !extractCallbackSpec->CreateSymLinks()) |
274 |
++ result = E_FAIL; |
275 |
++ |
276 |
+ return callback->ExtractResult(result); |
277 |
+ } |
278 |
+ |
279 |
+--- a/CPP/Windows/FileDir.cpp |
280 |
++++ b/CPP/Windows/FileDir.cpp |
281 |
+@@ -453,9 +453,10 @@ bool SetDirTime(LPCWSTR fileName, const |
282 |
+ } |
283 |
+ |
284 |
+ #ifndef _UNICODE |
285 |
+-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) |
286 |
++bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes, |
287 |
++ CObjectVector<CDelayedSymLink> *delayedSymLinks) |
288 |
+ { |
289 |
+- return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes); |
290 |
++ return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes, delayedSymLinks); |
291 |
+ } |
292 |
+ |
293 |
+ bool MyRemoveDirectory(LPCWSTR pathName) |
294 |
+@@ -488,7 +489,8 @@ static int convert_to_symlink(const char |
295 |
+ return -1; |
296 |
+ } |
297 |
+ |
298 |
+-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes) |
299 |
++bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes, |
300 |
++ CObjectVector<CDelayedSymLink> *delayedSymLinks) |
301 |
+ { |
302 |
+ if (!fileName) { |
303 |
+ SetLastError(ERROR_PATH_NOT_FOUND); |
304 |
+@@ -520,7 +522,9 @@ bool MySetFileAttributes(LPCTSTR fileNam |
305 |
+ stat_info.st_mode = fileAttributes >> 16; |
306 |
+ #ifdef ENV_HAVE_LSTAT |
307 |
+ if (S_ISLNK(stat_info.st_mode)) { |
308 |
+- if ( convert_to_symlink(name) != 0) { |
309 |
++ if (delayedSymLinks) |
310 |
++ delayedSymLinks->Add(CDelayedSymLink(name)); |
311 |
++ else if ( convert_to_symlink(name) != 0) { |
312 |
+ TRACEN((printf("MySetFileAttributes(%s,%d) : false-3\n",name,fileAttributes))) |
313 |
+ return false; |
314 |
+ } |
315 |
+@@ -924,4 +928,41 @@ bool CTempDirectory::Create(LPCTSTR pref |
316 |
+ } |
317 |
+ |
318 |
+ |
319 |
++#ifdef ENV_UNIX |
320 |
++ |
321 |
++CDelayedSymLink::CDelayedSymLink(LPCSTR source) |
322 |
++ : _source(source) |
323 |
++{ |
324 |
++ struct stat st; |
325 |
++ |
326 |
++ if (lstat(_source, &st) == 0) { |
327 |
++ _dev = st.st_dev; |
328 |
++ _ino = st.st_ino; |
329 |
++ } else { |
330 |
++ _dev = 0; |
331 |
++ } |
332 |
++} |
333 |
++ |
334 |
++bool CDelayedSymLink::Create() |
335 |
++{ |
336 |
++ struct stat st; |
337 |
++ |
338 |
++ if (_dev == 0) { |
339 |
++ errno = EPERM; |
340 |
++ return false; |
341 |
++ } |
342 |
++ if (lstat(_source, &st) != 0) |
343 |
++ return false; |
344 |
++ if (_dev != st.st_dev || _ino != st.st_ino) { |
345 |
++ // Placeholder file has been overwritten or moved by another |
346 |
++ // symbolic link creation |
347 |
++ errno = EPERM; |
348 |
++ return false; |
349 |
++ } |
350 |
++ |
351 |
++ return convert_to_symlink(_source) == 0; |
352 |
++} |
353 |
++ |
354 |
++#endif // ENV_UNIX |
355 |
++ |
356 |
+ }}} |
357 |
+--- a/CPP/Windows/FileDir.h |
358 |
++++ b/CPP/Windows/FileDir.h |
359 |
+@@ -4,6 +4,7 @@ |
360 |
+ #define __WINDOWS_FILEDIR_H |
361 |
+ |
362 |
+ #include "../Common/MyString.h" |
363 |
++#include "../Common/MyVector.h" |
364 |
+ #include "Defs.h" |
365 |
+ |
366 |
+ /* GetFullPathName for 7zAES.cpp */ |
367 |
+@@ -13,11 +14,15 @@ namespace NWindows { |
368 |
+ namespace NFile { |
369 |
+ namespace NDirectory { |
370 |
+ |
371 |
++class CDelayedSymLink; |
372 |
++ |
373 |
+ bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); |
374 |
+ |
375 |
+-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes); |
376 |
++bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes, |
377 |
++ CObjectVector<CDelayedSymLink> *delayedSymLinks = 0); |
378 |
+ #ifndef _UNICODE |
379 |
+-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes); |
380 |
++bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes, |
381 |
++ CObjectVector<CDelayedSymLink> *delayedSymLinks = 0); |
382 |
+ #endif |
383 |
+ |
384 |
+ bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName); |
385 |
+@@ -80,6 +85,31 @@ public: |
386 |
+ bool Remove(); |
387 |
+ }; |
388 |
+ |
389 |
++// Symbolic links must be created last so that they can't be used to |
390 |
++// create or overwrite files above the extraction directory. |
391 |
++class CDelayedSymLink |
392 |
++{ |
393 |
++#ifdef ENV_UNIX |
394 |
++ // Where the symlink should be created. The target is specified in |
395 |
++ // the placeholder file. |
396 |
++ AString _source; |
397 |
++ |
398 |
++ // Device and inode of the placeholder file. Before creating the |
399 |
++ // symlink, we must check that these haven't been changed by creation |
400 |
++ // of another symlink. |
401 |
++ dev_t _dev; |
402 |
++ ino_t _ino; |
403 |
++ |
404 |
++public: |
405 |
++ explicit CDelayedSymLink(LPCSTR source); |
406 |
++ bool Create(); |
407 |
++#else // !ENV_UNIX |
408 |
++public: |
409 |
++ CDelayedSymLink(LPCSTR source) {} |
410 |
++ bool Create() { return true; } |
411 |
++#endif // ENV_UNIX |
412 |
++}; |
413 |
++ |
414 |
+ #ifdef _UNICODE |
415 |
+ typedef CTempFile CTempFileW; |
416 |
+ #endif |
417 |
diff --git a/app-arch/p7zip/files/p7zip-9.20.1-QA.patch b/app-arch/p7zip/files/p7zip-9.20.1-QA.patch |
418 |
new file mode 100644 |
419 |
index 0000000..8845aca |
420 |
--- /dev/null |
421 |
+++ b/app-arch/p7zip/files/p7zip-9.20.1-QA.patch |
422 |
@@ -0,0 +1,17 @@ |
423 |
+From: Julian Ospald <hasufell@g.o> |
424 |
+Date: Thu Jun 7 14:31:12 UTC 2012 |
425 |
+Subject: fix QA warnings |
426 |
+ |
427 |
+https://sourceforge.net/tracker/?func=detail&atid=660493&aid=3532590&group_id=111810 |
428 |
+ |
429 |
+--- CPP/7zip/Archive/NtfsHandler.cpp |
430 |
++++ CPP/7zip/Archive/NtfsHandler.cpp |
431 |
+@@ -1280,7 +1280,7 @@ |
432 |
+ if (recSizeLog < Header.SectorSizeLog) |
433 |
+ return false; |
434 |
+ numSectorsInRec = 1 << (recSizeLog - Header.SectorSizeLog); |
435 |
+- if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, NULL, 0)) |
436 |
++ if (!mftRec.Parse(ByteBuf, Header.SectorSizeLog, numSectorsInRec, 0, NULL)) |
437 |
+ return S_FALSE; |
438 |
+ if (!mftRec.IsFILE()) |
439 |
+ return S_FALSE; |
440 |
diff --git a/app-arch/p7zip/files/p7zip-9.20.1-execstack.patch b/app-arch/p7zip/files/p7zip-9.20.1-execstack.patch |
441 |
new file mode 100644 |
442 |
index 0000000..1fdff48 |
443 |
--- /dev/null |
444 |
+++ b/app-arch/p7zip/files/p7zip-9.20.1-execstack.patch |
445 |
@@ -0,0 +1,24 @@ |
446 |
+diff -Naupr p7zip_9.20.1.orig/Asm/x64/7zCrcT8U.asm p7zip_9.20.1/Asm/x64/7zCrcT8U.asm |
447 |
+--- p7zip_9.20.1.orig/Asm/x64/7zCrcT8U.asm 2008-08-14 11:18:07.000000000 +0200 |
448 |
++++ p7zip_9.20.1/Asm/x64/7zCrcT8U.asm 2011-07-26 17:43:57.727910278 +0200 |
449 |
+@@ -101,3 +101,8 @@ _CrcUpdateT8: |
450 |
+ ret |
451 |
+ |
452 |
+ end |
453 |
++ |
454 |
++%ifidn __OUTPUT_FORMAT__,elf |
455 |
++section .note.GNU-stack noalloc noexec nowrite progbits |
456 |
++%endif |
457 |
++ |
458 |
+diff -Naupr p7zip_9.20.1.orig/Asm/x86/7zCrcT8U.asm p7zip_9.20.1/Asm/x86/7zCrcT8U.asm |
459 |
+--- p7zip_9.20.1.orig/Asm/x86/7zCrcT8U.asm 2009-07-14 12:44:15.000000000 +0200 |
460 |
++++ p7zip_9.20.1/Asm/x86/7zCrcT8U.asm 2011-07-26 17:44:23.938864508 +0200 |
461 |
+@@ -99,3 +99,8 @@ _CrcUpdateT8: |
462 |
+ |
463 |
+ |
464 |
+ ; end |
465 |
++ |
466 |
++%ifidn __OUTPUT_FORMAT__,elf |
467 |
++section .note.GNU-stack noalloc noexec nowrite progbits |
468 |
++%endif |
469 |
++ |
470 |
diff --git a/app-arch/p7zip/files/p7zip-CVE-2015-1038-musl.patch b/app-arch/p7zip/files/p7zip-CVE-2015-1038-musl.patch |
471 |
new file mode 100644 |
472 |
index 0000000..9837758 |
473 |
--- /dev/null |
474 |
+++ b/app-arch/p7zip/files/p7zip-CVE-2015-1038-musl.patch |
475 |
@@ -0,0 +1,14 @@ |
476 |
+diff -Naurw p7zip_15.09.orig/CPP/Windows/FileDir.h p7zip_15.09/CPP/Windows/FileDir.h |
477 |
+--- p7zip_15.09.orig/CPP/Windows/FileDir.h 2015-10-28 12:10:52.776688264 -0700 |
478 |
++++ p7zip_15.09/CPP/Windows/FileDir.h 2015-10-28 12:11:27.813355975 -0700 |
479 |
+@@ -3,6 +3,10 @@ |
480 |
+ #ifndef __WINDOWS_FILE_DIR_H |
481 |
+ #define __WINDOWS_FILE_DIR_H |
482 |
+ |
483 |
++#ifdef ENV_UNIX |
484 |
++#include <sys/types.h> |
485 |
++#endif |
486 |
++ |
487 |
+ #include "../Common/MyString.h" |
488 |
+ #include "../Common/MyVector.h" |
489 |
+ |
490 |
diff --git a/app-arch/p7zip/metadata.xml b/app-arch/p7zip/metadata.xml |
491 |
new file mode 100644 |
492 |
index 0000000..686e063 |
493 |
--- /dev/null |
494 |
+++ b/app-arch/p7zip/metadata.xml |
495 |
@@ -0,0 +1,14 @@ |
496 |
+<?xml version="1.0" encoding="UTF-8"?> |
497 |
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> |
498 |
+<pkgmetadata> |
499 |
+ <maintainer type="person"> |
500 |
+ <email>prometheanfire@g.o</email> |
501 |
+ <description>maintainer</description> |
502 |
+ </maintainer> |
503 |
+ <use> |
504 |
+ <flag name="rar">Enable support for non-free rar decoder</flag> |
505 |
+ </use> |
506 |
+ <upstream> |
507 |
+ <remote-id type="sourceforge">p7zip</remote-id> |
508 |
+ </upstream> |
509 |
+</pkgmetadata> |
510 |
diff --git a/app-arch/p7zip/p7zip-15.14.1.ebuild b/app-arch/p7zip/p7zip-15.14.1.ebuild |
511 |
new file mode 100644 |
512 |
index 0000000..4c3a0d2 |
513 |
--- /dev/null |
514 |
+++ b/app-arch/p7zip/p7zip-15.14.1.ebuild |
515 |
@@ -0,0 +1,160 @@ |
516 |
+# Copyright 1999-2016 Gentoo Foundation |
517 |
+# Distributed under the terms of the GNU General Public License v2 |
518 |
+# $Id$ |
519 |
+ |
520 |
+EAPI=5 |
521 |
+ |
522 |
+WX_GTK_VER="3.0" |
523 |
+ |
524 |
+inherit eutils multilib toolchain-funcs wxwidgets |
525 |
+ |
526 |
+DESCRIPTION="Port of 7-Zip archiver for Unix" |
527 |
+HOMEPAGE="http://p7zip.sourceforge.net/" |
528 |
+SRC_URI="mirror://sourceforge/${PN}/${PN}_${PV}_src_all.tar.bz2" |
529 |
+ |
530 |
+LICENSE="LGPL-2.1 rar? ( unRAR )" |
531 |
+SLOT="0" |
532 |
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 ~s390 ~sparc ~x86 ~x86-fbsd ~x86-freebsd ~x86-interix ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris" |
533 |
+IUSE="doc kde rar +pch static wxwidgets abi_x86_x32" |
534 |
+ |
535 |
+REQUIRED_USE="kde? ( wxwidgets )" |
536 |
+ |
537 |
+RDEPEND=" |
538 |
+ kde? ( x11-libs/wxGTK:${WX_GTK_VER}[X] kde-base/kdelibs ) |
539 |
+ wxwidgets? ( x11-libs/wxGTK:${WX_GTK_VER}[X] )" |
540 |
+DEPEND="${RDEPEND} |
541 |
+ amd64? ( dev-lang/yasm ) |
542 |
+ abi_x86_x32? ( >=dev-lang/yasm-1.2.0-r1 ) |
543 |
+ x86? ( dev-lang/nasm )" |
544 |
+ |
545 |
+S=${WORKDIR}/${PN}_${PV} |
546 |
+ |
547 |
+src_prepare() { |
548 |
+ epatch \ |
549 |
+ "${FILESDIR}"/${P}-darwin.patch \ |
550 |
+ "${FILESDIR}"/${PN}-CVE-2015-1038-musl.patch |
551 |
+ |
552 |
+ if ! use pch; then |
553 |
+ sed "s:PRE_COMPILED_HEADER=StdAfx.h.gch:PRE_COMPILED_HEADER=:g" -i makefile.* || die |
554 |
+ fi |
555 |
+ |
556 |
+ sed \ |
557 |
+ -e 's:-m32 ::g' \ |
558 |
+ -e 's:-m64 ::g' \ |
559 |
+ -e 's:-pipe::g' \ |
560 |
+ -e '/ALLFLAGS/s:-s ::' \ |
561 |
+ -e "/OPTFLAGS=/s:=.*:=${CXXFLAGS}:" \ |
562 |
+ -i makefile* || die |
563 |
+ |
564 |
+ # remove non-free RAR codec |
565 |
+ if use rar; then |
566 |
+ ewarn "Enabling nonfree RAR decompressor" |
567 |
+ else |
568 |
+ sed \ |
569 |
+ -e '/Rar/d' \ |
570 |
+ -e '/RAR/d' \ |
571 |
+ -i makefile* CPP/7zip/Bundles/Format7zFree/makefile || die |
572 |
+ rm -rf CPP/7zip/Compress/Rar || die |
573 |
+ fi |
574 |
+ |
575 |
+ if use abi_x86_x32; then |
576 |
+ sed -i -e "/^ASM=/s:amd64:x32:" makefile* || die |
577 |
+ cp -f makefile.linux_amd64_asm makefile.machine || die |
578 |
+ elif use amd64; then |
579 |
+ cp -f makefile.linux_amd64_asm makefile.machine || die |
580 |
+ elif use x86; then |
581 |
+ cp -f makefile.linux_x86_asm_gcc_4.X makefile.machine || die |
582 |
+ elif [[ ${CHOST} == *-darwin* ]] ; then |
583 |
+ # Mac OS X needs this special makefile, because it has a non-GNU |
584 |
+ # linker, it doesn't matter so much for bitwidth, for it doesn't |
585 |
+ # do anything with it |
586 |
+ cp -f makefile.macosx_llvm_64bits makefile.machine |
587 |
+ # bundles have extension .bundle but don't die because USE=-rar |
588 |
+ # removes the Rar directory |
589 |
+ sed -i -e '/strcpy(name/s/\.so/.bundle/' \ |
590 |
+ CPP/Windows/DLL.cpp || die |
591 |
+ sed -i -e '/^PROG=/s/\.so/.bundle/' \ |
592 |
+ CPP/7zip/Bundles/Format7zFree/makefile.list \ |
593 |
+ $(use rar && echo CPP/7zip/Compress/Rar/makefile.list) || die |
594 |
+ elif use x86-fbsd; then |
595 |
+ # FreeBSD needs this special makefile, because it hasn't -ldl |
596 |
+ sed -e 's/-lc_r/-pthread/' makefile.freebsd > makefile.machine |
597 |
+ fi |
598 |
+ |
599 |
+ if use static; then |
600 |
+ sed -i -e '/^LOCAL_LIBS=/s/LOCAL_LIBS=/&-static /' makefile.machine || die |
601 |
+ fi |
602 |
+ |
603 |
+ if use kde || use wxwidgets; then |
604 |
+ need-wxwidgets unicode |
605 |
+ einfo "Preparing dependency list" |
606 |
+ emake depend |
607 |
+ fi |
608 |
+} |
609 |
+ |
610 |
+src_compile() { |
611 |
+ emake CC=$(tc-getCC) CXX=$(tc-getCXX) all3 |
612 |
+ if use kde || use wxwidgets; then |
613 |
+ emake CC=$(tc-getCC) CXX=$(tc-getCXX) -- 7zG |
614 |
+# emake -- 7zFM |
615 |
+ fi |
616 |
+} |
617 |
+ |
618 |
+src_test() { |
619 |
+ emake test test_7z test_7zr |
620 |
+} |
621 |
+ |
622 |
+src_install() { |
623 |
+ # this wrappers can not be symlinks, p7zip should be called with full path |
624 |
+ make_wrapper 7zr "/usr/$(get_libdir)/${PN}/7zr" |
625 |
+ make_wrapper 7za "/usr/$(get_libdir)/${PN}/7za" |
626 |
+ make_wrapper 7z "/usr/$(get_libdir)/${PN}/7z" |
627 |
+ |
628 |
+ if use kde || use wxwidgets; then |
629 |
+ make_wrapper 7zG "/usr/$(get_libdir)/${PN}/7zG" |
630 |
+# make_wrapper 7zFM "/usr/$(get_libdir)/${PN}/7zFM" |
631 |
+ |
632 |
+# make_desktop_entry 7zFM "${PN} FM" ${PN} "GTK;Utility;Archiving;Compression" |
633 |
+ |
634 |
+ dobin GUI/p7zipForFilemanager |
635 |
+ exeinto /usr/$(get_libdir)/${PN} |
636 |
+# doexe bin/7z{G,FM} |
637 |
+ doexe bin/7zG |
638 |
+ |
639 |
+ insinto /usr/$(get_libdir)/${PN} |
640 |
+ doins -r GUI/{Lang,help} |
641 |
+ |
642 |
+ insinto /usr/share/icons/hicolor/16x16/apps/ |
643 |
+ newins GUI/p7zip_16_ok.png p7zip.png |
644 |
+ |
645 |
+ if use kde; then |
646 |
+ rm GUI/kde4/p7zip_compress.desktop || die |
647 |
+ insinto /usr/share/kde4/services/ServiceMenus |
648 |
+ doins GUI/kde4/*.desktop |
649 |
+ dodir /usr/share/kservices5/ServiceMenus |
650 |
+ for item in "${D}"/usr/share/kde4/services/ServiceMenus/*.desktop; do |
651 |
+ item="$(basename ${item})" |
652 |
+ dosym "/usr/share/kde4/services/ServiceMenus/${item}" "/usr/share/kservices5/ServiceMenus/${item}" |
653 |
+ done |
654 |
+ fi |
655 |
+ fi |
656 |
+ |
657 |
+ dobin contrib/gzip-like_CLI_wrapper_for_7z/p7zip |
658 |
+ doman contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 |
659 |
+ |
660 |
+ exeinto /usr/$(get_libdir)/${PN} |
661 |
+ doexe bin/7z bin/7za bin/7zr bin/7zCon.sfx |
662 |
+ doexe bin/*$(get_modname) |
663 |
+ if use rar; then |
664 |
+ exeinto /usr/$(get_libdir)/${PN}/Codecs/ |
665 |
+ doexe bin/Codecs/*$(get_modname) |
666 |
+ fi |
667 |
+ |
668 |
+ doman man1/7z.1 man1/7za.1 man1/7zr.1 |
669 |
+ dodoc ChangeLog README TODO |
670 |
+ |
671 |
+ if use doc; then |
672 |
+ dodoc DOC/*.txt |
673 |
+ dohtml -r DOC/MANUAL/* |
674 |
+ fi |
675 |
+} |
676 |
diff --git a/app-arch/p7zip/p7zip-9.20.1-r5.ebuild b/app-arch/p7zip/p7zip-9.20.1-r5.ebuild |
677 |
new file mode 100644 |
678 |
index 0000000..c399922 |
679 |
--- /dev/null |
680 |
+++ b/app-arch/p7zip/p7zip-9.20.1-r5.ebuild |
681 |
@@ -0,0 +1,156 @@ |
682 |
+# Copyright 1999-2015 Gentoo Foundation |
683 |
+# Distributed under the terms of the GNU General Public License v2 |
684 |
+# $Id$ |
685 |
+ |
686 |
+EAPI=4 |
687 |
+ |
688 |
+WX_GTK_VER="2.8" |
689 |
+ |
690 |
+inherit eutils multilib toolchain-funcs wxwidgets |
691 |
+ |
692 |
+DESCRIPTION="Port of 7-Zip archiver for Unix" |
693 |
+HOMEPAGE="http://p7zip.sourceforge.net/" |
694 |
+SRC_URI="mirror://sourceforge/${PN}/${PN}_${PV}_src_all.tar.bz2" |
695 |
+ |
696 |
+LICENSE="LGPL-2.1 rar? ( unRAR )" |
697 |
+SLOT="0" |
698 |
+KEYWORDS="alpha amd64 ~arm hppa ia64 ppc ppc64 ~s390 sparc x86 ~x86-fbsd ~x86-freebsd ~x86-interix ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris" |
699 |
+IUSE="doc kde rar +pch static wxwidgets" |
700 |
+ |
701 |
+REQUIRED_USE="kde? ( wxwidgets )" |
702 |
+ |
703 |
+RDEPEND=" |
704 |
+ kde? ( x11-libs/wxGTK:2.8[X,-odbc] kde-base/kdelibs ) |
705 |
+ wxwidgets? ( x11-libs/wxGTK:2.8[X,-odbc] )" |
706 |
+DEPEND="${RDEPEND} |
707 |
+ amd64? ( dev-lang/yasm ) |
708 |
+ x86? ( dev-lang/nasm )" |
709 |
+ |
710 |
+S=${WORKDIR}/${PN}_${PV} |
711 |
+ |
712 |
+src_prepare() { |
713 |
+ epatch \ |
714 |
+ "${FILESDIR}"/${P}-execstack.patch \ |
715 |
+ "${FILESDIR}"/${P}-QA.patch \ |
716 |
+ "${FILESDIR}"/${P}-CVE-2015-1038.patch \ |
717 |
+ "${FILESDIR}"/${PN}-CVE-2015-1038-musl.patch |
718 |
+ |
719 |
+ if ! use pch; then |
720 |
+ sed "s:PRE_COMPILED_HEADER=StdAfx.h.gch:PRE_COMPILED_HEADER=:g" -i makefile.* || die |
721 |
+ fi |
722 |
+ |
723 |
+ sed \ |
724 |
+ -e 's:-m32 ::g' \ |
725 |
+ -e 's:-m64 ::g' \ |
726 |
+ -e 's:-O::g' \ |
727 |
+ -e 's:-pipe::g' \ |
728 |
+ -e "/^CC/s:\$(ALLFLAGS):${CFLAGS} \$(ALLFLAGS):g" \ |
729 |
+ -e "/^CXX/s:\$(ALLFLAGS):${CXXFLAGS} \$(ALLFLAGS):g" \ |
730 |
+ -i makefile* || die |
731 |
+ |
732 |
+ # remove non-free RAR codec |
733 |
+ if use rar; then |
734 |
+ ewarn "Enabling nonfree RAR decompressor" |
735 |
+ else |
736 |
+ sed -e '/Rar/d' -i makefile* || die |
737 |
+ rm -rf CPP/7zip/Compress/Rar || die |
738 |
+ epatch "${FILESDIR}"/9.04-makefile.patch |
739 |
+ fi |
740 |
+ |
741 |
+ sed -i \ |
742 |
+ -e "/^CXX=/s:g++:$(tc-getCXX):" \ |
743 |
+ -e "/^CC=/s:gcc:$(tc-getCC):" \ |
744 |
+ -e '/ALLFLAGS/s:-s ::' \ |
745 |
+ makefile* || die "changing makefiles" |
746 |
+ |
747 |
+ if use amd64; then |
748 |
+ cp -f makefile.linux_amd64_asm makefile.machine || die |
749 |
+ elif use x86; then |
750 |
+ cp -f makefile.linux_x86_asm_gcc_4.X makefile.machine || die |
751 |
+ elif [[ ${CHOST} == *-darwin* ]] ; then |
752 |
+ # Mac OS X needs this special makefile, because it has a non-GNU linker |
753 |
+ [[ ${CHOST} == *64-* ]] \ |
754 |
+ && cp -f makefile.macosx_64bits makefile.machine \ |
755 |
+ || cp -f makefile.macosx_32bits makefile.machine |
756 |
+ # bundles have extension .bundle but don't die because USE=-rar |
757 |
+ # removes the Rar directory |
758 |
+ sed -i -e '/strcpy(name/s/\.so/.bundle/' \ |
759 |
+ CPP/Windows/DLL.cpp || die |
760 |
+ sed -i -e '/^PROG=/s/\.so/.bundle/' \ |
761 |
+ CPP/7zip/Bundles/Format7zFree/makefile \ |
762 |
+ $(use rar && echo CPP/7zip/Compress/Rar/makefile) || die |
763 |
+ elif use x86-fbsd; then |
764 |
+ # FreeBSD needs this special makefile, because it hasn't -ldl |
765 |
+ sed -e 's/-lc_r/-pthread/' makefile.freebsd > makefile.machine |
766 |
+ fi |
767 |
+ |
768 |
+ if use static; then |
769 |
+ sed -i -e '/^LOCAL_LIBS=/s/LOCAL_LIBS=/&-static /' makefile.machine || die |
770 |
+ fi |
771 |
+ |
772 |
+ if use kde || use wxwidgets; then |
773 |
+ einfo "Preparing dependency list" |
774 |
+ emake depend |
775 |
+ fi |
776 |
+} |
777 |
+ |
778 |
+src_compile() { |
779 |
+ emake all3 |
780 |
+ if use kde || use wxwidgets; then |
781 |
+ emake -- 7zG |
782 |
+ emake -- 7zFM |
783 |
+ fi |
784 |
+} |
785 |
+ |
786 |
+src_test() { |
787 |
+ emake test test_7z test_7zr |
788 |
+} |
789 |
+ |
790 |
+src_install() { |
791 |
+ # this wrappers can not be symlinks, p7zip should be called with full path |
792 |
+ make_wrapper 7zr "/usr/$(get_libdir)/${PN}/7zr" |
793 |
+ make_wrapper 7za "/usr/$(get_libdir)/${PN}/7za" |
794 |
+ make_wrapper 7z "/usr/$(get_libdir)/${PN}/7z" |
795 |
+ |
796 |
+ if use kde || use wxwidgets; then |
797 |
+ make_wrapper 7zG "/usr/$(get_libdir)/${PN}/7zG" |
798 |
+ make_wrapper 7zFM "/usr/$(get_libdir)/${PN}/7zFM" |
799 |
+ |
800 |
+ make_desktop_entry 7zFM "${PN} FM" ${PN} "GTK;Utility;Archiving;Compression" |
801 |
+ |
802 |
+ dobin GUI/p7zipForFilemanager |
803 |
+ exeinto /usr/$(get_libdir)/${PN} |
804 |
+ doexe bin/7z{G,FM} |
805 |
+ |
806 |
+ insinto /usr/$(get_libdir)/${PN} |
807 |
+ doins -r GUI/{Lang,help} |
808 |
+ |
809 |
+ insinto /usr/share/icons/hicolor/16x16/apps/ |
810 |
+ newins GUI/p7zip_16_ok.png p7zip.png |
811 |
+ |
812 |
+ if use kde; then |
813 |
+ rm GUI/kde4/p7zip_compress.desktop || die |
814 |
+ insinto /usr/share/kde4/services/ServiceMenus |
815 |
+ doins GUI/kde4/*.desktop |
816 |
+ fi |
817 |
+ fi |
818 |
+ |
819 |
+ dobin contrib/gzip-like_CLI_wrapper_for_7z/p7zip |
820 |
+ doman contrib/gzip-like_CLI_wrapper_for_7z/man1/p7zip.1 |
821 |
+ |
822 |
+ exeinto /usr/$(get_libdir)/${PN} |
823 |
+ doexe bin/7z bin/7za bin/7zr bin/7zCon.sfx |
824 |
+ doexe bin/*$(get_modname) |
825 |
+ if use rar; then |
826 |
+ exeinto /usr/$(get_libdir)/${PN}/Codecs/ |
827 |
+ doexe bin/Codecs/*$(get_modname) |
828 |
+ fi |
829 |
+ |
830 |
+ doman man1/7z.1 man1/7za.1 man1/7zr.1 |
831 |
+ dodoc ChangeLog README TODO |
832 |
+ |
833 |
+ if use doc; then |
834 |
+ dodoc DOCS/*.txt |
835 |
+ dohtml -r DOCS/MANUAL/* |
836 |
+ fi |
837 |
+} |
838 |
-- |
839 |
2.8.1 |