Fix an endless loop in CJBig2_HuffmanTable::parseFromCodedBuffer
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_HuffmanTable.cpp
index af4a549..0616123 100644 (file)
-// Copyright 2014 PDFium Authors. All rights reserved.\r
-// Use of this source code is governed by a BSD-style license that can be\r
-// found in the LICENSE file.\r
\r
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
-\r
-#include "JBig2_HuffmanTable.h"\r
-#include "JBig2_BitStream.h"\r
-#include <string.h>\r
-\r
-CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine *pTable, int nLines,\r
-        FX_BOOL bHTOOB)\r
-{\r
-    init();\r
-    m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);\r
-}\r
-\r
-CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream *pStream)\r
-{\r
-    init();\r
-    m_bOK = parseFromCodedBuffer(pStream);\r
-}\r
-\r
-CJBig2_HuffmanTable::~CJBig2_HuffmanTable()\r
-{\r
-    if(CODES) {\r
-        m_pModule->JBig2_Free(CODES);\r
-    }\r
-    if(PREFLEN) {\r
-        m_pModule->JBig2_Free(PREFLEN);\r
-    }\r
-    if(RANGELEN) {\r
-        m_pModule->JBig2_Free(RANGELEN);\r
-    }\r
-    if(RANGELOW) {\r
-        m_pModule->JBig2_Free(RANGELOW);\r
-    }\r
-}\r
-void CJBig2_HuffmanTable::init()\r
-{\r
-    HTOOB = FALSE;\r
-    NTEMP = 0;\r
-    CODES = NULL;\r
-    PREFLEN = NULL;\r
-    RANGELEN = NULL;\r
-    RANGELOW = NULL;\r
-}\r
-int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine *pTable, int nLines, FX_BOOL bHTOOB)\r
-{\r
-    int CURLEN, LENMAX, CURCODE, CURTEMP, i;\r
-    int *LENCOUNT;\r
-    int *FIRSTCODE;\r
-    HTOOB = bHTOOB;\r
-    NTEMP = nLines;\r
-    CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);\r
-    PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);\r
-    RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);\r
-    RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);\r
-    LENMAX = 0;\r
-    for(i = 0; i < NTEMP; i++) {\r
-        PREFLEN[i] = pTable[i].PREFLEN;\r
-        RANGELEN[i] = pTable[i].RANDELEN;\r
-        RANGELOW[i] = pTable[i].RANGELOW;\r
-        if(PREFLEN[i] > LENMAX) {\r
-            LENMAX = PREFLEN[i];\r
-        }\r
-    }\r
-    LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));\r
-    JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));\r
-    FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));\r
-    for(i = 0; i < NTEMP; i++) {\r
-        LENCOUNT[PREFLEN[i]] ++;\r
-    }\r
-    CURLEN = 1;\r
-    FIRSTCODE[0] = 0;\r
-    LENCOUNT[0]  = 0;\r
-    while(CURLEN <= LENMAX) {\r
-        FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;\r
-        CURCODE = FIRSTCODE[CURLEN];\r
-        CURTEMP = 0;\r
-        while(CURTEMP < NTEMP) {\r
-            if(PREFLEN[CURTEMP] == CURLEN) {\r
-                CODES[CURTEMP] = CURCODE;\r
-                CURCODE = CURCODE + 1;\r
-            }\r
-            CURTEMP = CURTEMP + 1;\r
-        }\r
-        CURLEN = CURLEN + 1;\r
-    }\r
-    m_pModule->JBig2_Free(LENCOUNT);\r
-    m_pModule->JBig2_Free(FIRSTCODE);\r
-    return 1;\r
-}\r
-\r
-#define HT_CHECK_MEMORY_ADJUST                 \\r
-    if(NTEMP >= nSize) \\r
-    {  \\r
-        nSize += 16;   \\r
-        PREFLEN  = (int*)m_pModule->JBig2_Realloc(PREFLEN,sizeof(int)*nSize);  \\r
-        RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN,sizeof(int)*nSize); \\r
-        RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW,sizeof(int)*nSize); \\r
-    }\r
-int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream)\r
-{\r
-    unsigned char HTPS, HTRS;\r
-    int HTLOW, HTHIGH;\r
-    int CURRANGELOW;\r
-    int nSize = 16;\r
-    int CURLEN, LENMAX, CURCODE, CURTEMP, i;\r
-    int *LENCOUNT;\r
-    int *FIRSTCODE;\r
-    unsigned char cTemp;\r
-    if(pStream->read1Byte(&cTemp) == -1) {\r
-        goto failed;\r
-    }\r
-    HTOOB = cTemp & 0x01;\r
-    HTPS  = ((cTemp >> 1) & 0x07) + 1;\r
-    HTRS  = ((cTemp >> 4) & 0x07) + 1;\r
-    if(pStream->readInteger((FX_DWORD*)&HTLOW) == -1 ||\r
-            pStream->readInteger((FX_DWORD*)&HTHIGH) == -1) {\r
-        goto failed;\r
-    }\r
-    PREFLEN  = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);\r
-    RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);\r
-    RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);\r
-    CURRANGELOW = HTLOW;\r
-    NTEMP = 0;\r
-    do {\r
-        HT_CHECK_MEMORY_ADJUST\r
-        if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)\r
-                || (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {\r
-            goto failed;\r
-        }\r
-        RANGELOW[NTEMP] = CURRANGELOW;\r
-        CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);\r
-        NTEMP = NTEMP + 1;\r
-    } while(CURRANGELOW < HTHIGH);\r
-    HT_CHECK_MEMORY_ADJUST\r
-    if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {\r
-        goto failed;\r
-    }\r
-    RANGELEN[NTEMP] = 32;\r
-    RANGELOW[NTEMP] = HTLOW - 1;\r
-    NTEMP = NTEMP + 1;\r
-    HT_CHECK_MEMORY_ADJUST\r
-    if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {\r
-        goto failed;\r
-    }\r
-    RANGELEN[NTEMP] = 32;\r
-    RANGELOW[NTEMP] = HTHIGH;\r
-    NTEMP = NTEMP + 1;\r
-    if(HTOOB) {\r
-        HT_CHECK_MEMORY_ADJUST\r
-        if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {\r
-            goto failed;\r
-        }\r
-        NTEMP = NTEMP + 1;\r
-    }\r
-    CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);\r
-    LENMAX = 0;\r
-    for(i = 0; i < NTEMP; i++) {\r
-        if(PREFLEN[i] > LENMAX) {\r
-            LENMAX = PREFLEN[i];\r
-        }\r
-    }\r
-    LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));\r
-    JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));\r
-    FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));\r
-    for(i = 0; i < NTEMP; i++) {\r
-        LENCOUNT[PREFLEN[i]] ++;\r
-    }\r
-    CURLEN = 1;\r
-    FIRSTCODE[0] = 0;\r
-    LENCOUNT[0]  = 0;\r
-    while(CURLEN <= LENMAX) {\r
-        FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;\r
-        CURCODE = FIRSTCODE[CURLEN];\r
-        CURTEMP = 0;\r
-        while(CURTEMP < NTEMP) {\r
-            if(PREFLEN[CURTEMP] == CURLEN) {\r
-                CODES[CURTEMP] = CURCODE;\r
-                CURCODE = CURCODE + 1;\r
-            }\r
-            CURTEMP = CURTEMP + 1;\r
-        }\r
-        CURLEN = CURLEN + 1;\r
-    }\r
-    m_pModule->JBig2_Free(LENCOUNT);\r
-    m_pModule->JBig2_Free(FIRSTCODE);\r
-    return TRUE;\r
-failed:\r
-    return FALSE;\r
-}\r
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "JBig2_HuffmanTable.h"
+#include "JBig2_BitStream.h"
+#include <string.h>
+
+CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine *pTable, int nLines,
+        FX_BOOL bHTOOB)
+{
+    init();
+    m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);
+}
+
+CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream *pStream)
+{
+    init();
+    m_bOK = parseFromCodedBuffer(pStream);
+}
+
+CJBig2_HuffmanTable::~CJBig2_HuffmanTable()
+{
+    if(CODES) {
+        m_pModule->JBig2_Free(CODES);
+    }
+    if(PREFLEN) {
+        m_pModule->JBig2_Free(PREFLEN);
+    }
+    if(RANGELEN) {
+        m_pModule->JBig2_Free(RANGELEN);
+    }
+    if(RANGELOW) {
+        m_pModule->JBig2_Free(RANGELOW);
+    }
+}
+void CJBig2_HuffmanTable::init()
+{
+    HTOOB = FALSE;
+    NTEMP = 0;
+    CODES = NULL;
+    PREFLEN = NULL;
+    RANGELEN = NULL;
+    RANGELOW = NULL;
+}
+int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine *pTable, int nLines, FX_BOOL bHTOOB)
+{
+    int CURLEN, LENMAX, CURCODE, CURTEMP, i;
+    int *LENCOUNT;
+    int *FIRSTCODE;
+    HTOOB = bHTOOB;
+    NTEMP = nLines;
+    CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
+    PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
+    RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
+    RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
+    LENMAX = 0;
+    for(i = 0; i < NTEMP; i++) {
+        PREFLEN[i] = pTable[i].PREFLEN;
+        RANGELEN[i] = pTable[i].RANDELEN;
+        RANGELOW[i] = pTable[i].RANGELOW;
+        if(PREFLEN[i] > LENMAX) {
+            LENMAX = PREFLEN[i];
+        }
+    }
+    LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
+    JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
+    FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
+    for(i = 0; i < NTEMP; i++) {
+        LENCOUNT[PREFLEN[i]] ++;
+    }
+    CURLEN = 1;
+    FIRSTCODE[0] = 0;
+    LENCOUNT[0]  = 0;
+    while(CURLEN <= LENMAX) {
+        FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
+        CURCODE = FIRSTCODE[CURLEN];
+        CURTEMP = 0;
+        while(CURTEMP < NTEMP) {
+            if(PREFLEN[CURTEMP] == CURLEN) {
+                CODES[CURTEMP] = CURCODE;
+                CURCODE = CURCODE + 1;
+            }
+            CURTEMP = CURTEMP + 1;
+        }
+        CURLEN = CURLEN + 1;
+    }
+    m_pModule->JBig2_Free(LENCOUNT);
+    m_pModule->JBig2_Free(FIRSTCODE);
+    return 1;
+}
+
+#define HT_CHECK_MEMORY_ADJUST                 \
+    if(NTEMP >= nSize) \
+    {  \
+        nSize += 16;   \
+        PREFLEN  = (int*)m_pModule->JBig2_Realloc(PREFLEN,sizeof(int)*nSize);  \
+        RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN,sizeof(int)*nSize); \
+        RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW,sizeof(int)*nSize); \
+    }
+int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream)
+{
+    unsigned char HTPS, HTRS;
+    FX_DWORD HTLOW, HTHIGH;
+    FX_DWORD CURRANGELOW;
+    FX_DWORD nSize = 16;
+    int CURLEN, LENMAX, CURCODE, CURTEMP;
+    int *LENCOUNT;
+    int *FIRSTCODE;
+    unsigned char cTemp;
+    if(pStream->read1Byte(&cTemp) == -1) {
+        goto failed;
+    }
+    HTOOB = cTemp & 0x01;
+    HTPS  = ((cTemp >> 1) & 0x07) + 1;
+    HTRS  = ((cTemp >> 4) & 0x07) + 1;
+    if(pStream->readInteger(&HTLOW) == -1  ||
+       pStream->readInteger(&HTHIGH) == -1 ||
+       HTLOW > HTHIGH) {
+        goto failed;
+    }
+    PREFLEN  = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
+    RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
+    RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
+    CURRANGELOW = HTLOW;
+    NTEMP = 0;
+    do {
+        HT_CHECK_MEMORY_ADJUST
+        if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
+           (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
+            goto failed;
+        }
+        RANGELOW[NTEMP] = CURRANGELOW;
+        CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);
+        NTEMP = NTEMP + 1;
+    } while(CURRANGELOW < HTHIGH);
+    HT_CHECK_MEMORY_ADJUST
+    if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
+        goto failed;
+    }
+    RANGELEN[NTEMP] = 32;
+    RANGELOW[NTEMP] = HTLOW - 1;
+    NTEMP = NTEMP + 1;
+    HT_CHECK_MEMORY_ADJUST
+    if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
+        goto failed;
+    }
+    RANGELEN[NTEMP] = 32;
+    RANGELOW[NTEMP] = HTHIGH;
+    NTEMP = NTEMP + 1;
+    if(HTOOB) {
+        HT_CHECK_MEMORY_ADJUST
+        if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
+            goto failed;
+        }
+        NTEMP = NTEMP + 1;
+    }
+    CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
+    LENMAX = 0;
+    for(int i = 0; i < NTEMP; i++) {
+        if(PREFLEN[i] > LENMAX) {
+            LENMAX = PREFLEN[i];
+        }
+    }
+    LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
+    JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
+    FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
+    for(int i = 0; i < NTEMP; i++) {
+        LENCOUNT[PREFLEN[i]] ++;
+    }
+    CURLEN = 1;
+    FIRSTCODE[0] = 0;
+    LENCOUNT[0]  = 0;
+    while(CURLEN <= LENMAX) {
+        FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
+        CURCODE = FIRSTCODE[CURLEN];
+        CURTEMP = 0;
+        while(CURTEMP < NTEMP) {
+            if(PREFLEN[CURTEMP] == CURLEN) {
+                CODES[CURTEMP] = CURCODE;
+                CURCODE = CURCODE + 1;
+            }
+            CURTEMP = CURTEMP + 1;
+        }
+        CURLEN = CURLEN + 1;
+    }
+    m_pModule->JBig2_Free(LENCOUNT);
+    m_pModule->JBig2_Free(FIRSTCODE);
+    return TRUE;
+failed:
+    return FALSE;
+}