@@ -150,7 +150,10 @@ cdef class ChunkerBuzHash64(ChunkerBase):
150150 self .table = NULL
151151 self .table_rot = NULL
152152 # see process, first while loop condition, first term must be able to get True:
153- assert hash_window_size + (1 << chunk_min_exp) + 1 <= (1 << chunk_max_exp), " too small max_size"
153+ if hash_window_size < 0 :
154+ raise ValueError (" hash_window_size must not be negative" )
155+ if hash_window_size + (1 << chunk_min_exp) + 1 > (1 << chunk_max_exp):
156+ raise ValueError (" too small max_size" )
154157
155158 self .window_size = hash_window_size
156159 self .table = buzhash64_init_table(key)
@@ -191,10 +194,8 @@ cdef class ChunkerBuzHash64(ChunkerBase):
191194 cdef uint64_t mask_s = self .mask_s, mask_l = self .mask_l
192195 cdef int nc_level = self .nc_level
193196 cdef size_t n, old_last, min_size = self .min_size, window_size = self .window_size
194- cdef size_t normal_size = self .normal_size, normal_pos
197+ cdef size_t normal_size = self .normal_size, chunk_len
195198 cdef uint8_t* p
196- cdef uint8_t* stop_at
197- cdef uint8_t* nc_stop
198199 cdef size_t did_bytes, span
199200 cdef int kernel_id = self .kernel_id
200201
@@ -204,7 +205,7 @@ cdef class ChunkerBuzHash64(ChunkerBase):
204205 else :
205206 raise Exception (" chunkifier byte count mismatch" )
206207
207- while self .remaining < min_size + window_size + 1 and not self .eof: # see assert in Chunker init
208+ while self .remaining < min_size + window_size + 1 and not self .eof: # see check in __cinit__
208209 self .fill()
209210
210211 # Here we either are at eof...
@@ -231,29 +232,28 @@ cdef class ChunkerBuzHash64(ChunkerBase):
231232 # Normalized chunking: pick the mask based on how far we are into the current chunk.
232233 # While below normal_size use the strict mask (lower cut probability), afterward the
233234 # loose mask (higher cut probability). The mask is re-evaluated at the top of every
234- # iteration, so the transition is honored exactly at normal_pos . When nc is disabled,
235- # mask_s == mask_l == chunk_mask and the normal_pos cap is not applied, so this reduces
235+ # iteration, so the transition is honored exactly at normal_size . When nc is disabled,
236+ # mask_s == mask_l == chunk_mask and the normal_size cap is not applied, so this reduces
236237 # to the original single-mask behavior.
237238 mask = mask_s
238- normal_pos = 0
239+ chunk_len = 0
239240 while True :
240241 if nc_level:
241- normal_pos = self .last + normal_size
242- mask = mask_s if self .position < normal_pos else mask_l
242+ chunk_len = self .position - self .last
243+ mask = mask_s if chunk_len < normal_size else mask_l
243244
244245 if not (self .remaining > window_size and (sum & mask) and not (self .eof and self .remaining <= window_size)):
245246 break
246247
247248 p = self .data + self .position
248- stop_at = p + self .remaining - window_size
249+ span = self .remaining - window_size
249250
250- if nc_level and self .position < normal_pos :
251- # do not scan past the strict->loose transition; re-evaluate the mask there
252- nc_stop = self .data + normal_pos
253- if nc_stop < stop_at:
254- stop_at = nc_stop
251+ if nc_level and chunk_len < normal_size and normal_size - chunk_len < span :
252+ # do not scan past the strict->loose transition; re-evaluate the mask there.
253+ # This compares lengths, not positions: normal_size is a caller-given size_t
254+ # and can be anything, self.last + normal_size might not even be representable.
255+ span = normal_size - chunk_len
255256
256- span = stop_at - p
257257 with nogil:
258258 did_bytes = bz64_scan(self .table, self .table_rot, p, p + window_size,
259259 span, & sum , mask, kernel_id)
0 commit comments