/src/LibRaw/src/metadata/adobepano.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2024 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | |
5 | | LibRaw is free software; you can redistribute it and/or modify |
6 | | it under the terms of the one of two licenses as you choose: |
7 | | |
8 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
9 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
10 | | |
11 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
12 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
13 | | |
14 | | */ |
15 | | |
16 | | #include "../../internal/dcraw_defs.h" |
17 | | |
18 | | void LibRaw::parseAdobePanoMakernote() |
19 | 14.8k | { |
20 | 14.8k | uchar *PrivateMknBuf; |
21 | 14.8k | unsigned posPrivateMknBuf; |
22 | 14.8k | unsigned PrivateMknLength; |
23 | 14.8k | unsigned PrivateOrder; |
24 | 14.8k | unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount; |
25 | 14.8k | unsigned PrivateTagBytes; |
26 | 14.8k | int truncated; |
27 | | |
28 | 14.8k | #define CHECKSPACE(s) \ |
29 | 53.6k | if (posPrivateMknBuf + (s) > PrivateMknLength) \ |
30 | 53.6k | { \ |
31 | 384 | free(PrivateMknBuf); \ |
32 | 384 | return; \ |
33 | 384 | } |
34 | | |
35 | 14.8k | order = 0x4d4d; |
36 | 14.8k | truncated = 0; |
37 | 14.8k | PrivateMknLength = get4(); |
38 | | |
39 | 14.8k | if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) && |
40 | 14.8k | (PrivateMknBuf = (uchar *)calloc(PrivateMknLength + 1024,1))) |
41 | 924 | { // 1024b for safety |
42 | 924 | fread(PrivateMknBuf, PrivateMknLength, 1, ifp); |
43 | 924 | PrivateOrder = sget2(PrivateMknBuf); |
44 | 924 | PrivateEntries = sget2(PrivateMknBuf + 2); |
45 | 924 | if ((PrivateEntries > 1000) || |
46 | 924 | ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) |
47 | 96 | { |
48 | 96 | free(PrivateMknBuf); |
49 | 96 | return; |
50 | 96 | } |
51 | 828 | posPrivateMknBuf = 4; |
52 | 3.31k | while (PrivateEntries--) |
53 | 3.21k | { |
54 | 3.21k | order = 0x4d4d; |
55 | 3.21k | CHECKSPACE(8); |
56 | 2.97k | PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); |
57 | 2.97k | PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
58 | 2.97k | PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4); |
59 | 2.97k | posPrivateMknBuf += 8; |
60 | 2.97k | order = PrivateOrder; |
61 | | |
62 | 2.97k | if (truncated && !PrivateTagCount) |
63 | 346 | continue; |
64 | | |
65 | 2.62k | PrivateTagBytes = PrivateTagCount * |
66 | 2.62k | tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0]; |
67 | 2.62k | if(PrivateTagBytes > 10240000u) |
68 | 308 | { |
69 | 308 | free(PrivateMknBuf); |
70 | 308 | return; |
71 | 308 | } |
72 | 2.32k | if (PrivateTagID == 0x0002) |
73 | 200 | { |
74 | 200 | posPrivateMknBuf += 2; |
75 | 200 | CHECKSPACE(2); |
76 | 200 | if (sget2(PrivateMknBuf + posPrivateMknBuf)) |
77 | 178 | { |
78 | 178 | truncated = 1; |
79 | 178 | } |
80 | 22 | else |
81 | 22 | { |
82 | 22 | posPrivateMknBuf += 2; |
83 | 22 | } |
84 | 200 | } |
85 | 2.12k | else if (PrivateTagID == 0x0013) |
86 | 106 | { |
87 | 106 | ushort nWB, cnt, tWB; |
88 | 106 | CHECKSPACE(2); |
89 | 106 | nWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
90 | 106 | posPrivateMknBuf += 2; |
91 | 106 | if (nWB > 0x100) |
92 | 0 | break; |
93 | 26.4k | for (cnt = 0; cnt < nWB; cnt++) |
94 | 26.3k | { |
95 | 26.3k | CHECKSPACE(2); |
96 | 26.3k | tWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
97 | 26.3k | if (tWB < 0x100) |
98 | 8.10k | { |
99 | 8.10k | CHECKSPACE(4); |
100 | 8.10k | icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
101 | 8.10k | icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); |
102 | 8.10k | icWBC[tWB][1] = icWBC[tWB][3] = 0x100; |
103 | 8.10k | } |
104 | 26.3k | posPrivateMknBuf += 6; |
105 | 26.3k | } |
106 | 106 | } |
107 | 2.01k | else if (PrivateTagID == 0x0027) |
108 | 184 | { |
109 | 184 | ushort nWB, cnt, tWB; |
110 | 184 | CHECKSPACE(2); |
111 | 184 | nWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
112 | 184 | posPrivateMknBuf += 2; |
113 | 184 | if (nWB > 0x100) |
114 | 32 | break; |
115 | 10.4k | for (cnt = 0; cnt < nWB; cnt++) |
116 | 10.4k | { |
117 | 10.4k | CHECKSPACE(2); |
118 | 10.3k | tWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
119 | 10.3k | if (tWB < 0x100) |
120 | 5.06k | { |
121 | 5.06k | CHECKSPACE(6); |
122 | 4.98k | icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
123 | 4.98k | icWBC[tWB][1] = icWBC[tWB][3] = |
124 | 4.98k | sget2(PrivateMknBuf + posPrivateMknBuf + 4); |
125 | 4.98k | icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6); |
126 | 4.98k | } |
127 | 10.2k | posPrivateMknBuf += 8; |
128 | 10.2k | } |
129 | 152 | } |
130 | 1.83k | else if (PrivateTagID == 0x0121) |
131 | 0 | { |
132 | 0 | CHECKSPACE(4); |
133 | 0 | imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf); |
134 | 0 | posPrivateMknBuf += 4; |
135 | 0 | } |
136 | 1.83k | else |
137 | 1.83k | { |
138 | 1.83k | if (PrivateTagBytes > 4) |
139 | 968 | posPrivateMknBuf += PrivateTagBytes; |
140 | 862 | else if (!truncated) |
141 | 704 | posPrivateMknBuf += 4; |
142 | 158 | else |
143 | 158 | { |
144 | 158 | if (PrivateTagBytes <= 2) |
145 | 158 | posPrivateMknBuf += 2; |
146 | 0 | else |
147 | 0 | posPrivateMknBuf += 4; |
148 | 158 | } |
149 | 1.83k | } |
150 | 2.32k | } |
151 | 136 | free(PrivateMknBuf); |
152 | 136 | } |
153 | 14.8k | #undef CHECKSPACE |
154 | 14.8k | } |