OLD | NEW |
1 /* exif-data.c | 1 /* exif-data.c |
2 * | 2 * |
3 * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net> | 3 * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net> |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Lesser General Public | 6 * modify it under the terms of the GNU Lesser General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 exif_mnote_data_load (data->priv->md, d, ds); | 774 exif_mnote_data_load (data->priv->md, d, ds); |
775 } | 775 } |
776 } | 776 } |
777 | 777 |
778 #define LOG_TOO_SMALL \ | 778 #define LOG_TOO_SMALL \ |
779 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \ | 779 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \ |
780 _("Size of data too small to allow for EXIF data.")); | 780 _("Size of data too small to allow for EXIF data.")); |
781 | 781 |
782 void | 782 void |
783 exif_data_load_data (ExifData *data, const unsigned char *d_orig, | 783 exif_data_load_data (ExifData *data, const unsigned char *d_orig, |
784 » » unsigned int ds_orig) | 784 » » unsigned int ds) |
785 { | 785 { |
786 unsigned int l; | 786 unsigned int l; |
787 ExifLong offset; | 787 ExifLong offset; |
788 ExifShort n; | 788 ExifShort n; |
789 const unsigned char *d = d_orig; | 789 const unsigned char *d = d_orig; |
790 » unsigned int ds = ds_orig, len; | 790 » unsigned int len, fullds; |
791 | 791 |
792 » if (!data || !data->priv || !d || !ds) | 792 » if (!data || !data->priv || !d || !ds) |
793 return; | 793 return; |
794 | 794 |
795 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 795 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
796 "Parsing %i byte(s) EXIF data...\n", ds); | 796 "Parsing %i byte(s) EXIF data...\n", ds); |
797 | 797 |
798 /* | 798 /* |
799 * It can be that the data starts with the EXIF header. If it does | 799 * It can be that the data starts with the EXIF header. If it does |
800 * not, search the EXIF marker. | 800 * not, search the EXIF marker. |
801 */ | 801 */ |
802 if (ds < 6) { | 802 if (ds < 6) { |
803 LOG_TOO_SMALL; | 803 LOG_TOO_SMALL; |
804 return; | 804 return; |
805 } | 805 } |
806 if (!memcmp (d, ExifHeader, 6)) { | 806 if (!memcmp (d, ExifHeader, 6)) { |
807 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 807 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
808 "Found EXIF header."); | 808 "Found EXIF header."); |
809 } else { | 809 } else { |
810 » » while (1) { | 810 » » while (ds >= 3) { |
811 » » » while ((d[0] == 0xff) && ds) { | 811 » » » while (ds && (d[0] == 0xff)) { |
812 d++; | 812 d++; |
813 ds--; | 813 ds--; |
814 } | 814 } |
815 | 815 |
816 /* JPEG_MARKER_SOI */ | 816 /* JPEG_MARKER_SOI */ |
817 » » » if (d[0] == JPEG_MARKER_SOI) { | 817 » » » if (ds && d[0] == JPEG_MARKER_SOI) { |
818 d++; | 818 d++; |
819 ds--; | 819 ds--; |
820 continue; | 820 continue; |
821 } | 821 } |
822 | 822 |
823 /* JPEG_MARKER_APP0 */ | 823 /* JPEG_MARKER_APP0 */ |
824 » » » if (d[0] == JPEG_MARKER_APP0) { | 824 » » » if (ds >= 3 && d[0] == JPEG_MARKER_APP0) { |
825 d++; | 825 d++; |
826 ds--; | 826 ds--; |
827 l = (d[0] << 8) | d[1]; | 827 l = (d[0] << 8) | d[1]; |
828 if (l > ds) | 828 if (l > ds) |
829 return; | 829 return; |
830 d += l; | 830 d += l; |
831 ds -= l; | 831 ds -= l; |
832 continue; | 832 continue; |
833 } | 833 } |
834 | 834 |
835 /* JPEG_MARKER_APP1 */ | 835 /* JPEG_MARKER_APP1 */ |
836 » » » if (d[0] == JPEG_MARKER_APP1) | 836 » » » if (ds && d[0] == JPEG_MARKER_APP1) |
837 break; | 837 break; |
838 | 838 |
839 /* Unknown marker or data. Give up. */ | 839 /* Unknown marker or data. Give up. */ |
840 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, | 840 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
841 "ExifData", _("EXIF marker not found.")); | 841 "ExifData", _("EXIF marker not found.")); |
842 return; | 842 return; |
843 } | 843 } |
| 844 if (ds < 3) { |
| 845 LOG_TOO_SMALL; |
| 846 return; |
| 847 } |
844 d++; | 848 d++; |
845 ds--; | 849 ds--; |
846 if (ds < 2) { | |
847 LOG_TOO_SMALL; | |
848 return; | |
849 } | |
850 len = (d[0] << 8) | d[1]; | 850 len = (d[0] << 8) | d[1]; |
851 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 851 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
852 "We have to deal with %i byte(s) of EXIF data.", | 852 "We have to deal with %i byte(s) of EXIF data.", |
853 len); | 853 len); |
854 d += 2; | 854 d += 2; |
855 ds -= 2; | 855 ds -= 2; |
856 } | 856 } |
857 | 857 |
858 /* | 858 /* |
859 * Verify the exif header | 859 * Verify the exif header |
860 * (offset 2, length 6). | 860 * (offset 2, length 6). |
861 */ | 861 */ |
862 if (ds < 6) { | 862 if (ds < 6) { |
863 LOG_TOO_SMALL; | 863 LOG_TOO_SMALL; |
864 return; | 864 return; |
865 } | 865 } |
866 if (memcmp (d, ExifHeader, 6)) { | 866 if (memcmp (d, ExifHeader, 6)) { |
867 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, | 867 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
868 "ExifData", _("EXIF header not found.")); | 868 "ExifData", _("EXIF header not found.")); |
869 return; | 869 return; |
870 } | 870 } |
871 | 871 |
872 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 872 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
873 "Found EXIF header."); | 873 "Found EXIF header."); |
874 | 874 |
875 » /* Byte order (offset 6, length 2) */ | 875 » /* Sanity check the data length */ |
876 if (ds < 14) | 876 if (ds < 14) |
877 return; | 877 return; |
| 878 |
| 879 /* The JPEG APP1 section can be no longer than 64 KiB (including a |
| 880 16-bit length), so cap the data length to protect against overflow |
| 881 in future offset calculations */ |
| 882 fullds = ds; |
| 883 if (ds > 0xfffe) |
| 884 ds = 0xfffe; |
| 885 |
| 886 /* Byte order (offset 6, length 2) */ |
878 if (!memcmp (d + 6, "II", 2)) | 887 if (!memcmp (d + 6, "II", 2)) |
879 data->priv->order = EXIF_BYTE_ORDER_INTEL; | 888 data->priv->order = EXIF_BYTE_ORDER_INTEL; |
880 else if (!memcmp (d + 6, "MM", 2)) | 889 else if (!memcmp (d + 6, "MM", 2)) |
881 data->priv->order = EXIF_BYTE_ORDER_MOTOROLA; | 890 data->priv->order = EXIF_BYTE_ORDER_MOTOROLA; |
882 else { | 891 else { |
883 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, | 892 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
884 "ExifData", _("Unknown encoding.")); | 893 "ExifData", _("Unknown encoding.")); |
885 return; | 894 return; |
886 } | 895 } |
887 | 896 |
888 /* Fixed value */ | 897 /* Fixed value */ |
889 if (exif_get_short (d + 8, data->priv->order) != 0x002a) | 898 if (exif_get_short (d + 8, data->priv->order) != 0x002a) |
890 return; | 899 return; |
891 | 900 |
892 /* IFD 0 offset */ | 901 /* IFD 0 offset */ |
893 offset = exif_get_long (d + 10, data->priv->order); | 902 offset = exif_get_long (d + 10, data->priv->order); |
894 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 903 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
895 "IFD 0 at %i.", (int) offset); | 904 "IFD 0 at %i.", (int) offset); |
896 | 905 |
| 906 /* Sanity check the offset, being careful about overflow */ |
| 907 if (offset > ds || offset + 6 + 2 > ds) |
| 908 return; |
| 909 |
897 /* Parse the actual exif data (usually offset 14 from start) */ | 910 /* Parse the actual exif data (usually offset 14 from start) */ |
898 exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0)
; | 911 exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0)
; |
899 | 912 |
900 /* IFD 1 offset */ | 913 /* IFD 1 offset */ |
901 » if (offset + 6 + 2 > ds) { | 914 » n = exif_get_short (d + 6 + offset, data->priv->order); |
| 915 » if (offset + 6 + 2 + 12 * n + 4 > ds) |
902 return; | 916 return; |
903 » } | 917 |
904 » n = exif_get_short (d + 6 + offset, data->priv->order); | |
905 » if (offset + 6 + 2 + 12 * n + 4 > ds) { | |
906 » » return; | |
907 » } | |
908 offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order); | 918 offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order); |
909 if (offset) { | 919 if (offset) { |
910 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", | 920 exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
911 "IFD 1 at %i.", (int) offset); | 921 "IFD 1 at %i.", (int) offset); |
912 | 922 |
913 /* Sanity check. */ | 923 /* Sanity check. */ |
914 » » if (offset > ds - 6) { | 924 » » if (offset > ds || offset + 6 > ds) { |
915 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, | 925 exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
916 "ExifData", "Bogus offset of IFD1."); | 926 "ExifData", "Bogus offset of IFD1."); |
917 } else { | 927 } else { |
918 exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6,
offset, 0); | 928 exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6,
offset, 0); |
919 } | 929 } |
920 } | 930 } |
921 | 931 |
922 /* | 932 /* |
923 * If we got an EXIF_TAG_MAKER_NOTE, try to interpret it. Some | 933 * If we got an EXIF_TAG_MAKER_NOTE, try to interpret it. Some |
924 * cameras use pointers in the maker note tag that point to the | 934 * cameras use pointers in the maker note tag that point to the |
925 * space between IFDs. Here is the only place where we have access | 935 * space between IFDs. Here is the only place where we have access |
926 * to that data. | 936 * to that data. |
927 */ | 937 */ |
928 » interpret_maker_note(data, d, ds); | 938 » interpret_maker_note(data, d, fullds); |
929 | 939 |
930 /* Fixup tags if requested */ | 940 /* Fixup tags if requested */ |
931 if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION) | 941 if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION) |
932 exif_data_fix (data); | 942 exif_data_fix (data); |
933 } | 943 } |
934 | 944 |
935 void | 945 void |
936 exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds) | 946 exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds) |
937 { | 947 { |
938 if (ds) | 948 if (ds) |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 return; | 1267 return; |
1258 | 1268 |
1259 d->priv->data_type = dt; | 1269 d->priv->data_type = dt; |
1260 } | 1270 } |
1261 | 1271 |
1262 ExifDataType | 1272 ExifDataType |
1263 exif_data_get_data_type (ExifData *d) | 1273 exif_data_get_data_type (ExifData *d) |
1264 { | 1274 { |
1265 return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_UNKNOWN; | 1275 return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_UNKNOWN; |
1266 } | 1276 } |
OLD | NEW |