OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
14 KiB

  1. # --- SDE-COPYRIGHT-NOTE-BEGIN ---
  2. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  3. #
  4. # Filename: package/.../musl/pkg/gcc/0016-dlang-update-zlib-binding.patch
  5. # Copyright (C) 2020 The OpenSDE Project
  6. #
  7. # More information can be found in the files COPYING and README.
  8. #
  9. # This patch file is dual-licensed. It is available under the license the
  10. # patched project is licensed under, as long as it is an OpenSource license
  11. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  12. # of the GNU General Public License as published by the Free Software
  13. # Foundation; either version 2 of the License, or (at your option) any later
  14. # version.
  15. # --- SDE-COPYRIGHT-NOTE-END ---
  16. From 7fc386a2e629e859968da4eb4d0ff4983cb3b76f Mon Sep 17 00:00:00 2001
  17. From: Ariadne Conill <ariadne@dereferenced.org>
  18. Date: Fri, 21 Aug 2020 06:57:51 +0000
  19. Subject: [PATCH 16/30] dlang: update zlib binding
  20. ---
  21. libphobos/src/std/zlib.d | 266 ++++++++++++++++++++++++++++-----------
  22. 1 file changed, 196 insertions(+), 70 deletions(-)
  23. diff --git a/libphobos/src/std/zlib.d b/libphobos/src/std/zlib.d
  24. index e6cce240fd5..bd2fe37ebec 100644
  25. --- a/libphobos/src/std/zlib.d
  26. +++ b/libphobos/src/std/zlib.d
  27. @@ -1,7 +1,7 @@
  28. // Written in the D programming language.
  29. /**
  30. - * Compress/decompress data using the $(HTTP www._zlib.net, _zlib library).
  31. + * Compress/decompress data using the $(HTTP www.zlib.net, zlib library).
  32. *
  33. * Examples:
  34. *
  35. @@ -43,12 +43,12 @@
  36. * References:
  37. * $(HTTP en.wikipedia.org/wiki/Zlib, Wikipedia)
  38. *
  39. - * Copyright: Copyright Digital Mars 2000 - 2011.
  40. + * Copyright: Copyright The D Language Foundation 2000 - 2011.
  41. * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
  42. * Authors: $(HTTP digitalmars.com, Walter Bright)
  43. - * Source: $(PHOBOSSRC std/_zlib.d)
  44. + * Source: $(PHOBOSSRC std/zlib.d)
  45. */
  46. -/* Copyright Digital Mars 2000 - 2011.
  47. +/* Copyright The D Language Foundation 2000 - 2011.
  48. * Distributed under the Boost Software License, Version 1.0.
  49. * (See accompanying file LICENSE_1_0.txt or copy at
  50. * http://www.boost.org/LICENSE_1_0.txt)
  51. @@ -75,9 +75,9 @@ enum
  52. class ZlibException : Exception
  53. {
  54. - this(int errnum)
  55. - { string msg;
  56. -
  57. + private static string getmsg(int errnum) nothrow @nogc pure @safe
  58. + {
  59. + string msg;
  60. switch (errnum)
  61. {
  62. case Z_STREAM_END: msg = "stream end"; break;
  63. @@ -90,7 +90,12 @@ class ZlibException : Exception
  64. case Z_VERSION_ERROR: msg = "version error"; break;
  65. default: msg = "unknown error"; break;
  66. }
  67. - super(msg);
  68. + return msg;
  69. + }
  70. +
  71. + this(int errnum)
  72. + {
  73. + super(getmsg(errnum));
  74. }
  75. }
  76. @@ -104,7 +109,7 @@ class ZlibException : Exception
  77. * buf = buffer containing input data
  78. *
  79. * Returns:
  80. - * A $(D uint) checksum for the provided input data and starting checksum
  81. + * A `uint` checksum for the provided input data and starting checksum
  82. *
  83. * See_Also:
  84. * $(LINK http://en.wikipedia.org/wiki/Adler-32)
  85. @@ -147,7 +152,7 @@ uint adler32(uint adler, const(void)[] buf)
  86. * buf = buffer containing input data
  87. *
  88. * Returns:
  89. - * A $(D uint) checksum for the provided input data and starting checksum
  90. + * A `uint` checksum for the provided input data and starting checksum
  91. *
  92. * See_Also:
  93. * $(LINK http://en.wikipedia.org/wiki/Cyclic_redundancy_check)
  94. @@ -191,13 +196,14 @@ uint crc32(uint crc, const(void)[] buf)
  95. ubyte[] compress(const(void)[] srcbuf, int level)
  96. in
  97. {
  98. - assert(-1 <= level && level <= 9);
  99. + assert(-1 <= level && level <= 9, "Compression level needs to be within [-1, 9].");
  100. }
  101. -body
  102. +do
  103. {
  104. import core.memory : GC;
  105. + import std.array : uninitializedArray;
  106. auto destlen = srcbuf.length + ((srcbuf.length + 1023) / 1024) + 12;
  107. - auto destbuf = new ubyte[destlen];
  108. + auto destbuf = uninitializedArray!(ubyte[])(destlen);
  109. auto err = etc.c.zlib.compress2(destbuf.ptr, &destlen, cast(ubyte *) srcbuf.ptr, srcbuf.length, level);
  110. if (err)
  111. {
  112. @@ -276,7 +282,7 @@ void[] uncompress(const(void)[] srcbuf, size_t destlen = 0u, int winbits = 15)
  113. throw new ZlibException(err);
  114. }
  115. }
  116. - assert(0);
  117. + assert(0, "Unreachable code");
  118. }
  119. @system unittest
  120. @@ -370,9 +376,9 @@ class Compress
  121. this(int level, HeaderFormat header = HeaderFormat.deflate)
  122. in
  123. {
  124. - assert(1 <= level && level <= 9);
  125. + assert(1 <= level && level <= 9, "Legal compression level are in [1, 9].");
  126. }
  127. - body
  128. + do
  129. {
  130. this.level = level;
  131. this.gzip = header == HeaderFormat.gzip;
  132. @@ -406,6 +412,7 @@ class Compress
  133. const(void)[] compress(const(void)[] buf)
  134. {
  135. import core.memory : GC;
  136. + import std.array : uninitializedArray;
  137. int err;
  138. ubyte[] destbuf;
  139. @@ -420,7 +427,7 @@ class Compress
  140. inited = 1;
  141. }
  142. - destbuf = new ubyte[zs.avail_in + buf.length];
  143. + destbuf = uninitializedArray!(ubyte[])(zs.avail_in + buf.length);
  144. zs.next_out = destbuf.ptr;
  145. zs.avail_out = to!uint(destbuf.length);
  146. @@ -461,9 +468,10 @@ class Compress
  147. void[] flush(int mode = Z_FINISH)
  148. in
  149. {
  150. - assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH);
  151. + assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH,
  152. + "Mode must be either Z_FINISH, Z_SYNC_FLUSH or Z_FULL_FLUSH.");
  153. }
  154. - body
  155. + do
  156. {
  157. import core.memory : GC;
  158. ubyte[] destbuf;
  159. @@ -523,6 +531,7 @@ class UnCompress
  160. z_stream zs;
  161. int inited;
  162. int done;
  163. + bool inputEnded;
  164. size_t destbufsize;
  165. HeaderFormat format;
  166. @@ -571,16 +580,16 @@ class UnCompress
  167. const(void)[] uncompress(const(void)[] buf)
  168. in
  169. {
  170. - assert(!done);
  171. + assert(!done, "Buffer has been flushed.");
  172. }
  173. - body
  174. + do
  175. {
  176. + if (inputEnded || !buf.length)
  177. + return null;
  178. +
  179. import core.memory : GC;
  180. + import std.array : uninitializedArray;
  181. int err;
  182. - ubyte[] destbuf;
  183. -
  184. - if (buf.length == 0)
  185. - return null;
  186. if (!inited)
  187. {
  188. @@ -598,26 +607,152 @@ class UnCompress
  189. if (!destbufsize)
  190. destbufsize = to!uint(buf.length) * 2;
  191. - destbuf = new ubyte[zs.avail_in * 2 + destbufsize];
  192. - zs.next_out = destbuf.ptr;
  193. - zs.avail_out = to!uint(destbuf.length);
  194. -
  195. - if (zs.avail_in)
  196. - buf = zs.next_in[0 .. zs.avail_in] ~ cast(ubyte[]) buf;
  197. + auto destbuf = uninitializedArray!(ubyte[])(destbufsize);
  198. + size_t destFill;
  199. zs.next_in = cast(ubyte*) buf.ptr;
  200. zs.avail_in = to!uint(buf.length);
  201. - err = inflate(&zs, Z_NO_FLUSH);
  202. - if (err != Z_STREAM_END && err != Z_OK)
  203. + while (true)
  204. {
  205. - GC.free(destbuf.ptr);
  206. - error(err);
  207. + auto oldAvailIn = zs.avail_in;
  208. +
  209. + zs.next_out = destbuf[destFill .. $].ptr;
  210. + zs.avail_out = to!uint(destbuf.length - destFill);
  211. +
  212. + err = inflate(&zs, Z_NO_FLUSH);
  213. + if (err == Z_STREAM_END)
  214. + {
  215. + inputEnded = true;
  216. + break;
  217. + }
  218. + else if (err != Z_OK)
  219. + {
  220. + GC.free(destbuf.ptr);
  221. + error(err);
  222. + }
  223. + else if (!zs.avail_in)
  224. + break;
  225. +
  226. + /*
  227. + According to the zlib manual inflate() stops when either there's
  228. + no more data to uncompress or the output buffer is full
  229. + So at this point, the output buffer is too full
  230. + */
  231. +
  232. + destFill = destbuf.length;
  233. +
  234. + if (destbuf.capacity)
  235. + {
  236. + if (destbuf.length < destbuf.capacity)
  237. + destbuf.length = destbuf.capacity;
  238. + else
  239. + {
  240. + auto newLength = GC.extend(destbuf.ptr, destbufsize, destbufsize);
  241. +
  242. + if (newLength && destbuf.length < destbuf.capacity)
  243. + destbuf.length = destbuf.capacity;
  244. + else
  245. + destbuf.length += destbufsize;
  246. + }
  247. + }
  248. + else
  249. + destbuf.length += destbufsize;
  250. }
  251. +
  252. destbuf.length = destbuf.length - zs.avail_out;
  253. return destbuf;
  254. }
  255. + // Test for issues 3191 and 9505
  256. + @system unittest
  257. + {
  258. + import std.algorithm.comparison;
  259. + import std.array;
  260. + import std.file;
  261. + import std.zlib;
  262. +
  263. + // Data that can be easily compressed
  264. + ubyte[1024] originalData;
  265. +
  266. + // This should yield a compression ratio of at least 1/2
  267. + auto compressedData = compress(originalData, 9);
  268. + assert(compressedData.length < originalData.length / 2,
  269. + "The compression ratio is too low to accurately test this situation");
  270. +
  271. + auto chunkSize = compressedData.length / 4;
  272. + assert(chunkSize < compressedData.length,
  273. + "The length of the compressed data is too small to accurately test this situation");
  274. +
  275. + auto decompressor = new UnCompress();
  276. + ubyte[originalData.length] uncompressedData;
  277. + ubyte[] reusedBuf;
  278. + int progress;
  279. +
  280. + reusedBuf.length = chunkSize;
  281. +
  282. + for (int i = 0; i < compressedData.length; i += chunkSize)
  283. + {
  284. + auto len = min(chunkSize, compressedData.length - i);
  285. + // simulate reading from a stream in small chunks
  286. + reusedBuf[0 .. len] = compressedData[i .. i + len];
  287. +
  288. + // decompress using same input buffer
  289. + auto chunk = decompressor.uncompress(reusedBuf);
  290. + assert(progress + chunk.length <= originalData.length,
  291. + "The uncompressed result is bigger than the original data");
  292. +
  293. + uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[];
  294. + progress += chunk.length;
  295. + }
  296. +
  297. + auto chunk = decompressor.flush();
  298. + assert(progress + chunk.length <= originalData.length,
  299. + "The uncompressed result is bigger than the original data");
  300. +
  301. + uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[];
  302. + progress += chunk.length;
  303. +
  304. + assert(progress == originalData.length,
  305. + "The uncompressed and the original data sizes differ");
  306. + assert(originalData[] == uncompressedData[],
  307. + "The uncompressed and the original data differ");
  308. + }
  309. +
  310. + @system unittest
  311. + {
  312. + ubyte[1024] invalidData;
  313. + auto decompressor = new UnCompress();
  314. +
  315. + try
  316. + {
  317. + auto uncompressedData = decompressor.uncompress(invalidData);
  318. + }
  319. + catch (ZlibException e)
  320. + {
  321. + assert(e.msg == "data error");
  322. + return;
  323. + }
  324. +
  325. + assert(false, "Corrupted data didn't result in an error");
  326. + }
  327. +
  328. + @system unittest
  329. + {
  330. + ubyte[2014] originalData = void;
  331. + auto compressedData = compress(originalData, 9);
  332. +
  333. + auto decompressor = new UnCompress();
  334. + auto uncompressedData = decompressor.uncompress(compressedData ~ cast(ubyte[]) "whatever");
  335. +
  336. + assert(originalData.length == uncompressedData.length,
  337. + "The uncompressed and the original data sizes differ");
  338. + assert(originalData[] == uncompressedData[],
  339. + "The uncompressed and the original data differ");
  340. + assert(!decompressor.uncompress("whatever").length,
  341. + "Compression continued after the end");
  342. + }
  343. +
  344. /**
  345. * Decompress and return any remaining data.
  346. * The returned data should be appended to that returned by uncompress().
  347. @@ -626,49 +761,40 @@ class UnCompress
  348. void[] flush()
  349. in
  350. {
  351. - assert(!done);
  352. + assert(!done, "Buffer has been flushed before.");
  353. }
  354. out
  355. {
  356. - assert(done);
  357. + assert(done, "Flushing failed.");
  358. }
  359. - body
  360. + do
  361. {
  362. - import core.memory : GC;
  363. - ubyte[] extra;
  364. - ubyte[] destbuf;
  365. - int err;
  366. -
  367. done = 1;
  368. - if (!inited)
  369. - return null;
  370. + return null;
  371. + }
  372. - L1:
  373. - destbuf = new ubyte[zs.avail_in * 2 + 100];
  374. - zs.next_out = destbuf.ptr;
  375. - zs.avail_out = to!uint(destbuf.length);
  376. + /// Returns true if all input data has been decompressed and no further data
  377. + /// can be decompressed (inflate() returned Z_STREAM_END)
  378. + @property bool empty() const
  379. + {
  380. + return inputEnded;
  381. + }
  382. - err = etc.c.zlib.inflate(&zs, Z_NO_FLUSH);
  383. - if (err == Z_OK && zs.avail_out == 0)
  384. - {
  385. - extra ~= destbuf;
  386. - goto L1;
  387. - }
  388. - if (err != Z_STREAM_END)
  389. - {
  390. - GC.free(destbuf.ptr);
  391. - if (err == Z_OK)
  392. - err = Z_BUF_ERROR;
  393. - error(err);
  394. - }
  395. - destbuf = destbuf.ptr[0 .. zs.next_out - destbuf.ptr];
  396. - err = etc.c.zlib.inflateEnd(&zs);
  397. - inited = 0;
  398. - if (err)
  399. - error(err);
  400. - if (extra.length)
  401. - destbuf = extra ~ destbuf;
  402. - return destbuf;
  403. + ///
  404. + @system unittest
  405. + {
  406. + // some random data
  407. + ubyte[1024] originalData = void;
  408. +
  409. + // append garbage data (or don't, this works in both cases)
  410. + auto compressedData = cast(ubyte[]) compress(originalData) ~ cast(ubyte[]) "whatever";
  411. +
  412. + auto decompressor = new UnCompress();
  413. + auto uncompressedData = decompressor.uncompress(compressedData);
  414. +
  415. + assert(uncompressedData[] == originalData[],
  416. + "The uncompressed and the original data differ");
  417. + assert(decompressor.empty, "The UnCompressor reports not being done");
  418. }
  419. }
  420. --
  421. 2.27.0