1 /* Integration test to ensure we issue FILE * leak diagnostics for 2 this particular non-trivial case. 3 Adapted from zlib/contrib/minizip/mztools.c, with all #includes 4 removed. */ 5 6 /* { dg-do "compile" } */ 7 8 /* Minimal replacement of system headers. */ 9 10 typedef __SIZE_TYPE__ size_t; 11 #define NULL ((void *) 0) 12 13 typedef struct _IO_FILE FILE; 14 extern FILE *fopen(const char *__restrict __filename, 15 const char *__restrict __modes); 16 extern size_t fread (void *__restrict __ptr, size_t __size, 17 size_t __n, FILE *__restrict __stream); 18 extern size_t fwrite (const void *__restrict __ptr, size_t __size, 19 size_t __n, FILE *__restrict __s); 20 extern int fclose (FILE *__stream); 21 extern int remove (const char *__filename) 22 __attribute__ ((__nothrow__ , __leaf__)); 23 24 extern void *malloc (size_t __size) 25 __attribute__ ((__nothrow__ , __leaf__)) 26 __attribute__ ((__malloc__)); 27 extern void free (void *__ptr) 28 __attribute__ ((__nothrow__ , __leaf__)); 29 30 extern size_t strlen (const char *__s) 31 __attribute__ ((__nothrow__ , __leaf__)) 32 __attribute__ ((__pure__)) 33 __attribute__ ((__nonnull__ (1))); 34 35 /* Minimal replacement of zlib headers. */ 36 37 #define ZEXPORT 38 typedef unsigned long uLong; /* 32 bits or more */ 39 #define Z_OK 0 40 #define Z_ERRNO (-1) 41 #define Z_STREAM_ERROR (-2) 42 #define Z_MEM_ERROR (-4) 43 44 /* 45 Additional tools for Minizip 46 Code: Xavier Roche '2004 47 License: Same as ZLIB (www.gzip.org) 48 */ 49 50 /* Code */ 51 52 #define READ_8(adr) ((unsigned char)*(adr)) 53 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) 54 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) 55 56 #define WRITE_8(buff, n) do { \ 57 *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ 58 } while(0) 59 #define WRITE_16(buff, n) do { \ 60 WRITE_8((unsigned char*)(buff), n); \ 61 WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ 62 } while(0) 63 #define WRITE_32(buff, n) do { \ 64 WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ 65 WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ 66 } while(0) 67 68 extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) 69 const char* file; 70 const char* fileOut; 71 const char* fileOutTmp; 72 uLong* nRecovered; 73 uLong* bytesRecovered; 74 { 75 int err = Z_OK; 76 FILE* fpZip = fopen(file, "rb"); 77 FILE* fpOut = fopen(fileOut, "wb"); 78 FILE* fpOutCD = fopen(fileOutTmp, "wb"); 79 if (fpZip != NULL && fpOut != NULL) { 80 int entries = 0; 81 uLong totalBytes = 0; 82 char header[30]; 83 char filename[1024]; 84 char extra[1024]; 85 int offset = 0; 86 int offsetCD = 0; 87 while ( fread(header, 1, 30, fpZip) == 30 ) { 88 int currentOffset = offset; 89 90 /* File entry */ 91 if (READ_32(header) == 0x04034b50) { 92 unsigned int version = READ_16(header + 4); 93 unsigned int gpflag = READ_16(header + 6); 94 unsigned int method = READ_16(header + 8); 95 unsigned int filetime = READ_16(header + 10); 96 unsigned int filedate = READ_16(header + 12); 97 unsigned int crc = READ_32(header + 14); /* crc */ 98 unsigned int cpsize = READ_32(header + 18); /* compressed size */ 99 unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ 100 unsigned int fnsize = READ_16(header + 26); /* file name length */ 101 unsigned int extsize = READ_16(header + 28); /* extra field length */ 102 filename[0] = extra[0] = '\0'; 103 104 /* Header */ 105 if (fwrite(header, 1, 30, fpOut) == 30) { 106 offset += 30; 107 } else { 108 err = Z_ERRNO; 109 break; 110 } 111 112 /* Filename */ 113 if (fnsize > 0) { 114 if (fnsize < sizeof(filename)) { 115 if (fread(filename, 1, fnsize, fpZip) == fnsize) { 116 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { 117 offset += fnsize; 118 } else { 119 err = Z_ERRNO; 120 break; 121 } 122 } else { 123 err = Z_ERRNO; 124 break; 125 } 126 } else { 127 err = Z_ERRNO; 128 break; 129 } 130 } else { 131 err = Z_STREAM_ERROR; 132 break; 133 } 134 135 /* Extra field */ 136 if (extsize > 0) { 137 if (extsize < sizeof(extra)) { 138 if (fread(extra, 1, extsize, fpZip) == extsize) { 139 if (fwrite(extra, 1, extsize, fpOut) == extsize) { 140 offset += extsize; 141 } else { 142 err = Z_ERRNO; 143 break; 144 } 145 } else { 146 err = Z_ERRNO; 147 break; 148 } 149 } else { 150 err = Z_ERRNO; 151 break; 152 } 153 } 154 155 /* Data */ 156 { 157 int dataSize = cpsize; 158 if (dataSize == 0) { 159 dataSize = uncpsize; 160 } 161 if (dataSize > 0) { 162 char* data = malloc(dataSize); 163 if (data != NULL) { 164 if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { 165 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { 166 offset += dataSize; 167 totalBytes += dataSize; 168 } else { 169 err = Z_ERRNO; 170 } 171 } else { 172 err = Z_ERRNO; 173 } 174 free(data); 175 if (err != Z_OK) { 176 break; 177 } 178 } else { 179 err = Z_MEM_ERROR; 180 break; 181 } 182 } 183 } 184 185 /* Central directory entry */ 186 { 187 char header[46]; 188 char* comment = ""; 189 int comsize = (int) strlen(comment); 190 WRITE_32(header, 0x02014b50); 191 WRITE_16(header + 4, version); 192 WRITE_16(header + 6, version); 193 WRITE_16(header + 8, gpflag); 194 WRITE_16(header + 10, method); 195 WRITE_16(header + 12, filetime); 196 WRITE_16(header + 14, filedate); 197 WRITE_32(header + 16, crc); 198 WRITE_32(header + 20, cpsize); 199 WRITE_32(header + 24, uncpsize); 200 WRITE_16(header + 28, fnsize); 201 WRITE_16(header + 30, extsize); 202 WRITE_16(header + 32, comsize); 203 WRITE_16(header + 34, 0); /* disk # */ 204 WRITE_16(header + 36, 0); /* int attrb */ 205 WRITE_32(header + 38, 0); /* ext attrb */ 206 WRITE_32(header + 42, currentOffset); 207 /* Header */ 208 if (fwrite(header, 1, 46, fpOutCD) == 46) { 209 offsetCD += 46; 210 211 /* Filename */ 212 if (fnsize > 0) { 213 if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { 214 offsetCD += fnsize; 215 } else { 216 err = Z_ERRNO; 217 break; 218 } 219 } else { 220 err = Z_STREAM_ERROR; 221 break; 222 } 223 224 /* Extra field */ 225 if (extsize > 0) { 226 if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { 227 offsetCD += extsize; 228 } else { 229 err = Z_ERRNO; 230 break; 231 } 232 } 233 234 /* Comment field */ 235 if (comsize > 0) { 236 if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { 237 offsetCD += comsize; 238 } else { 239 err = Z_ERRNO; 240 break; 241 } 242 } 243 244 245 } else { 246 err = Z_ERRNO; 247 break; 248 } 249 } 250 251 /* Success */ 252 entries++; 253 254 } else { 255 break; 256 } 257 } 258 259 /* Final central directory */ 260 { 261 int entriesZip = entries; 262 char header[22]; 263 char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; 264 int comsize = (int) strlen(comment); 265 if (entriesZip > 0xffff) { 266 entriesZip = 0xffff; 267 } 268 WRITE_32(header, 0x06054b50); 269 WRITE_16(header + 4, 0); /* disk # */ 270 WRITE_16(header + 6, 0); /* disk # */ 271 WRITE_16(header + 8, entriesZip); /* hack */ 272 WRITE_16(header + 10, entriesZip); /* hack */ 273 WRITE_32(header + 12, offsetCD); /* size of CD */ 274 WRITE_32(header + 16, offset); /* offset to CD */ 275 WRITE_16(header + 20, comsize); /* comment */ 276 277 /* Header */ 278 if (fwrite(header, 1, 22, fpOutCD) == 22) { 279 280 /* Comment field */ 281 if (comsize > 0) { 282 if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { 283 err = Z_ERRNO; 284 } 285 } 286 287 } else { 288 err = Z_ERRNO; 289 } 290 } 291 292 /* Final merge (file + central directory) */ 293 fclose(fpOutCD); 294 if (err == Z_OK) { 295 fpOutCD = fopen(fileOutTmp, "rb"); 296 if (fpOutCD != NULL) { 297 int nRead; 298 char buffer[8192]; 299 while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { 300 if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { 301 err = Z_ERRNO; 302 break; 303 } 304 } 305 fclose(fpOutCD); 306 } 307 } 308 309 /* Close */ 310 fclose(fpZip); 311 fclose(fpOut); 312 313 /* Wipe temporary file */ 314 (void)remove(fileOutTmp); 315 316 /* Number of recovered entries */ 317 if (err == Z_OK) { 318 if (nRecovered != NULL) { 319 *nRecovered = entries; 320 } 321 if (bytesRecovered != NULL) { 322 *bytesRecovered = totalBytes; 323 } 324 } 325 } else { 326 err = Z_STREAM_ERROR; 327 } 328 return err; /* { dg-warning "leak of FILE 'fpZip'" "leak of fpZip" } */ 329 /* { dg-warning "leak of FILE 'fpOut'" "leak of fpOut" { target *-*-* } .-1 } */ 330 /* { dg-warning "leak of FILE 'fpOutCD'" "leak of fpOutCD" { target *-*-* } .-2 } */ 331 } 332