xdiff: use unambiguous types in xdl_hash_record()

Convert the function signature and body to use unambiguous types. char is changed to uint8_t because this function processes bytes in memory. unsigned long to uint64_t so that the hash output is consistent across platforms. `flags` was changed from long to uint64_t to ensure the high order bits are not dropped on platforms that treat long as 32 bits. Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ezekiel Newren committed Nov 18, 2025 at 22:34 UTC b0d4ae30f5a23fa9da87e9396b78e6442b351ddc
4 files changed +21 -21
xdiff-interface.c
+1 -1
@@ -300,7 +300,7 @@ void xdiff_clear_find_func(xdemitconf_t *xecfg)
300
301 unsigned long xdiff_hash_string(const char *s, size_t len, long flags)
302 {
303 - return xdl_hash_record(&s, s + len, flags);
303 + return xdl_hash_record((uint8_t const**)&s, (uint8_t const*)s + len, flags);
304 }
305
306 int xdiff_compare_lines(const char *l1, long s1,
xdiff/xprepare.c
+3 -3
@@ -137,8 +137,8 @@ static void xdl_free_ctx(xdfile_t *xdf)
137 static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
138 xdlclassifier_t *cf, xdfile_t *xdf) {
139 long bsize;
140 - unsigned long hav;
141 - char const *blk, *cur, *top, *prev;
140 + uint64_t hav;
141 + uint8_t const *blk, *cur, *top, *prev;
142 xrecord_t *crec;
143
144 xdf->rindex = NULL;
@@ -156,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
156 if (XDL_ALLOC_GROW(xdf->recs, xdf->nrec + 1, narec))
157 goto abort;
158 crec = &xdf->recs[xdf->nrec++];
159 - crec->ptr = (uint8_t const *)prev;
159 + crec->ptr = prev;
160 crec->size = cur - prev;
161 crec->ha = hav;
162 if (xdl_classify_record(pass, cf, crec) < 0)
xdiff/xutils.c
+14 -14
@@ -249,11 +249,11 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
249 return 1;
250 }
251
252 -unsigned long xdl_hash_record_with_whitespace(char const **data,
253 - char const *top, long flags) {
254 - unsigned long ha = 5381;
255 - char const *ptr = *data;
256 - int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
252 +uint64_t xdl_hash_record_with_whitespace(uint8_t const **data,
253 + uint8_t const *top, uint64_t flags) {
254 + uint64_t ha = 5381;
255 + uint8_t const *ptr = *data;
256 + bool cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
257
258 for (; ptr < top && *ptr != '\n'; ptr++) {
259 if (cr_at_eol_only) {
@@ -263,8 +263,8 @@ unsigned long xdl_hash_record_with_whitespace(char const **data,
263 continue;
264 }
265 else if (XDL_ISSPACE(*ptr)) {
266 - const char *ptr2 = ptr;
267 - int at_eol;
266 + const uint8_t *ptr2 = ptr;
267 + bool at_eol;
268 while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
269 && ptr[1] != '\n')
270 ptr++;
@@ -274,20 +274,20 @@ unsigned long xdl_hash_record_with_whitespace(char const **data,
274 else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
275 && !at_eol) {
276 ha += (ha << 5);
277 - ha ^= (unsigned long) ' ';
277 + ha ^= (uint64_t) ' ';
278 }
279 else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
280 && !at_eol) {
281 while (ptr2 != ptr + 1) {
282 ha += (ha << 5);
283 - ha ^= (unsigned long) *ptr2;
283 + ha ^= (uint64_t) *ptr2;
284 ptr2++;
285 }
286 }
287 continue;
288 }
289 ha += (ha << 5);
290 - ha ^= (unsigned long) *ptr;
290 + ha ^= (uint64_t) *ptr;
291 }
292 *data = ptr < top ? ptr + 1: ptr;
293
@@ -304,9 +304,9 @@ unsigned long xdl_hash_record_with_whitespace(char const **data,
304 #define REASSOC_FENCE(x, y)
305 #endif
306
307 -unsigned long xdl_hash_record_verbatim(char const **data, char const *top) {
308 - unsigned long ha = 5381, c0, c1;
309 - char const *ptr = *data;
307 +uint64_t xdl_hash_record_verbatim(uint8_t const **data, uint8_t const *top) {
308 + uint64_t ha = 5381, c0, c1;
309 + uint8_t const *ptr = *data;
310 #if 0
311 /*
312 * The baseline form of the optimized loop below. This is the djb2
@@ -314,7 +314,7 @@ unsigned long xdl_hash_record_verbatim(char const **data, char const *top) {
314 */
315 for (; ptr < top && *ptr != '\n'; ptr++) {
316 ha += (ha << 5);
317 - ha += (unsigned long) *ptr;
317 + ha += (uint64_t) *ptr;
318 }
319 *data = ptr < top ? ptr + 1: ptr;
320 #else
xdiff/xutils.h
+3 -3
@@ -34,9 +34,9 @@ void *xdl_cha_alloc(chastore_t *cha);
34 long xdl_guess_lines(mmfile_t *mf, long sample);
35 int xdl_blankline(const char *line, long size, long flags);
36 int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
37 -unsigned long xdl_hash_record_verbatim(char const **data, char const *top);
38 -unsigned long xdl_hash_record_with_whitespace(char const **data, char const *top, long flags);
39 -static inline unsigned long xdl_hash_record(char const **data, char const *top, long flags)
37 +uint64_t xdl_hash_record_verbatim(uint8_t const **data, uint8_t const *top);
38 +uint64_t xdl_hash_record_with_whitespace(uint8_t const **data, uint8_t const *top, uint64_t flags);
39 +static inline uint64_t xdl_hash_record(uint8_t const **data, uint8_t const *top, uint64_t flags)
40 {
41 if (flags & XDF_WHITESPACE_FLAGS)
42 return xdl_hash_record_with_whitespace(data, top, flags);