Ensure validity of max_search_depth
authorEric Biggers <ebiggers3@gmail.com>
Mon, 12 Jan 2015 02:06:41 +0000 (20:06 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 12 Jan 2015 02:06:41 +0000 (20:06 -0600)
include/wimlib/bt_matchfinder.h
include/wimlib/hc_matchfinder.h
src/lzx_compress.c
src/xpress_compress.c

index 1d30e36216a05876e8074956b3b7dfe4de2e012c..78ecdd751c20dd62c5787d52d8a81dda81d35ffb 100644 (file)
@@ -127,8 +127,9 @@ bt_right_child(struct bt_matchfinder *mf, pos_t node)
  *     The maximum permissible match length at this position.
  * @nice_len
  *     Stop searching if a match of at least this length is found.
+ *     Must be <= @max_len.
  * @max_search_depth
- *     Limit on the number of potential matches to consider.
+ *     Limit on the number of potential matches to consider.  Must be >= 1.
  * @next_hash
  *     Pointer to the hash code for the current sequence, which was computed
  *     one position in advance so that the binary tree root could be
index 1403a15781039a49f0400e4789ecde9667f7b261..a5cca95e6a9d18032aad1ae8004ec33650ecd3a1 100644 (file)
@@ -145,8 +145,9 @@ hc_matchfinder_init(struct hc_matchfinder *mf)
  *     The maximum permissible match length at this position.
  * @nice_len
  *     Stop searching if a match of at least this length is found.
+ *     Must be <= @max_len.
  * @max_search_depth
- *     Limit on the number of potential matches to consider.
+ *     Limit on the number of potential matches to consider.  Must be >= 1.
  * @offset_ret
  *     If a match is found, its offset is returned in this location.
  *
index 88ac8fac7b2a72aa31df2a32754fa04d085747ef..0db8f10877f2f4c1fca9bb3eac1c9732d7003235 100644 (file)
@@ -2062,9 +2062,13 @@ lzx_create_compressor(size_t max_bufsize, unsigned compression_level,
 
                c->impl = lzx_compress_lazy;
                c->max_search_depth = (36 * compression_level) / 20;
-               c->nice_match_length = min((72 * compression_level) / 20,
-                                          LZX_MAX_MATCH_LEN);
+               c->nice_match_length = (72 * compression_level) / 20;
 
+               /* lzx_compress_lazy() needs max_search_depth >= 2 because it
+                * halves the max_search_depth when attempting a lazy match, and
+                * max_search_depth cannot be 0.  */
+               if (c->max_search_depth < 2)
+                       c->max_search_depth = 2;
        } else {
 
                /* Normal / high compression: Use near-optimal parsing.  */
@@ -2074,8 +2078,7 @@ lzx_create_compressor(size_t max_bufsize, unsigned compression_level,
                /* Scale nice_match_length and max_search_depth with the
                 * compression level.  */
                c->max_search_depth = (24 * compression_level) / 50;
-               c->nice_match_length = min((32 * compression_level) / 50,
-                                          LZX_MAX_MATCH_LEN);
+               c->nice_match_length = (32 * compression_level) / 50;
 
                /* Set a number of optimization passes appropriate for the
                 * compression level.  */
@@ -2101,6 +2104,13 @@ lzx_create_compressor(size_t max_bufsize, unsigned compression_level,
                }
        }
 
+       /* max_search_depth == 0 is invalid.  */
+       if (c->max_search_depth < 1)
+               c->max_search_depth = 1;
+
+       if (c->nice_match_length > LZX_MAX_MATCH_LEN)
+               c->nice_match_length = LZX_MAX_MATCH_LEN;
+
        lzx_init_offset_slot_fast(c);
        *c_ret = c;
        return 0;
index 65c4b026627bdeaf912b29e04cdba435779f7cef..1c824a57634520cdd3974e32ef88cfbe47cf7aa6 100644 (file)
@@ -1088,6 +1088,13 @@ xpress_create_compressor(size_t max_bufsize, unsigned compression_level,
                        c->impl = xpress_compress_lazy;
                        c->max_search_depth = (compression_level * 24) / 32;
                        c->nice_match_length = (compression_level * 48) / 32;
+
+                       /* xpress_compress_lazy() needs max_search_depth >= 2
+                        * because it halves the max_search_depth when
+                        * attempting a lazy match, and max_search_depth cannot
+                        * be 0.  */
+                       if (c->max_search_depth < 2)
+                               c->max_search_depth = 2;
                }
        }
 #if SUPPORT_NEAR_OPTIMAL_PARSING
@@ -1113,6 +1120,10 @@ xpress_create_compressor(size_t max_bufsize, unsigned compression_level,
        }
 #endif /* SUPPORT_NEAR_OPTIMAL_PARSING */
 
+       /* max_search_depth == 0 is invalid.  */
+       if (c->max_search_depth < 1)
+               c->max_search_depth = 1;
+
        *c_ret = c;
        return 0;