Fix series of JPEG vulnerabilities

Test: PoC
Bug: 35639138
Change-Id: I7fc4385d7f446ecfbc7dbd350e4c9bac6db0c9f0
(cherry picked from commit 117c2d5b213b42b8cb2bedc45b6139a8f4516712)
diff --git a/gdx/jni/gdx2d/jpgd.cpp b/gdx/jni/gdx2d/jpgd.cpp
index 4c84a33..d76e930 100644
--- a/gdx/jni/gdx2d/jpgd.cpp
+++ b/gdx/jni/gdx2d/jpgd.cpp
@@ -29,6 +29,10 @@
 #define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
 #define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
 
+// TODO: Move to header and use these constants when declaring the arrays.
+#define JPGD_HUFF_TREE_MAX_LENGTH 512
+#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
+
 namespace jpgd {
 
 static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
@@ -493,8 +497,9 @@
 // Decodes a Huffman encoded symbol.
 inline int jpeg_decoder::huff_decode(huff_tables *pH)
 {
-  int symbol;
+  JPGD_ASSERT(pH);
 
+  int symbol;
   // Check first 8-bits: do we have a complete symbol?
   if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
   {
@@ -502,14 +507,19 @@
     int ofs = 23;
     do
     {
-      symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+      unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+      JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+      symbol = pH->tree[idx];
       ofs--;
     } while (symbol < 0);
 
     get_bits_no_markers(8 + (23 - ofs));
   }
   else
+  {
+    JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
     get_bits_no_markers(pH->code_size[symbol]);
+  }
 
   return symbol;
 }
@@ -519,6 +529,8 @@
 {
   int symbol;
 
+  JPGD_ASSERT(pH);
+
   // Check first 8-bits: do we have a complete symbol?
   if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
   {
@@ -526,7 +538,9 @@
     int ofs = 23;
     do
     {
-      symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+      unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+      JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+      symbol = pH->tree[idx];
       ofs--;
     } while (symbol < 0);
 
@@ -1497,6 +1511,12 @@
 void jpeg_decoder::transform_mcu(int mcu_row)
 {
   jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
+  if (m_freq_domain_chroma_upsample) {
+     JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row);
+  }
+  else {
+     JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row);
+  }
   uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
 
   for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
@@ -1652,6 +1672,7 @@
     for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
     {
       component_id = m_mcu_org[mcu_block];
+      JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
       q = m_quant[m_comp_quant[component_id]];
 
       p = m_pMCU_coefficients + 64 * mcu_block;
@@ -1772,6 +1793,7 @@
     for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
     {
       int component_id = m_mcu_org[mcu_block];
+      JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
       jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
 
       int r, s;
@@ -2281,7 +2303,8 @@
 
       for (l = 1 << (8 - code_size); l > 0; l--)
       {
-        JPGD_ASSERT(i < 256);
+        JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+        JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
 
         pH->look_up[code] = i;
 
@@ -2331,16 +2354,19 @@
         if ((code & 0x8000) == 0)
           currententry--;
 
-        if (pH->tree[-currententry - 1] == 0)
+        unsigned int idx = -currententry - 1;
+        JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+        if (pH->tree[idx] == 0)
         {
-          pH->tree[-currententry - 1] = nextfreeentry;
+          pH->tree[idx] = nextfreeentry;
 
           currententry = nextfreeentry;
 
           nextfreeentry -= 2;
         }
-        else
-          currententry = pH->tree[-currententry - 1];
+        else {
+          currententry = pH->tree[idx];
+        }
 
         code <<= 1;
       }
@@ -2642,7 +2668,9 @@
 
   for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
   {
-    s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+    unsigned int idx = pD->m_comp_ac_tab[component_id];
+    JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+    s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
 
     r = s >> 4;
     s &= 15;
@@ -2685,7 +2713,6 @@
   int p1 = 1 << pD->m_successive_low;
   int m1 = (-1) << pD->m_successive_low;
   jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-  
   JPGD_ASSERT(pD->m_spectral_end <= 63);
   
   k = pD->m_spectral_start;
@@ -2694,7 +2721,9 @@
   {
     for ( ; k <= pD->m_spectral_end; k++)
     {
-      s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+      unsigned int idx = pD->m_comp_ac_tab[component_id];
+      JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+      s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
 
       r = s >> 4;
       s &= 15;