Coverage Report

Created: 2025-07-16 07:53

/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
}