summaryrefslogtreecommitdiffstats
path: root/usr.bin/basename/basename.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-07-15 06:15:10 +0000
committertjr <tjr@FreeBSD.org>2004-07-15 06:15:10 +0000
commitfdd18f5e83d7d8e160c8d60c1912fe1f37cff246 (patch)
treea57fcfdd02093bc7eb979babf801dd21ae1d72ce /usr.bin/basename/basename.c
parent51777f0d813d0571911639312a521d0520d348ff (diff)
downloadFreeBSD-src-fdd18f5e83d7d8e160c8d60c1912fe1f37cff246.zip
FreeBSD-src-fdd18f5e83d7d8e160c8d60c1912fe1f37cff246.tar.gz
Ensure that suffix matches occur on character boundaries.
Diffstat (limited to 'usr.bin/basename/basename.c')
-rw-r--r--usr.bin/basename/basename.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/usr.bin/basename/basename.c b/usr.bin/basename/basename.c
index 9e1a992..d94ee67 100644
--- a/usr.bin/basename/basename.c
+++ b/usr.bin/basename/basename.c
@@ -48,20 +48,26 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <libgen.h>
+#include <limits.h>
+#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <wchar.h>
+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,9 +105,7 @@ 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);
}
@@ -109,6 +113,30 @@ main(int argc, char **argv)
}
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)
{
OpenPOWER on IntegriCloud