Bug Summary

File:s/cmd/signtool/zip.c
Warning:line 73, column 9
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name zip.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/signtool -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/signtool -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c zip.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "signtool.h"
6#include "zip.h"
7#include "zlib.h"
8#include "prmem.h"
9
10static void inttox(int in, char *out);
11static void longtox(long in, char *out);
12
13/****************************************************************
14 *
15 * J z i p O p e n
16 *
17 * Opens a new ZIP file and creates a new ZIPfile structure to
18 * control the process of installing files into a zip.
19 */
20ZIPfile *
21JzipOpen(char *filename, char *comment)
22{
23 ZIPfile *zipfile;
24 PRExplodedTime prtime;
25
26 zipfile = PORT_ZAllocPORT_ZAlloc_Util(sizeof(ZIPfile));
27 if (!zipfile)
1
Assuming 'zipfile' is non-null
2
Taking false branch
28 out_of_memory();
29
30 /* Construct time and date */
31 PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime);
32 zipfile->date = ((prtime.tm_year - 1980) << 9) |
33 ((prtime.tm_month + 1) << 5) |
34 prtime.tm_mday;
35 zipfile->time = (prtime.tm_hour << 11) |
36 (prtime.tm_min << 5) |
37 (prtime.tm_sec & 0x3f);
38
39 zipfile->fp = NULL((void*)0);
40 if (filename &&
3
Assuming 'filename' is null
41 (zipfile->fp = PR_Open(filename,
42 PR_WRONLY0x02 |
43 PR_CREATE_FILE0x08 |
44 PR_TRUNCATE0x20,
45 0777)) == NULL((void*)0)) {
46 char *nsprErr;
47 if (PR_GetErrorTextLength()) {
48 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
49 PR_GetErrorText(nsprErr);
50 } else {
51 nsprErr = NULL((void*)0);
52 }
53 PR_fprintf(errorFD, "%s: can't open output jar, %s.%s\n",
54 PROGRAM_NAME"signtool",
55 filename, nsprErr ? nsprErr : "");
56 if (nsprErr)
57 PR_Free(nsprErr);
58 errorCount++;
59 exit(ERRX(-1));
60 }
61
62 zipfile->list = NULL((void*)0);
63 if (filename
3.1
'filename' is null
) {
4
Taking false branch
64 zipfile->filename = PORT_ZAllocPORT_ZAlloc_Util(strlen(filename) + 1);
65 if (!zipfile->filename)
66 out_of_memory();
67 PORT_Strcpystrcpy(zipfile->filename, filename);
68 }
69 if (comment) {
5
Assuming 'comment' is non-null
6
Taking true branch
70 zipfile->comment = PORT_ZAllocPORT_ZAlloc_Util(strlen(comment) + 1);
7
Value assigned to field 'comment'
71 if (!zipfile->comment)
8
Assuming field 'comment' is null
9
Taking true branch
72 out_of_memory();
73 PORT_Strcpystrcpy(zipfile->comment, comment);
10
Null pointer passed to 1st parameter expecting 'nonnull'
74 }
75
76 return zipfile;
77}
78
79static void *
80my_alloc_func(void *opaque, uInt items, uInt size)
81{
82 return PORT_AllocPORT_Alloc_Util(items * size);
83}
84
85static void
86my_free_func(void *opaque, void *address)
87{
88 PORT_FreePORT_Free_Util(address);
89}
90
91static void
92handle_zerror(int err, char *msg)
93{
94 if (!msg) {
95 msg = "";
96 }
97
98 errorCount++; /* unless Z_OK...see below */
99
100 switch (err) {
101 case Z_OK0:
102 PR_fprintf(errorFD, "No error: %s\n", msg);
103 errorCount--; /* this was incremented above */
104 break;
105 case Z_MEM_ERROR(-4):
106 PR_fprintf(errorFD, "Deflation ran out of memory: %s\n", msg);
107 break;
108 case Z_STREAM_ERROR(-2):
109 PR_fprintf(errorFD, "Invalid compression level: %s\n", msg);
110 break;
111 case Z_VERSION_ERROR(-6):
112 PR_fprintf(errorFD, "Incompatible compression library version: %s\n",
113 msg);
114 break;
115 case Z_DATA_ERROR(-3):
116 PR_fprintf(errorFD, "Compression data error: %s\n", msg);
117 break;
118 default:
119 PR_fprintf(errorFD, "Unknown error in compression library: %s\n", msg);
120 break;
121 }
122}
123
124/****************************************************************
125 *
126 * J z i p A d d
127 *
128 * Adds a new file into a ZIP file. The ZIP file must have already
129 * been opened with JzipOpen.
130 */
131int
132JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int lvl)
133{
134 ZIPentry *entry;
135 PRFileDesc *readfp;
136 PRFileDesc *zipfp;
137 unsigned long crc;
138 unsigned long local_size_pos;
139 int num;
140 int err;
141 int deflate_percent;
142 z_stream zstream;
143 Bytef inbuf[BUFSIZ8192];
144 Bytef outbuf[BUFSIZ8192];
145
146 if (!fullname || !filename || !zipfile) {
147 return -1;
148 }
149
150 zipfp = zipfile->fp;
151 if (!zipfp)
152 return -1;
153
154 if ((readfp = PR_Open(fullname, PR_RDONLY0x01, 0777)) == NULL((void*)0)) {
155 char *nsprErr;
156 if (PR_GetErrorTextLength()) {
157 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
158 PR_GetErrorText(nsprErr);
159 } else {
160 nsprErr = NULL((void*)0);
161 }
162 PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr : "");
163 errorCount++;
164 if (nsprErr)
165 PR_Free(nsprErr);
166 exit(ERRX(-1));
167 }
168
169 /*
170 * Make sure the input file is not the output file.
171 * Add a few bytes to the end of the JAR file and see if the input file
172 * twitches
173 */
174 {
175 PRInt32 endOfJar;
176 PRInt32 inputSize;
177 PRBool isSame;
178
179 inputSize = PR_Available(readfp);
180
181 endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR);
182
183 if (PR_Write(zipfp, "abcde", 5) < 5) {
184 char *nsprErr;
185
186 if (PR_GetErrorTextLength()) {
187 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
188 PR_GetErrorText(nsprErr);
189 } else {
190 nsprErr = NULL((void*)0);
191 }
192 PR_fprintf(errorFD, "Writing to zip file: %s\n",
193 nsprErr ? nsprErr : "");
194 if (nsprErr)
195 PR_Free(nsprErr);
196 errorCount++;
197 exit(ERRX(-1));
198 }
199
200 isSame = (PR_Available(readfp) != inputSize);
201
202 PR_Seek(zipfp, endOfJar, PR_SEEK_SET);
203
204 if (isSame) {
205 /* It's the same file! Forget it! */
206 PR_Close(readfp);
207 return 0;
208 }
209 }
210
211 if (verbosity >= 0) {
212 PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename);
213 }
214
215 entry = PORT_ZAllocPORT_ZAlloc_Util(sizeof(ZIPentry));
216 if (!entry)
217 out_of_memory();
218
219 entry->filename = PORT_StrdupPORT_Strdup_Util(filename);
220 entry->comment = NULL((void*)0);
221
222 /* Set up local file header */
223 longtox(LSIG0x04034B50l, entry->local.signature);
224 inttox(strlen(filename), entry->local.filename_len);
225 inttox(zipfile->time, entry->local.time);
226 inttox(zipfile->date, entry->local.date);
227 inttox(Z_DEFLATED8, entry->local.method);
228
229 /* Set up central directory entry */
230 longtox(CSIG0x02014B50l, entry->central.signature);
231 inttox(strlen(filename), entry->central.filename_len);
232 if (entry->comment) {
233 inttox(strlen(entry->comment), entry->central.commentfield_len);
234 }
235 longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR),
236 entry->central.localhdr_offset);
237 inttox(zipfile->time, entry->central.time);
238 inttox(zipfile->date, entry->central.date);
239 inttox(Z_DEFLATED8, entry->central.method);
240
241 /* Compute crc. Too bad we have to process the whole file to do this*/
242 crc = crc32(0L, NULL((void*)0), 0);
243 while ((num = PR_Read(readfp, inbuf, BUFSIZ8192)) > 0) {
244 crc = crc32(crc, inbuf, num);
245 }
246 PR_Seek(readfp, 0L, PR_SEEK_SET);
247
248 /* Store CRC */
249 longtox(crc, entry->local.crc32);
250 longtox(crc, entry->central.crc32);
251
252 /* Stick this entry onto the end of the list */
253 entry->next = NULL((void*)0);
254 if (zipfile->list == NULL((void*)0)) {
255 /* First entry */
256 zipfile->list = entry;
257 } else {
258 ZIPentry *pe;
259
260 pe = zipfile->list;
261 while (pe->next != NULL((void*)0)) {
262 pe = pe->next;
263 }
264 pe->next = entry;
265 }
266
267 /*
268 * Start writing stuff out
269 */
270
271 local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18;
272 /* File header */
273 if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal)) <
274 sizeof(struct ZipLocal)) {
275 char *nsprErr;
276 if (PR_GetErrorTextLength()) {
277 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
278 PR_GetErrorText(nsprErr);
279 } else {
280 nsprErr = NULL((void*)0);
281 }
282 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
283 if (nsprErr)
284 PR_Free(nsprErr);
285 errorCount++;
286 exit(ERRX(-1));
287 }
288
289 /* File Name */
290 if (PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) {
291 char *nsprErr;
292 if (PR_GetErrorTextLength()) {
293 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
294 PR_GetErrorText(nsprErr);
295 } else {
296 nsprErr = NULL((void*)0);
297 }
298 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
299 if (nsprErr)
300 PR_Free(nsprErr);
301 errorCount++;
302 exit(ERRX(-1));
303 }
304
305 /*
306 * File data
307 */
308 /* Initialize zstream */
309 zstream.zalloc = my_alloc_func;
310 zstream.zfree = my_free_func;
311 zstream.opaque = NULL((void*)0);
312 zstream.next_in = inbuf;
313 zstream.avail_in = BUFSIZ8192;
314 zstream.next_out = outbuf;
315 zstream.avail_out = BUFSIZ8192;
316 /* Setting the windowBits to -MAX_WBITS is an undocumented feature of
317 * zlib (see deflate.c in zlib). It is the same thing that Java does
318 * when you specify the nowrap option for deflation in java.util.zip.
319 * It causes zlib to leave out its headers and footers, which don't
320 * work in PKZIP files.
321 */
322 err = deflateInit2(&zstream, lvl, Z_DEFLATED,deflateInit2_((&zstream),(lvl),(8),(-15),(8), (0), "1.3",
(int)sizeof(z_stream))
323 -MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY)deflateInit2_((&zstream),(lvl),(8),(-15),(8), (0), "1.3",
(int)sizeof(z_stream))
;
324 if (err != Z_OK0) {
325 handle_zerror(err, zstream.msg);
326 exit(ERRX(-1));
327 }
328
329 while ((zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ8192)) > 0) {
330 zstream.next_in = inbuf;
331 /* Process this chunk of data */
332 while (zstream.avail_in > 0) {
333 err = deflate(&zstream, Z_NO_FLUSH0);
334 if (err != Z_OK0) {
335 handle_zerror(err, zstream.msg);
336 exit(ERRX(-1));
337 }
338 if (zstream.avail_out <= 0) {
339 if (PR_Write(zipfp, outbuf, BUFSIZ8192) < BUFSIZ8192) {
340 char *nsprErr;
341 if (PR_GetErrorTextLength()) {
342 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
343 PR_GetErrorText(nsprErr);
344 } else {
345 nsprErr = NULL((void*)0);
346 }
347 PR_fprintf(errorFD, "Writing zip data: %s\n",
348 nsprErr ? nsprErr : "");
349 if (nsprErr)
350 PR_Free(nsprErr);
351 errorCount++;
352 exit(ERRX(-1));
353 }
354 zstream.next_out = outbuf;
355 zstream.avail_out = BUFSIZ8192;
356 }
357 }
358 }
359
360 /* Now flush everything */
361 while (1) {
362 err = deflate(&zstream, Z_FINISH4);
363 if (err == Z_STREAM_END1) {
364 break;
365 } else if (err == Z_OK0) {
366 /* output buffer full, repeat */
367 } else {
368 handle_zerror(err, zstream.msg);
369 exit(ERRX(-1));
370 }
371 if (PR_Write(zipfp, outbuf, BUFSIZ8192) < BUFSIZ8192) {
372 char *nsprErr;
373 if (PR_GetErrorTextLength()) {
374 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
375 PR_GetErrorText(nsprErr);
376 } else {
377 nsprErr = NULL((void*)0);
378 }
379 PR_fprintf(errorFD, "Writing zip data: %s\n",
380 nsprErr ? nsprErr : "");
381 if (nsprErr)
382 PR_Free(nsprErr);
383 errorCount++;
384 exit(ERRX(-1));
385 }
386 zstream.avail_out = BUFSIZ8192;
387 zstream.next_out = outbuf;
388 }
389
390 /* If there's any output left, write it out. */
391 if (zstream.next_out != outbuf) {
392 if (PR_Write(zipfp, outbuf, zstream.next_out - outbuf) <
393 zstream.next_out - outbuf) {
394 char *nsprErr;
395 if (PR_GetErrorTextLength()) {
396 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
397 PR_GetErrorText(nsprErr);
398 } else {
399 nsprErr = NULL((void*)0);
400 }
401 PR_fprintf(errorFD, "Writing zip data: %s\n",
402 nsprErr ? nsprErr : "");
403 if (nsprErr)
404 PR_Free(nsprErr);
405 errorCount++;
406 exit(ERRX(-1));
407 }
408 zstream.avail_out = BUFSIZ8192;
409 zstream.next_out = outbuf;
410 }
411
412 /* Now that we know the compressed size, write this to the headers */
413 longtox(zstream.total_in, entry->local.orglen);
414 longtox(zstream.total_out, entry->local.size);
415 if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) {
416 char *nsprErr;
417 if (PR_GetErrorTextLength()) {
418 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
419 PR_GetErrorText(nsprErr);
420 } else {
421 nsprErr = NULL((void*)0);
422 }
423 PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : "");
424 if (nsprErr)
425 PR_Free(nsprErr);
426 errorCount++;
427 exit(ERRX(-1));
428 }
429 if (PR_Write(zipfp, entry->local.size, 8) != 8) {
430 char *nsprErr;
431 if (PR_GetErrorTextLength()) {
432 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
433 PR_GetErrorText(nsprErr);
434 } else {
435 nsprErr = NULL((void*)0);
436 }
437 PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
438 if (nsprErr)
439 PR_Free(nsprErr);
440 errorCount++;
441 exit(ERRX(-1));
442 }
443 if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) {
444 char *nsprErr;
445 if (PR_GetErrorTextLength()) {
446 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
447 PR_GetErrorText(nsprErr);
448 } else {
449 nsprErr = NULL((void*)0);
450 }
451 PR_fprintf(errorFD, "Accessing zip file: %s\n",
452 nsprErr ? nsprErr : "");
453 if (nsprErr)
454 PR_Free(nsprErr);
455 errorCount++;
456 exit(ERRX(-1));
457 }
458 longtox(zstream.total_in, entry->central.orglen);
459 longtox(zstream.total_out, entry->central.size);
460
461 /* Close out the deflation operation */
462 err = deflateEnd(&zstream);
463 if (err != Z_OK0) {
464 handle_zerror(err, zstream.msg);
465 exit(ERRX(-1));
466 }
467
468 PR_Close(readfp);
469
470 if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) {
471 deflate_percent = (int)((zstream.total_in -
472 zstream.total_out) *
473 100 / zstream.total_in);
474 } else {
475 deflate_percent = 0;
476 }
477 if (verbosity >= 0) {
478 PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent);
479 }
480
481 return 0;
482}
483
484/********************************************************************
485 * J z i p C l o s e
486 *
487 * Finishes the ZipFile. ALSO DELETES THE ZIPFILE STRUCTURE PASSED IN!!
488 */
489int
490JzipClose(ZIPfile *zipfile)
491{
492 ZIPentry *pe, *dead;
493 PRFileDesc *zipfp;
494 struct ZipEnd zipend;
495 unsigned int entrycount = 0;
496
497 if (!zipfile) {
498 return -1;
499 }
500
501 if (!zipfile->filename) {
502 /* bogus */
503 return 0;
504 }
505
506 zipfp = zipfile->fp;
507 zipfile->central_start = PR_Seek(zipfp, 0L, PR_SEEK_CUR);
508
509 /* Write out all the central directories */
510 pe = zipfile->list;
511 while (pe) {
512 entrycount++;
513
514 /* Write central directory info */
515 if (PR_Write(zipfp, &pe->central, sizeof(struct ZipCentral)) <
516 sizeof(struct ZipCentral)) {
517 char *nsprErr;
518 if (PR_GetErrorTextLength()) {
519 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
520 PR_GetErrorText(nsprErr);
521 } else {
522 nsprErr = NULL((void*)0);
523 }
524 PR_fprintf(errorFD, "Writing zip data: %s\n",
525 nsprErr ? nsprErr : "");
526 if (nsprErr)
527 PR_Free(nsprErr);
528 errorCount++;
529 exit(ERRX(-1));
530 }
531
532 /* Write filename */
533 if (PR_Write(zipfp, pe->filename, strlen(pe->filename)) <
534 strlen(pe->filename)) {
535 char *nsprErr;
536 if (PR_GetErrorTextLength()) {
537 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
538 PR_GetErrorText(nsprErr);
539 } else {
540 nsprErr = NULL((void*)0);
541 }
542 PR_fprintf(errorFD, "Writing zip data: %s\n",
543 nsprErr ? nsprErr : "");
544 if (nsprErr)
545 PR_Free(nsprErr);
546 errorCount++;
547 exit(ERRX(-1));
548 }
549
550 /* Write file comment */
551 if (pe->comment) {
552 if (PR_Write(zipfp, pe->comment, strlen(pe->comment)) <
553 strlen(pe->comment)) {
554 char *nsprErr;
555 if (PR_GetErrorTextLength()) {
556 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
557 PR_GetErrorText(nsprErr);
558 } else {
559 nsprErr = NULL((void*)0);
560 }
561 PR_fprintf(errorFD, "Writing zip data: %s\n",
562 nsprErr ? nsprErr : "");
563 if (nsprErr)
564 PR_Free(nsprErr);
565 errorCount++;
566 exit(ERRX(-1));
567 }
568 }
569
570 /* Delete the structure */
571 dead = pe;
572 pe = pe->next;
573 if (dead->filename) {
574 PORT_FreePORT_Free_Util(dead->filename);
575 }
576 if (dead->comment) {
577 PORT_FreePORT_Free_Util(dead->comment);
578 }
579 PORT_FreePORT_Free_Util(dead);
580 }
581 zipfile->central_end = PR_Seek(zipfile->fp, 0L, PR_SEEK_CUR);
582
583 /* Create the ZipEnd structure */
584 PORT_Memsetmemset(&zipend, 0, sizeof(zipend));
585 longtox(ESIG0x06054B50l, zipend.signature);
586 inttox(entrycount, zipend.total_entries_disk);
587 inttox(entrycount, zipend.total_entries_archive);
588 longtox(zipfile->central_end - zipfile->central_start,
589 zipend.central_dir_size);
590 longtox(zipfile->central_start, zipend.offset_central_dir);
591 if (zipfile->comment) {
592 inttox(strlen(zipfile->comment), zipend.commentfield_len);
593 }
594
595 /* Write out ZipEnd xtructure */
596 if (PR_Write(zipfp, &zipend, sizeof(zipend)) < sizeof(zipend)) {
597 char *nsprErr;
598 if (PR_GetErrorTextLength()) {
599 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
600 PR_GetErrorText(nsprErr);
601 } else {
602 nsprErr = NULL((void*)0);
603 }
604 PR_fprintf(errorFD, "Writing zip data: %s\n",
605 nsprErr ? nsprErr : "");
606 if (nsprErr)
607 PR_Free(nsprErr);
608 errorCount++;
609 exit(ERRX(-1));
610 }
611
612 /* Write out Zipfile comment */
613 if (zipfile->comment) {
614 if (PR_Write(zipfp, zipfile->comment, strlen(zipfile->comment)) <
615 strlen(zipfile->comment)) {
616 char *nsprErr;
617 if (PR_GetErrorTextLength()) {
618 nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
619 PR_GetErrorText(nsprErr);
620 } else {
621 nsprErr = NULL((void*)0);
622 }
623 PR_fprintf(errorFD, "Writing zip data: %s\n",
624 nsprErr ? nsprErr : "");
625 if (nsprErr)
626 PR_Free(nsprErr);
627 errorCount++;
628 exit(ERRX(-1));
629 }
630 }
631
632 PR_Close(zipfp);
633
634 /* Free the memory of the zipfile structure */
635 if (zipfile->filename) {
636 PORT_FreePORT_Free_Util(zipfile->filename);
637 }
638 if (zipfile->comment) {
639 PORT_FreePORT_Free_Util(zipfile->comment);
640 }
641 PORT_FreePORT_Free_Util(zipfile);
642
643 return 0;
644}
645
646/**********************************************
647 * i n t t o x
648 *
649 * Converts a two byte ugly endianed integer
650 * to our platform's integer.
651 *
652 */
653
654static void
655inttox(int in, char *out)
656{
657 out[0] = (in & 0xFF);
658 out[1] = (in & 0xFF00) >> 8;
659}
660
661/*********************************************
662 * l o n g t o x
663 *
664 * Converts a four byte ugly endianed integer
665 * to our platform's integer.
666 *
667 */
668
669static void
670longtox(long in, char *out)
671{
672 out[0] = (in & 0xFF);
673 out[1] = (in & 0xFF00) >> 8;
674 out[2] = (in & 0xFF0000) >> 16;
675 out[3] = (in & 0xFF000000) >> 24;
676}