OSDN Git Service

Merge branch 'master' of github.com:jca02266/lha
[lha/lha.git] / src / huf.c
index dae7407..aa48c6e 100644 (file)
--- a/src/huf.c
+++ b/src/huf.c
@@ -9,8 +9,6 @@
 /* ------------------------------------------------------------------------ */
 #include "lha.h"
 
-#include <assert.h>
-
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
@@ -295,9 +293,9 @@ encode_start_st1( /* void */ )
     case LZHUFF6_DICBIT: pbit = 5; np = LZHUFF6_DICBIT + 1; break;
     case LZHUFF7_DICBIT: pbit = 5; np = LZHUFF7_DICBIT + 1; break;
     default:
-        assert(0);
+        fatal_error("Cannot use %d bytes dictionary", 1 << dicbit);
     }
-        
+
     for (i = 0; i < NC; i++)
         c_freq[i] = 0;
     for (i = 0; i < np; i++)
@@ -340,7 +338,7 @@ read_pt_len(nn, nbit, i_special)
     }
     else {
         i = 0;
-        while (i < n) {
+        while (i < MIN(n, NPT)) {
             c = peekbits(3);
             if (c != 7)
                 fillbuf(3);
@@ -356,7 +354,7 @@ read_pt_len(nn, nbit, i_special)
             pt_len[i++] = c;
             if (i == i_special) {
                 c = getbits(2);
-                while (--c >= 0)
+                while (--c >= 0 && i < NPT)
                     pt_len[i++] = 0;
             }
         }
@@ -381,7 +379,7 @@ read_c_len( /* void */ )
             c_table[i] = c;
     } else {
         i = 0;
-        while (i < n) {
+        while (i < MIN(n,NC)) {
             c = pt_table[peekbits(8)];
             if (c >= NT) {
                 unsigned short  mask = 1 << (16 - 9);
@@ -391,7 +389,7 @@ read_c_len( /* void */ )
                     else
                         c = left[c];
                     mask >>= 1;
-                } while (c >= NT);
+                } while (c >= NT && (mask || c != left[c])); /* CVE-2006-4338 */
             }
             fillbuf(pt_len[c]);
             if (c <= 2) {
@@ -439,7 +437,7 @@ decode_c_st1( /*void*/ )
             else
                 j = left[j];
             mask >>= 1;
-        } while (j >= NC);
+        } while (j >= NC && (mask || j != left[j])); /* CVE-2006-4338 */
         fillbuf(c_len[j] - 12);
     }
     return j;
@@ -464,7 +462,7 @@ decode_p_st1( /* void */ )
             else
                 j = left[j];
             mask >>= 1;
-        } while (j >= np);
+        } while (j >= np && (mask || j != left[j])); /* CVE-2006-4338 */
         fillbuf(pt_len[j] - 8);
     }
     if (j != 0)
@@ -483,7 +481,7 @@ decode_start_st1( /* void */ )
     case LZHUFF6_DICBIT: pbit = 5; np = LZHUFF6_DICBIT + 1; break;
     case LZHUFF7_DICBIT: pbit = 5; np = LZHUFF7_DICBIT + 1; break;
     default:
-        assert(0);
+        fatal_error("Cannot use %d bytes dictionary", 1 << dicbit);
     }
 
     init_getbits();