1 /*
2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
345 * content is prepended, zip -A is run, then the prefix is
346 * detached!
347 */
348 jlong base_offset;
349
350 /** The position within the file of the start of the central directory. */
351 jlong censtart;
352
353 Byte *p;
354 Byte *bp;
355 Byte *buffer;
356 Byte locbuf[LOCHDR];
357
358 if ((buffer = (Byte*)malloc(BUFSIZE)) == NULL) {
359 return(-1);
360 }
361
362 bp = buffer;
363
364 if (find_positions(fd, bp, &base_offset, &censtart) == -1) {
365 return -1;
366 }
367 if (JLI_Lseek(fd, censtart, SEEK_SET) < (jlong) 0) {
368 return -1;
369 }
370
371 if ((bytes = read(fd, bp, MINREAD)) < 0) {
372 free(buffer);
373 return (-1);
374 }
375 p = bp;
376 /*
377 * Loop through the Central Directory Headers. Note that a valid zip/jar
378 * must have an ENDHDR (with ENDSIG) after the Central Directory.
379 */
380 while (CENSIG_AT(p)) {
381
382 /*
383 * If a complete header isn't in the buffer, shift the contents
384 * of the buffer down and refill the buffer. Note that the check
385 * for "bytes < CENHDR" must be made before the test for the entire
386 * size of the header, because if bytes is less than CENHDR, the
387 * actual size of the header can't be determined. The addition of
545 *nl++ = '\0';
546 }
547 }
548
549 /*
550 * Separate the name from the value;
551 */
552 cp = JLI_StrChr(*lp, (int)':');
553 if (cp == NULL)
554 return (-1);
555 *cp++ = '\0'; /* The colon terminates the name */
556 if (*cp != ' ')
557 return (-1);
558 *cp++ = '\0'; /* Eat the required space */
559 *name = *lp;
560 *value = cp;
561 *lp = nl;
562 return (1);
563 }
564
565 /*
566 * Read the manifest from the specified jar file and fill in the manifest_info
567 * structure with the information found within.
568 *
569 * Error returns are as follows:
570 * 0 Success
571 * -1 Unable to open jarfile
572 * -2 Error accessing the manifest from within the jarfile (most likely
573 * a manifest is not present, or this isn't a valid zip/jar file).
574 */
575 int
576 JLI_ParseManifest(char *jarfile, manifest_info *info)
577 {
578 int fd;
579 zentry entry;
580 char *lp;
581 char *name;
582 char *value;
583 int rc;
584 char *splashscreen_name = NULL;
585
586 if ((fd = open(jarfile, O_RDONLY
587 #ifdef O_LARGEFILE
588 | O_LARGEFILE /* large file mode */
589 #endif
590 #ifdef O_BINARY
591 | O_BINARY /* use binary mode on windows */
592 #endif
593 )) == -1) {
594 return (-1);
595 }
596 info->manifest_version = NULL;
597 info->main_class = NULL;
598 info->jre_version = NULL;
599 info->jre_restrict_search = 0;
600 info->splashscreen_image_file_name = NULL;
601 if ((rc = find_file(fd, &entry, manifest_name)) != 0) {
602 close(fd);
603 return (-2);
604 }
605 manifest = inflate_file(fd, &entry, NULL);
606 if (manifest == NULL) {
623 info->splashscreen_image_file_name = value;
624 }
625 }
626 close(fd);
627 if (rc == 0)
628 return (0);
629 else
630 return (-2);
631 }
632
633 /*
634 * Opens the jar file and unpacks the specified file from its contents.
635 * Returns NULL on failure.
636 */
637 void *
638 JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) {
639 int fd;
640 zentry entry;
641 void *data = NULL;
642
643 if ((fd = open(jarfile, O_RDONLY
644 #ifdef O_LARGEFILE
645 | O_LARGEFILE /* large file mode */
646 #endif
647 #ifdef O_BINARY
648 | O_BINARY /* use binary mode on windows */
649 #endif
650 )) == -1) {
651 return NULL;
652 }
653 if (find_file(fd, &entry, filename) == 0) {
654 data = inflate_file(fd, &entry, size);
655 }
656 close(fd);
657 return (data);
658 }
659
660 /*
661 * Specialized "free" function.
662 */
663 void
671 * Iterate over the manifest of the specified jar file and invoke the provided
672 * closure function for each attribute encountered.
673 *
674 * Error returns are as follows:
675 * 0 Success
676 * -1 Unable to open jarfile
677 * -2 Error accessing the manifest from within the jarfile (most likely
678 * this means a manifest is not present, or it isn't a valid zip/jar file).
679 */
680 JNIEXPORT int JNICALL
681 JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data)
682 {
683 int fd;
684 zentry entry;
685 char *mp; /* manifest pointer */
686 char *lp; /* pointer into manifest, updated during iteration */
687 char *name;
688 char *value;
689 int rc;
690
691 if ((fd = open(jarfile, O_RDONLY
692 #ifdef O_LARGEFILE
693 | O_LARGEFILE /* large file mode */
694 #endif
695 #ifdef O_BINARY
696 | O_BINARY /* use binary mode on windows */
697 #endif
698 )) == -1) {
699 return (-1);
700 }
701
702 if ((rc = find_file(fd, &entry, manifest_name)) != 0) {
703 close(fd);
704 return (-2);
705 }
706
707 mp = inflate_file(fd, &entry, NULL);
708 if (mp == NULL) {
709 close(fd);
710 return (-2);
711 }
|
1 /*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
345 * content is prepended, zip -A is run, then the prefix is
346 * detached!
347 */
348 jlong base_offset;
349
350 /** The position within the file of the start of the central directory. */
351 jlong censtart;
352
353 Byte *p;
354 Byte *bp;
355 Byte *buffer;
356 Byte locbuf[LOCHDR];
357
358 if ((buffer = (Byte*)malloc(BUFSIZE)) == NULL) {
359 return(-1);
360 }
361
362 bp = buffer;
363
364 if (find_positions(fd, bp, &base_offset, &censtart) == -1) {
365 free(buffer);
366 return -1;
367 }
368 if (JLI_Lseek(fd, censtart, SEEK_SET) < (jlong) 0) {
369 free(buffer);
370 return -1;
371 }
372
373 if ((bytes = read(fd, bp, MINREAD)) < 0) {
374 free(buffer);
375 return (-1);
376 }
377 p = bp;
378 /*
379 * Loop through the Central Directory Headers. Note that a valid zip/jar
380 * must have an ENDHDR (with ENDSIG) after the Central Directory.
381 */
382 while (CENSIG_AT(p)) {
383
384 /*
385 * If a complete header isn't in the buffer, shift the contents
386 * of the buffer down and refill the buffer. Note that the check
387 * for "bytes < CENHDR" must be made before the test for the entire
388 * size of the header, because if bytes is less than CENHDR, the
389 * actual size of the header can't be determined. The addition of
547 *nl++ = '\0';
548 }
549 }
550
551 /*
552 * Separate the name from the value;
553 */
554 cp = JLI_StrChr(*lp, (int)':');
555 if (cp == NULL)
556 return (-1);
557 *cp++ = '\0'; /* The colon terminates the name */
558 if (*cp != ' ')
559 return (-1);
560 *cp++ = '\0'; /* Eat the required space */
561 *name = *lp;
562 *value = cp;
563 *lp = nl;
564 return (1);
565 }
566
567 #ifdef _WIN32
568 int open_jarfile(const char* name, int flags);
569 #else
570 int open_jarfile(const char* name, int flags) { return open(name, flags); }
571 #endif
572
573 /*
574 * Read the manifest from the specified jar file and fill in the manifest_info
575 * structure with the information found within.
576 *
577 * Error returns are as follows:
578 * 0 Success
579 * -1 Unable to open jarfile
580 * -2 Error accessing the manifest from within the jarfile (most likely
581 * a manifest is not present, or this isn't a valid zip/jar file).
582 */
583 int
584 JLI_ParseManifest(char *jarfile, manifest_info *info)
585 {
586 int fd;
587 zentry entry;
588 char *lp;
589 char *name;
590 char *value;
591 int rc;
592 char *splashscreen_name = NULL;
593
594 if ((fd = open_jarfile(jarfile, O_RDONLY
595 #ifdef O_LARGEFILE
596 | O_LARGEFILE /* large file mode */
597 #endif
598 #ifdef O_BINARY
599 | O_BINARY /* use binary mode on windows */
600 #endif
601 )) == -1) {
602 return (-1);
603 }
604 info->manifest_version = NULL;
605 info->main_class = NULL;
606 info->jre_version = NULL;
607 info->jre_restrict_search = 0;
608 info->splashscreen_image_file_name = NULL;
609 if ((rc = find_file(fd, &entry, manifest_name)) != 0) {
610 close(fd);
611 return (-2);
612 }
613 manifest = inflate_file(fd, &entry, NULL);
614 if (manifest == NULL) {
631 info->splashscreen_image_file_name = value;
632 }
633 }
634 close(fd);
635 if (rc == 0)
636 return (0);
637 else
638 return (-2);
639 }
640
641 /*
642 * Opens the jar file and unpacks the specified file from its contents.
643 * Returns NULL on failure.
644 */
645 void *
646 JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) {
647 int fd;
648 zentry entry;
649 void *data = NULL;
650
651 if ((fd = open_jarfile(jarfile, O_RDONLY
652 #ifdef O_LARGEFILE
653 | O_LARGEFILE /* large file mode */
654 #endif
655 #ifdef O_BINARY
656 | O_BINARY /* use binary mode on windows */
657 #endif
658 )) == -1) {
659 return NULL;
660 }
661 if (find_file(fd, &entry, filename) == 0) {
662 data = inflate_file(fd, &entry, size);
663 }
664 close(fd);
665 return (data);
666 }
667
668 /*
669 * Specialized "free" function.
670 */
671 void
679 * Iterate over the manifest of the specified jar file and invoke the provided
680 * closure function for each attribute encountered.
681 *
682 * Error returns are as follows:
683 * 0 Success
684 * -1 Unable to open jarfile
685 * -2 Error accessing the manifest from within the jarfile (most likely
686 * this means a manifest is not present, or it isn't a valid zip/jar file).
687 */
688 JNIEXPORT int JNICALL
689 JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data)
690 {
691 int fd;
692 zentry entry;
693 char *mp; /* manifest pointer */
694 char *lp; /* pointer into manifest, updated during iteration */
695 char *name;
696 char *value;
697 int rc;
698
699 if ((fd = open_jarfile(jarfile, O_RDONLY
700 #ifdef O_LARGEFILE
701 | O_LARGEFILE /* large file mode */
702 #endif
703 #ifdef O_BINARY
704 | O_BINARY /* use binary mode on windows */
705 #endif
706 )) == -1) {
707 return (-1);
708 }
709
710 if ((rc = find_file(fd, &entry, manifest_name)) != 0) {
711 close(fd);
712 return (-2);
713 }
714
715 mp = inflate_file(fd, &entry, NULL);
716 if (mp == NULL) {
717 close(fd);
718 return (-2);
719 }
|