From 5d8c7c7ed612164bf3129c5c445696487e87f59c Mon Sep 17 00:00:00 2001 From: "Tim J. Robbins" Date: Thu, 15 Jul 2004 06:15:10 +0000 Subject: [PATCH] Ensure that suffix matches occur on character boundaries. --- usr.bin/basename/basename.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/usr.bin/basename/basename.c b/usr.bin/basename/basename.c index 9e1a992cf641..d94ee67a3a1d 100644 --- a/usr.bin/basename/basename.c +++ b/usr.bin/basename/basename.c @@ -48,20 +48,26 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include #include +#include +void stripsuffix(char *, const char *, size_t); void usage(void); int main(int argc, char **argv) { - char *p, *q, *suffix; + char *p, *suffix; size_t suffixlen; int aflag, ch; + setlocale(LC_ALL, ""); + aflag = 0; suffix = NULL; suffixlen = 0; @@ -99,15 +105,37 @@ main(int argc, char **argv) while (argc--) { if ((p = basename(*argv)) == NULL) err(1, "%s", argv[0]); - if (suffixlen && (q = strchr(p, '\0') - suffixlen) > p && - strcmp(suffix, q) == 0) - *q = '\0'; + stripsuffix(p, suffix, suffixlen); argv++; (void)printf("%s\n", p); } exit(0); } +void +stripsuffix(char *p, const char *suffix, size_t suffixlen) +{ + char *q, *r; + mbstate_t mbs; + size_t n; + + if (suffixlen && (q = strchr(p, '\0') - suffixlen) > p && + strcmp(suffix, q) == 0) { + /* Ensure that the match occurred on a character boundary. */ + memset(&mbs, 0, sizeof(mbs)); + for (r = p; r < q; r += n) { + n = mbrlen(r, MB_LEN_MAX, &mbs); + if (n == (size_t)-1 || n == (size_t)-2) { + memset(&mbs, 0, sizeof(mbs)); + n = 1; + } + } + /* Chop off the suffix. */ + if (q == r) + *q = '\0'; + } +} + void usage(void) {