File indexing completed on 2025-01-05 03:56:57

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004 
0005  LibRaw is free software; you can redistribute it and/or modify
0006  it under the terms of the one of two licenses as you choose:
0007 
0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0009    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0010 
0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0012    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0013 
0014  */
0015 
0016 #include "../../internal/dcraw_defs.h"
0017 
0018 void LibRaw::parseAdobePanoMakernote()
0019 {
0020   uchar *PrivateMknBuf;
0021   unsigned posPrivateMknBuf;
0022   unsigned PrivateMknLength;
0023   unsigned PrivateOrder;
0024   unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount;
0025   unsigned PrivateTagBytes;
0026   int truncated;
0027 
0028 #define CHECKSPACE(s)                                                          \
0029   if (posPrivateMknBuf + (s) > PrivateMknLength)                               \
0030   {                                                                            \
0031     free(PrivateMknBuf);                                                       \
0032     return;                                                                    \
0033   }
0034 
0035   order = 0x4d4d;
0036   truncated = 0;
0037   PrivateMknLength = get4();
0038 
0039   if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) &&
0040       (PrivateMknBuf = (uchar *)malloc(PrivateMknLength + 1024)))
0041   { // 1024b for safety
0042     fread(PrivateMknBuf, PrivateMknLength, 1, ifp);
0043     PrivateOrder = sget2(PrivateMknBuf);
0044     PrivateEntries = sget2(PrivateMknBuf + 2);
0045     if ((PrivateEntries > 1000) ||
0046         ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949)))
0047     {
0048       free(PrivateMknBuf);
0049       return;
0050     }
0051     posPrivateMknBuf = 4;
0052     while (PrivateEntries--)
0053     {
0054       order = 0x4d4d;
0055       CHECKSPACE(8);
0056       PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf);
0057       PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
0058       PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4);
0059       posPrivateMknBuf += 8;
0060       order = PrivateOrder;
0061 
0062       if (truncated && !PrivateTagCount)
0063         continue;
0064 
0065       PrivateTagBytes = PrivateTagCount *
0066           tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0];
0067       if(PrivateTagBytes > 10240000u)
0068       {
0069          free(PrivateMknBuf);
0070          return;
0071       }
0072       if (PrivateTagID == 0x0002)
0073       {
0074         posPrivateMknBuf += 2;
0075         CHECKSPACE(2);
0076         if (sget2(PrivateMknBuf + posPrivateMknBuf))
0077         {
0078           truncated = 1;
0079         }
0080         else
0081         {
0082           posPrivateMknBuf += 2;
0083         }
0084       }
0085       else if (PrivateTagID == 0x0013)
0086       {
0087         ushort nWB, cnt, tWB;
0088         CHECKSPACE(2);
0089         nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
0090         posPrivateMknBuf += 2;
0091         if (nWB > 0x100)
0092           break;
0093         for (cnt = 0; cnt < nWB; cnt++)
0094         {
0095           CHECKSPACE(2);
0096           tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
0097           if (tWB < 0x100)
0098           {
0099             CHECKSPACE(4);
0100             icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
0101             icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4);
0102             icWBC[tWB][1] = icWBC[tWB][3] = 0x100;
0103           }
0104           posPrivateMknBuf += 6;
0105         }
0106       }
0107       else if (PrivateTagID == 0x0027)
0108       {
0109         ushort nWB, cnt, tWB;
0110         CHECKSPACE(2);
0111         nWB = sget2(PrivateMknBuf + posPrivateMknBuf);
0112         posPrivateMknBuf += 2;
0113         if (nWB > 0x100)
0114           break;
0115         for (cnt = 0; cnt < nWB; cnt++)
0116         {
0117           CHECKSPACE(2);
0118           tWB = sget2(PrivateMknBuf + posPrivateMknBuf);
0119           if (tWB < 0x100)
0120           {
0121             CHECKSPACE(6);
0122             icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2);
0123             icWBC[tWB][1] = icWBC[tWB][3] =
0124                 sget2(PrivateMknBuf + posPrivateMknBuf + 4);
0125             icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6);
0126           }
0127           posPrivateMknBuf += 8;
0128         }
0129       }
0130       else if (PrivateTagID == 0x0121)
0131       {
0132         CHECKSPACE(4);
0133         imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf);
0134         posPrivateMknBuf += 4;
0135       }
0136       else
0137       {
0138         if (PrivateTagBytes > 4)
0139           posPrivateMknBuf += PrivateTagBytes;
0140         else if (!truncated)
0141           posPrivateMknBuf += 4;
0142         else
0143         {
0144           if (PrivateTagBytes <= 2)
0145             posPrivateMknBuf += 2;
0146           else
0147             posPrivateMknBuf += 4;
0148         }
0149       }
0150     }
0151     free(PrivateMknBuf);
0152   }
0153 #undef CHECKSPACE
0154 }