@@ -172,6 +172,15 @@ typedef struct rpmhead {
172172} RpmHead ;
173173
174174
175+ static inline void
176+ headinit (RpmHead * h , unsigned int cnt , unsigned int dcnt )
177+ {
178+ h -> cnt = (int )cnt ;
179+ h -> dcnt = dcnt ;
180+ h -> dp = h -> data + 16 * cnt ;
181+ h -> dp [dcnt ] = 0 ;
182+ }
183+
175184static inline unsigned char *
176185headfindtag (RpmHead * h , int tag )
177186{
@@ -1240,57 +1249,63 @@ struct rpmdbstate {
12401249 char * rootdir ;
12411250
12421251 RpmHead * rpmhead ; /* header storage space */
1243- int rpmheadsize ;
1252+ unsigned int rpmheadsize ;
12441253};
12451254
12461255#endif
12471256
12481257
12491258#ifndef ENABLE_RPMPKG_LIBRPM
12501259
1251- static int
1252- headfromfp (struct rpmdbstate * state , const char * name , FILE * fp , unsigned char * lead , unsigned int cnt , unsigned int dsize , unsigned int pad , Chksum * chk1 , Chksum * chk2 )
1260+ static inline RpmHead *
1261+ realloc_head (struct rpmdbstate * state , unsigned int len )
12531262{
1254- RpmHead * rpmhead ;
1255- unsigned int len = 16 * cnt + dsize + pad ;
1256- if (len + 1 > state -> rpmheadsize )
1263+ if (len > state -> rpmheadsize )
12571264 {
12581265 state -> rpmheadsize = len + 128 ;
12591266 state -> rpmhead = solv_realloc (state -> rpmhead , sizeof (* state -> rpmhead ) + state -> rpmheadsize );
12601267 }
1261- rpmhead = state -> rpmhead ;
1268+ return state -> rpmhead ;
1269+ }
1270+
1271+ static int
1272+ headfromfp (struct rpmdbstate * state , const char * name , FILE * fp , unsigned char * lead , unsigned int cnt , unsigned int dsize , unsigned int pad , Chksum * chk1 , Chksum * chk2 )
1273+ {
1274+ unsigned int len = 16 * cnt + dsize + pad ;
1275+ RpmHead * rpmhead = realloc_head (state , len + 1 );
12621276 if (fread (rpmhead -> data , len , 1 , fp ) != 1 )
12631277 return pool_error (state -> pool , 0 , "%s: unexpected EOF" , name );
12641278 if (chk1 )
12651279 solv_chksum_add (chk1 , rpmhead -> data , len );
12661280 if (chk2 )
12671281 solv_chksum_add (chk2 , rpmhead -> data , len );
1268- rpmhead -> data [len ] = 0 ;
1269- rpmhead -> cnt = cnt ;
1270- rpmhead -> dcnt = dsize ;
1271- rpmhead -> dp = rpmhead -> data + cnt * 16 ;
1282+ headinit (rpmhead , cnt , dsize );
12721283 return 1 ;
12731284}
12741285
1275- #if defined(ENABLE_RPMDB_BYRPMHEADER )
1276- static void
1277- headfromblob (struct rpmdbstate * state , const unsigned char * blob , unsigned int cnt , unsigned int dsize )
1286+ # if defined(ENABLE_RPMDB ) && (!defined(ENABLE_RPMDB_LIBRPM ) || defined(HAVE_RPMDBNEXTITERATORHEADERBLOB ))
1287+
1288+ static int
1289+ headfromhdrblob (struct rpmdbstate * state , const unsigned char * data , unsigned int size )
12781290{
1291+ unsigned int dsize , cnt , len ;
12791292 RpmHead * rpmhead ;
1280- unsigned int len = 16 * cnt + dsize ;
1281- if (len + 1 > state -> rpmheadsize )
1282- {
1283- state -> rpmheadsize = len + 128 ;
1284- state -> rpmhead = solv_realloc (state -> rpmhead , sizeof (* state -> rpmhead ) + state -> rpmheadsize );
1285- }
1286- rpmhead = state -> rpmhead ;
1287- memcpy (rpmhead -> data , blob , len );
1288- rpmhead -> data [len ] = 0 ;
1289- rpmhead -> cnt = cnt ;
1290- rpmhead -> dcnt = dsize ;
1291- rpmhead -> dp = rpmhead -> data + cnt * 16 ;
1293+ if (size < 8 )
1294+ return pool_error (state -> pool , 0 , "corrupt rpm database (size)" );
1295+ cnt = getu32 (data );
1296+ dsize = getu32 (data + 4 );
1297+ if (cnt >= MAX_HDR_CNT || dsize >= MAX_HDR_DSIZE )
1298+ return pool_error (state -> pool , 0 , "corrupt rpm database (cnt/dcnt)" );
1299+ if (8 + cnt * 16 + dsize > size )
1300+ return pool_error (state -> pool , 0 , "corrupt rpm database (data size)" );
1301+ len = 16 * cnt + dsize ;
1302+ rpmhead = realloc_head (state , len + 1 );
1303+ memcpy (rpmhead -> data , data + 8 , len );
1304+ headinit (rpmhead , cnt , dsize );
1305+ return 1 ;
12921306}
1293- #endif
1307+
1308+ # endif
12941309
12951310#else
12961311
@@ -2497,7 +2512,8 @@ rpm_byrpmh(void *rpmstate, Header h)
24972512 struct rpmdbstate * state = rpmstate ;
24982513#ifndef ENABLE_RPMPKG_LIBRPM
24992514 const unsigned char * uh ;
2500- unsigned int dsize , cnt ;
2515+ unsigned int dsize , cnt , len ;
2516+ RpmHead * rpmhead ;
25012517
25022518 if (!h )
25032519 return 0 ;
@@ -2515,7 +2531,10 @@ rpm_byrpmh(void *rpmstate, Header h)
25152531 free ((void * )uh );
25162532 return 0 ;
25172533 }
2518- headfromblob (state , uh + 8 , cnt , dsize );
2534+ len = 16 * cnt + dsize ;
2535+ rpmhead = realloc_head (state , len + 1 );;
2536+ memcpy (rpmhead -> data , uh + 8 , len );
2537+ headinit (rpmhead , cnt , dsize );
25192538 free ((void * )uh );
25202539#else
25212540 if (!h )
0 commit comments