Coverage Report

Created: 2025-11-14 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/adobepano.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 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
11.3k
{
20
11.3k
  uchar *PrivateMknBuf;
21
11.3k
  unsigned posPrivateMknBuf;
22
11.3k
  unsigned PrivateMknLength;
23
11.3k
  unsigned PrivateOrder;
24
11.3k
  unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount;
25
11.3k
  unsigned PrivateTagBytes;
26
11.3k
  int truncated;
27
28
11.3k
#define CHECKSPACE(s)                                                          \
29
173k
  if (posPrivateMknBuf + (s) > PrivateMknLength)                               \
30
173k
  {                                                                            \
31
1.63k
    free(PrivateMknBuf);                                                       \
32
1.63k
    return;                                                                    \
33
1.63k
  }
34
35
11.3k
  order = 0x4d4d;
36
11.3k
  truncated = 0;
37
11.3k
  PrivateMknLength = get4();
38
39
11.3k
  if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
40
3.78k
      (PrivateMknBuf = (uchar *)calloc(PrivateMknLength + 1024,1)))
41
3.78k
  { // 1024b for safety
42
3.78k
    fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
43
3.78k
    PrivateOrder = sget2(PrivateMknBuf);
44
3.78k
    PrivateEntries = sget2(PrivateMknBuf + 2);
45
3.78k
    if ((PrivateEntries > 1000) ||
46
3.56k
        ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
47
465
    {
48
465
      free(PrivateMknBuf);
49
465
      return;
50
465
    }
51
3.32k
    posPrivateMknBuf = 4;
52
75.9k
    while (PrivateEntries--)
53
75.5k
    {
54
75.5k
      order = 0x4d4d;
55
75.5k
      CHECKSPACE(8);
56
74.8k
      PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
57
74.8k
      PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
58
74.8k
      PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4);
59
74.8k
      posPrivateMknBuf += 8;
60
74.8k
      order = PrivateOrder;
61
62
74.8k
      if (truncated && !PrivateTagCount)
63
3.22k
        continue;
64
65
71.6k
      PrivateTagBytes = PrivateTagCount *
66
71.6k
          tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0];
67
71.6k
      if(PrivateTagBytes > 10240000u)
68
961
      {
69
961
         free(PrivateMknBuf);
70
961
         return;
71
961
      }
72
70.6k
      if (PrivateTagID == 0x0002)
73
1.36k
      {
74
1.36k
        posPrivateMknBuf += 2;
75
1.36k
        CHECKSPACE(2);
76
1.32k
        if (sget2(PrivateMknBuf + posPrivateMknBuf))
77
453
        {
78
453
          truncated = 1;
79
453
        }
80
876
        else
81
876
        {
82
876
          posPrivateMknBuf += 2;
83
876
        }
84
1.32k
      }
85
69.3k
      else if (PrivateTagID == 0x0013)
86
1.45k
      {
87
1.45k
        ushort nWB, cnt, tWB;
88
1.45k
        CHECKSPACE(2);
89
1.37k
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
90
1.37k
        posPrivateMknBuf += 2;
91
1.37k
        if (nWB > 0x100)
92
249
          break;
93
55.6k
        for (cnt = 0; cnt < nWB; cnt++)
94
55.0k
        {
95
55.0k
          CHECKSPACE(2);
96
54.8k
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
97
54.8k
          if (tWB < 0x100)
98
19.5k
          {
99
19.5k
            CHECKSPACE(4);
100
19.2k
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
101
19.2k
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4);
102
19.2k
            icWBC[tWB][1] = icWBC[tWB][3] = 0x100;
103
19.2k
          }
104
54.5k
          posPrivateMknBuf += 6;
105
54.5k
        }
106
1.12k
      }
107
67.8k
      else if (PrivateTagID == 0x0027)
108
862
      {
109
862
        ushort nWB, cnt, tWB;
110
862
        CHECKSPACE(2);
111
813
        nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
112
813
        posPrivateMknBuf += 2;
113
813
        if (nWB > 0x100)
114
81
          break;
115
13.5k
        for (cnt = 0; cnt < nWB; cnt++)
116
12.9k
        {
117
12.9k
          CHECKSPACE(2);
118
12.8k
          tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
119
12.8k
          if (tWB < 0x100)
120
6.29k
          {
121
6.29k
            CHECKSPACE(6);
122
6.25k
            icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
123
6.25k
            icWBC[tWB][1] = icWBC[tWB][3] =
124
6.25k
                sget2(PrivateMknBuf + posPrivateMknBuf + 4);
125
6.25k
            icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6);
126
6.25k
          }
127
12.8k
          posPrivateMknBuf += 8;
128
12.8k
        }
129
732
      }
130
66.9k
      else if (PrivateTagID == 0x0121)
131
153
      {
132
153
        CHECKSPACE(4);
133
69
        imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf);
134
69
        posPrivateMknBuf += 4;
135
69
      }
136
66.8k
      else
137
66.8k
      {
138
66.8k
        if (PrivateTagBytes > 4)
139
1.70k
          posPrivateMknBuf += PrivateTagBytes;
140
65.1k
        else if (!truncated)
141
64.9k
          posPrivateMknBuf += 4;
142
151
        else
143
151
        {
144
151
          if (PrivateTagBytes <= 2)
145
77
            posPrivateMknBuf += 2;
146
74
          else
147
74
            posPrivateMknBuf += 4;
148
151
        }
149
66.8k
      }
150
70.6k
    }
151
722
    free(PrivateMknBuf);
152
722
  }
153
11.3k
#undef CHECKSPACE
154
11.3k
}