1111#include <stdlib.h>
1212#include <string.h>
1313#include <unistd.h>
14+ #include <errno.h>
15+ #ifdef ENABLE_ZLIB_COMPRESSION
1416#include <zlib.h>
17+ #endif
18+ #ifdef ENABLE_LZMA_COMPRESSION
1519#include <lzma.h>
16- #include <errno.h>
20+ #endif
21+ #ifdef ENABLE_ZSTD_COMPRESSION
22+ #include <zstd.h>
23+ #endif
1724
1825#include "pool.h"
1926#include "repo.h"
3037#define S_ISREG (m ) (((m) & S_IFMT) == S_IFREG)
3138#endif
3239
40+ #define MAX_CONTROL_SIZE 0x1000000
41+
42+ #ifdef ENABLE_ZLIB_COMPRESSION
43+
3344static unsigned char *
3445decompress_gz (unsigned char * in , int inl , int * outlp , int maxoutl )
3546{
@@ -107,6 +118,18 @@ decompress_gz(unsigned char *in, int inl, int *outlp, int maxoutl)
107118 return out ;
108119}
109120
121+ #else
122+
123+ static unsigned char *
124+ decompress_gz (unsigned char * in , int inl , int * outlp , int maxoutl )
125+ {
126+ return 0 ;
127+ }
128+
129+ #endif /* ENABLE_ZLIB_COMPRESSION */
130+
131+ #ifdef ENABLE_LZMA_COMPRESSION
132+
110133static unsigned char *
111134decompress_xz (unsigned char * in , int inl , int * outlp , int maxoutl )
112135{
@@ -159,6 +182,81 @@ decompress_xz(unsigned char *in, int inl, int *outlp, int maxoutl)
159182 return out ;
160183}
161184
185+ #else
186+
187+ static unsigned char *
188+ decompress_xz (unsigned char * in , int inl , int * outlp , int maxoutl )
189+ {
190+ return 0 ;
191+ }
192+
193+ #endif /* ENABLE_LZMA_COMPRESSION */
194+
195+ #ifdef ENABLE_ZSTD_COMPRESSION
196+
197+ static unsigned char *
198+ decompress_zstd (unsigned char * in , int inl , int * outlp , int maxoutl )
199+ {
200+ ZSTD_DStream * dstream ;
201+ ZSTD_inBuffer inbuf ;
202+ ZSTD_outBuffer outbuf ;
203+ int ret ;
204+
205+ dstream = ZSTD_createDStream ();
206+ if (!dstream )
207+ return 0 ;
208+ if (ZSTD_isError (ZSTD_initDStream (dstream )))
209+ {
210+ ZSTD_freeDStream (dstream );
211+ return 0 ;
212+ }
213+ inbuf .src = in ;
214+ inbuf .pos = 0 ;
215+ inbuf .size = inl ;
216+ outbuf .dst = solv_malloc (4096 );
217+ outbuf .pos = 0 ;
218+ outbuf .size = 4096 ;
219+ for (;;)
220+ {
221+ if (outbuf .pos == outbuf .size )
222+ {
223+ outbuf .size += 4096 ;
224+ if (outbuf .size >= maxoutl )
225+ {
226+ ret = 1 ;
227+ break ;
228+ }
229+ outbuf .dst = solv_realloc (outbuf .dst , outbuf .size + 4096 );
230+ }
231+ ret = ZSTD_decompressStream (dstream , & outbuf , & inbuf );
232+ if (ret == 0 && inbuf .pos == inbuf .size )
233+ break ;
234+ if (ZSTD_isError (ret ) || (inbuf .pos == inbuf .size && outbuf .pos < outbuf .size ))
235+ {
236+ ret = 1 ;
237+ break ;
238+ }
239+ }
240+ ZSTD_freeDStream (dstream );
241+ if (ret )
242+ {
243+ solv_free (outbuf .dst );
244+ return 0 ;
245+ }
246+ * outlp = outbuf .pos ;
247+ return outbuf .dst ;
248+ }
249+
250+ #else
251+
252+ static unsigned char *
253+ decompress_zstd (unsigned char * in , int inl , int * outlp , int maxoutl )
254+ {
255+ return 0 ;
256+ }
257+
258+ #endif /* ENABLE_ZSTD_COMPRESSION */
259+
162260static Id
163261parseonedep (Pool * pool , char * p )
164262{
@@ -544,6 +642,7 @@ repo_add_debdb(Repo *repo, int flags)
544642#define CONTROL_COMP_NONE 0
545643#define CONTROL_COMP_GZIP 1
546644#define CONTROL_COMP_XZ 2
645+ #define CONTROL_COMP_ZSTD 3
547646
548647Id
549648repo_add_deb (Repo * repo , const char * deb , int flags )
@@ -599,6 +698,8 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
599698 control_comp = CONTROL_COMP_GZIP ;
600699 else if (!strncmp ((char * )buf + 8 + 60 + vlen , "control.tar.xz " , 16 ) || !strncmp ((char * )buf + 8 + 60 + vlen , "control.tar.xz/ " , 16 ))
601700 control_comp = CONTROL_COMP_XZ ;
701+ else if (!strncmp ((char * )buf + 8 + 60 + vlen , "control.tar.zst " , 16 ) || !strncmp ((char * )buf + 8 + 60 + vlen , "control.tar.zst/" , 16 ))
702+ control_comp = CONTROL_COMP_ZSTD ;
602703 else if (!strncmp ((char * )buf + 8 + 60 + vlen , "control.tar " , 16 ) || !strncmp ((char * )buf + 8 + 60 + vlen , "control.tar/ " , 16 ))
603704 control_comp = CONTROL_COMP_NONE ;
604705 else
@@ -611,7 +712,7 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
611712 * just keeps from allocating arbitrarily large amounts of memory.
612713 */
613714 clen = atoi ((char * )buf + 8 + 60 + vlen + 48 );
614- if (clen <= 0 || clen >= 0x1000000 )
715+ if (clen <= 0 || clen >= MAX_CONTROL_SIZE )
615716 {
616717 pool_error (pool , -1 , "%s: control.tar has illegal size" , deb );
617718 fclose (fp );
@@ -645,9 +746,11 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
645746 }
646747 ctar = 0 ;
647748 if (control_comp == CONTROL_COMP_GZIP )
648- ctar = decompress_gz (ctgz , clen , & ctarlen , 0x1000000 );
749+ ctar = decompress_gz (ctgz , clen , & ctarlen , MAX_CONTROL_SIZE );
649750 else if (control_comp == CONTROL_COMP_XZ )
650- ctar = decompress_xz (ctgz , clen , & ctarlen , 0x1000000 );
751+ ctar = decompress_xz (ctgz , clen , & ctarlen , MAX_CONTROL_SIZE );
752+ else if (control_comp == CONTROL_COMP_ZSTD )
753+ ctar = decompress_zstd (ctgz , clen , & ctarlen , MAX_CONTROL_SIZE );
651754 else
652755 {
653756 ctarlen = clen ;
@@ -656,7 +759,7 @@ repo_add_deb(Repo *repo, const char *deb, int flags)
656759 solv_free (ctgz );
657760 if (!ctar )
658761 {
659- pool_error (pool , -1 , "%s: control.tar is corrupt " , deb );
762+ pool_error (pool , -1 , "%s: control.tar decompression error " , deb );
660763 return 0 ;
661764 }
662765 bp = ctar ;
0 commit comments