use xstrncmpz()

Add and apply a semantic patch for calling xstrncmpz() to compare a NUL-terminated string with a buffer of a known length instead of using strncmp() and checking the terminating NUL explicitly. This simplifies callers by reducing code duplication. I had to adjust remote.c manually because Coccinelle inexplicably changed the indent of the else branches. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Feb 10, 2024 at 08:43 UTC f0e578c69cd91a554179c09dab6989f6eb0e2910
10 files changed +38 -16
archive-tar.c
+1 -1
@@ -365,7 +365,7 @@ static struct archiver *find_tar_filter(const char *name, size_t len)
365 int i;
366 for (i = 0; i < nr_tar_filters; i++) {
367 struct archiver *ar = tar_filters[i];
368 - if (!strncmp(ar->name, name, len) && !ar->name[len])
368 + if (!xstrncmpz(ar->name, name, len))
369 return ar;
370 }
371 return NULL;
builtin/fast-export.c
+1 -2
@@ -136,8 +136,7 @@ static int anonymized_entry_cmp(const void *cmp_data UNUSED,
136 a = container_of(eptr, const struct anonymized_entry, hash);
137 if (keydata) {
138 const struct anonymized_entry_key *key = keydata;
139 - int equal = !strncmp(a->orig, key->orig, key->orig_len) &&
140 - !a->orig[key->orig_len];
139 + int equal = !xstrncmpz(a->orig, key->orig, key->orig_len);
140 return !equal;
141 }
142
builtin/merge.c
+1 -2
@@ -192,8 +192,7 @@ static struct strategy *get_strategy(const char *name)
192 int j, found = 0;
193 struct cmdname *ent = main_cmds.names[i];
194 for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++)
195 - if (!strncmp(ent->name, all_strategy[j].name, ent->len)
196 - && !all_strategy[j].name[ent->len])
195 + if (!xstrncmpz(all_strategy[j].name, ent->name, ent->len))
196 found = 1;
197 if (!found)
198 add_cmdname(&not_strategies, ent->name, ent->len);
builtin/reflog.c
+1 -2
@@ -96,8 +96,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
96 reflog_expire_cfg_tail = &reflog_expire_cfg;
97
98 for (ent = reflog_expire_cfg; ent; ent = ent->next)
99 - if (!strncmp(ent->pattern, pattern, len) &&
100 - ent->pattern[len] == '\0')
99 + if (!xstrncmpz(ent->pattern, pattern, len))
100 return ent;
101
102 FLEX_ALLOC_MEM(ent, pattern, pattern, len);
contrib/coccinelle/xstrncmpz.cocci new
+28
@@ -0,0 +1,28 @@
1 +@@
2 +expression S, T, L;
3 +@@
4 +(
5 +- strncmp(S, T, L) || S[L]
6 ++ !!xstrncmpz(S, T, L)
7 +|
8 +- strncmp(S, T, L) || S[L] != '\0'
9 ++ !!xstrncmpz(S, T, L)
10 +|
11 +- strncmp(S, T, L) || T[L]
12 ++ !!xstrncmpz(T, S, L)
13 +|
14 +- strncmp(S, T, L) || T[L] != '\0'
15 ++ !!xstrncmpz(T, S, L)
16 +|
17 +- !strncmp(S, T, L) && !S[L]
18 ++ !xstrncmpz(S, T, L)
19 +|
20 +- !strncmp(S, T, L) && S[L] == '\0'
21 ++ !xstrncmpz(S, T, L)
22 +|
23 +- !strncmp(S, T, L) && !T[L]
24 ++ !xstrncmpz(T, S, L)
25 +|
26 +- !strncmp(S, T, L) && T[L] == '\0'
27 ++ !xstrncmpz(T, S, L)
28 +)
convert.c
+1 -1
@@ -1028,7 +1028,7 @@ static int read_convert_config(const char *var, const char *value,
1028 if (parse_config_key(var, "filter", &name, &namelen, &key) < 0 || !name)
1029 return 0;
1030 for (drv = user_convert; drv; drv = drv->next)
1031 - if (!strncmp(drv->name, name, namelen) && !drv->name[namelen])
1031 + if (!xstrncmpz(drv->name, name, namelen))
1032 break;
1033 if (!drv) {
1034 CALLOC_ARRAY(drv, 1);
merge-ll.c
+1 -1
@@ -286,7 +286,7 @@ static int read_merge_config(const char *var, const char *value,
286 * after seeing merge.<name>.var1.
287 */
288 for (fn = ll_user_merge; fn; fn = fn->next)
289 - if (!strncmp(fn->name, name, namelen) && !fn->name[namelen])
289 + if (!xstrncmpz(fn->name, name, namelen))
290 break;
291 if (!fn) {
292 CALLOC_ARRAY(fn, 1);
object.c
+1 -2
@@ -47,8 +47,7 @@ int type_from_string_gently(const char *str, ssize_t len, int gentle)
47 len = strlen(str);
48
49 for (i = 1; i < ARRAY_SIZE(object_type_strings); i++)
50 - if (!strncmp(str, object_type_strings[i], len) &&
51 - object_type_strings[i][len] == '\0')
50 + if (!xstrncmpz(object_type_strings[i], str, len))
51 return i;
52
53 if (gentle)
remote.c
+2 -3
@@ -105,7 +105,7 @@ static int remotes_hash_cmp(const void *cmp_data UNUSED,
105 b = container_of(entry_or_key, const struct remote, ent);
106
107 if (key)
108 - return strncmp(a->name, key->str, key->len) || a->name[key->len];
108 + return !!xstrncmpz(a->name, key->str, key->len);
109 else
110 return strcmp(a->name, b->name);
111 }
@@ -189,8 +189,7 @@ static int branches_hash_cmp(const void *cmp_data UNUSED,
189 b = container_of(entry_or_key, const struct branch, ent);
190
191 if (key)
192 - return strncmp(a->name, key->str, key->len) ||
193 - a->name[key->len];
192 + return !!xstrncmpz(a->name, key->str, key->len);
193 else
194 return strcmp(a->name, b->name);
195 }
userdiff.c
+1 -2
@@ -323,8 +323,7 @@ static int userdiff_find_by_namelen_cb(struct userdiff_driver *driver,
323 {
324 struct find_by_namelen_data *cb_data = priv;
325
326 - if (!strncmp(driver->name, cb_data->name, cb_data->len) &&
327 - !driver->name[cb_data->len]) {
326 + if (!xstrncmpz(driver->name, cb_data->name, cb_data->len)) {
327 cb_data->driver = driver;
328 return 1; /* tell the caller to stop iterating */
329 }