aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-09-21 15:19:18 +0100
committerRon Yorston <rmy@pobox.com>2021-09-21 15:19:18 +0100
commit90b3ba992ecb39e32e5a66b2e37579becc56d286 (patch)
tree4c4a2c9e1baeb8230d78efd058bb4bcabc3fd12b /libbb
parentdf34f5e92b1d10f0bb858d2ea6e8c249e87ac593 (diff)
parent56f0e886db0543a27f369d7f95eb9da2fb3d069c (diff)
downloadbusybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.tar.gz
busybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.tar.bz2
busybox-w32-90b3ba992ecb39e32e5a66b2e37579becc56d286.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c11
-rw-r--r--libbb/mode_string.c34
-rw-r--r--libbb/parse_mode.c5
-rw-r--r--libbb/time.c23
4 files changed, 34 insertions, 39 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index f17c9a215..7c46fa5db 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1219,7 +1219,16 @@ static void showfiles(void)
1219 1219
1220static const char *is_special_char(char c) 1220static const char *is_special_char(char c)
1221{ 1221{
1222 return strchr(" `\"#$%^&*()=+{}[]:;'|\\<>", c); 1222 // {: It's mandatory to escape { only if entire name is "{"
1223 // (otherwise it's not special. Example: file named "{ "
1224 // can be escaped simply as "{\ "; "{a" or "a{" need no escaping),
1225 // or if shell supports brace expansion
1226 // (ash doesn't, hush optionally does).
1227 // (): unlike {, shell treats () specially even in contexts
1228 // where they clearly are not valid (e.g. "echo )" is an error).
1229 // #: needs escaping to not start a shell comment.
1230 return strchr(" `'\"\\#$~?*[{()&;|<>", c);
1231 // Used to also have %^=+}]: but not necessary to escape?
1223} 1232}
1224 1233
1225static char *quote_special_chars(char *found) 1234static char *quote_special_chars(char *found)
diff --git a/libbb/mode_string.c b/libbb/mode_string.c
index dc3f9f88c..906c03964 100644
--- a/libbb/mode_string.c
+++ b/libbb/mode_string.c
@@ -16,16 +16,18 @@
16#error permission bitflag value assumption(s) violated! 16#error permission bitflag value assumption(s) violated!
17#endif 17#endif
18 18
19/* Generate ls-style "mode string" like "-rwsr-xr-x" or "drwxrwxrwt" */
20
19#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \ 21#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \
20 || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 && S_IFBLK != 0030000 ) \ 22 || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 && S_IFBLK != 0030000 ) \
21 || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \ 23 || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \
22 || ( S_IFIFO != 0010000 ) 24 || ( S_IFIFO != 0010000 )
23#warning mode type bitflag value assumption(s) violated! falling back to larger version 25# warning mode type bitflag value assumption(s) violated! falling back to larger version
24 26
25#if (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX) == 07777 27# if (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX) == 07777
26#undef mode_t 28# undef mode_t
27#define mode_t unsigned short 29# define mode_t unsigned short
28#endif 30# endif
29 31
30static const mode_t mode_flags[] ALIGN4 = { 32static const mode_t mode_flags[] ALIGN4 = {
31 S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID, 33 S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID,
@@ -33,19 +35,14 @@ static const mode_t mode_flags[] ALIGN4 = {
33 S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX 35 S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX
34}; 36};
35 37
36/* The static const char arrays below are duplicated for the two cases
37 * because moving them ahead of the mode_flags declaration cause a text
38 * size increase with the gcc version I'm using. */
39
40/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', 38/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
41 * and 'B' types don't appear to be available on linux. So I removed them. */ 39 * and 'B' types don't appear to be available on linux. So I removed them. */
42static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???"; 40static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???";
43/***************************************** 0123456789abcdef */ 41/***************************************** 0123456789abcdef */
44static const char mode_chars[7] ALIGN1 = "rwxSTst"; 42static const char mode_chars[7] ALIGN1 = "rwxSTst";
45 43
46const char* FAST_FUNC bb_mode_string(mode_t mode) 44char* FAST_FUNC bb_mode_string(char buf[11], mode_t mode)
47{ 45{
48 static char buf[12];
49 char *p = buf; 46 char *p = buf;
50 47
51 int i, j, k; 48 int i, j, k;
@@ -67,10 +64,7 @@ const char* FAST_FUNC bb_mode_string(mode_t mode)
67 i += 4; 64 i += 4;
68 } while (i < 12); 65 } while (i < 12);
69 66
70 /* Note: We don't bother with nul termination because bss initialization 67 buf[10] = '\0';
71 * should have taken care of that for us. If the user scribbled in buf
72 * memory, they deserve whatever happens. But we'll at least assert. */
73 assert(buf[10] == 0);
74 68
75 return buf; 69 return buf;
76} 70}
@@ -80,12 +74,11 @@ const char* FAST_FUNC bb_mode_string(mode_t mode)
80/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', 74/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
81 * and 'B' types don't appear to be available on linux. So I removed them. */ 75 * and 'B' types don't appear to be available on linux. So I removed them. */
82static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???"; 76static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???";
83/********************************** 0123456789abcdef */ 77/***************************************** 0123456789abcdef */
84static const char mode_chars[7] ALIGN1 = "rwxSTst"; 78static const char mode_chars[7] ALIGN1 = "rwxSTst";
85 79
86const char* FAST_FUNC bb_mode_string(mode_t mode) 80char* FAST_FUNC bb_mode_string(char buf[11], mode_t mode)
87{ 81{
88 static char buf[12];
89 char *p = buf; 82 char *p = buf;
90 83
91 int i, j, k, m; 84 int i, j, k, m;
@@ -109,10 +102,7 @@ const char* FAST_FUNC bb_mode_string(mode_t mode)
109 } 102 }
110 } while (i < 3); 103 } while (i < 3);
111 104
112 /* Note: We don't bother with nul termination because bss initialization 105 buf[10] = '\0';
113 * should have taken care of that for us. If the user scribbled in buf
114 * memory, they deserve whatever happens. But we'll at least assert. */
115 assert(buf[10] == 0);
116 106
117 return buf; 107 return buf;
118} 108}
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c
index dc65860f6..1d238e1e0 100644
--- a/libbb/parse_mode.c
+++ b/libbb/parse_mode.c
@@ -16,13 +16,14 @@
16 16
17int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) 17int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode)
18{ 18{
19 static const mode_t who_mask[] = { 19/* should be mode_t really, but in all Unixes these constants fit into uint16 */
20 static const uint16_t who_mask[] ALIGN2 = {
20 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ 21 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
21 S_ISUID | S_IRWXU, /* u */ 22 S_ISUID | S_IRWXU, /* u */
22 S_ISGID | S_IRWXG, /* g */ 23 S_ISGID | S_IRWXG, /* g */
23 S_IRWXO /* o */ 24 S_IRWXO /* o */
24 }; 25 };
25 static const mode_t perm_mask[] = { 26 static const uint16_t perm_mask[] ALIGN2 = {
26 S_IRUSR | S_IRGRP | S_IROTH, /* r */ 27 S_IRUSR | S_IRGRP | S_IROTH, /* r */
27 S_IWUSR | S_IWGRP | S_IWOTH, /* w */ 28 S_IWUSR | S_IWGRP | S_IWOTH, /* w */
28 S_IXUSR | S_IXGRP | S_IXOTH, /* x */ 29 S_IXUSR | S_IXGRP | S_IXOTH, /* x */
diff --git a/libbb/time.c b/libbb/time.c
index ed4f50470..e7c9fa65e 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -13,6 +13,7 @@
13int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) 13int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
14{ 14{
15 char end = '\0'; 15 char end = '\0';
16 time_t t;
16#if ENABLE_DESKTOP 17#if ENABLE_DESKTOP
17/* 18/*
18 * strptime is BIG: ~1k in uclibc, ~10k in glibc 19 * strptime is BIG: ~1k in uclibc, ~10k in glibc
@@ -29,10 +30,10 @@ int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
29 "%b %d %T %Y" "\0" /* month_name d HH:MM:SS YYYY */ 30 "%b %d %T %Y" "\0" /* month_name d HH:MM:SS YYYY */
30 "%Y-%m-%d %R" "\0" /* yyyy-mm-dd HH:MM */ 31 "%Y-%m-%d %R" "\0" /* yyyy-mm-dd HH:MM */
31 "%Y-%m-%d %T" "\0" /* yyyy-mm-dd HH:MM:SS */ 32 "%Y-%m-%d %T" "\0" /* yyyy-mm-dd HH:MM:SS */
32#if ENABLE_FEATURE_TIMEZONE 33# if ENABLE_FEATURE_TIMEZONE
33 "%Y-%m-%d %R %z" "\0" /* yyyy-mm-dd HH:MM TZ */ 34 "%Y-%m-%d %R %z" "\0" /* yyyy-mm-dd HH:MM TZ */
34 "%Y-%m-%d %T %z" "\0" /* yyyy-mm-dd HH:MM:SS TZ */ 35 "%Y-%m-%d %T %z" "\0" /* yyyy-mm-dd HH:MM:SS TZ */
35#endif 36# endif
36 "%Y-%m-%d %H" "\0" /* yyyy-mm-dd HH */ 37 "%Y-%m-%d %H" "\0" /* yyyy-mm-dd HH */
37 "%Y-%m-%d" "\0" /* yyyy-mm-dd */ 38 "%Y-%m-%d" "\0" /* yyyy-mm-dd */
38 /* extra NUL */; 39 /* extra NUL */;
@@ -50,11 +51,8 @@ int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
50 endp = strptime(date_str, fmt, ptm); 51 endp = strptime(date_str, fmt, ptm);
51#endif 52#endif
52 if (endp && *endp == '\0') { 53 if (endp && *endp == '\0') {
53#if ENABLE_FEATURE_TIMEZONE 54# if ENABLE_FEATURE_TIMEZONE
54 if (strchr(fmt, 'z')) { 55 if (strchr(fmt, 'z')) {
55 time_t t;
56 struct tm *utm;
57
58 /* we have timezone offset: obtain Unix time_t */ 56 /* we have timezone offset: obtain Unix time_t */
59#if ENABLE_PLATFORM_MINGW32 57#if ENABLE_PLATFORM_MINGW32
60 ptm->tm_sec -= gmtoff; 58 ptm->tm_sec -= gmtoff;
@@ -66,13 +64,9 @@ int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
66 if (t == (time_t)-1) 64 if (t == (time_t)-1)
67 break; 65 break;
68 /* convert Unix time_t to struct tm in user's locale */ 66 /* convert Unix time_t to struct tm in user's locale */
69 utm = localtime(&t); 67 goto localise;
70 if (!utm)
71 break;
72 *ptm = *utm;
73 return 0;
74 } 68 }
75#endif 69# endif
76 return 1; 70 return 1;
77 } 71 }
78 *ptm = save; 72 *ptm = save;
@@ -150,13 +144,14 @@ int FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
150 } else 144 } else
151#endif /* ENABLE_DESKTOP */ 145#endif /* ENABLE_DESKTOP */
152 if (date_str[0] == '@') { 146 if (date_str[0] == '@') {
153 time_t t;
154 if (sizeof(t) <= sizeof(long)) 147 if (sizeof(t) <= sizeof(long))
155 t = bb_strtol(date_str + 1, NULL, 10); 148 t = bb_strtol(date_str + 1, NULL, 10);
156 else /* time_t is 64 bits but longs are smaller */ 149 else /* time_t is 64 bits but longs are smaller */
157 t = bb_strtoll(date_str + 1, NULL, 10); 150 t = bb_strtoll(date_str + 1, NULL, 10);
158 if (!errno) { 151 if (!errno) {
159 struct tm *lt = localtime(&t); 152 struct tm *lt;
153 IF_FEATURE_TIMEZONE(localise:)
154 lt = localtime(&t);
160 if (lt) { 155 if (lt) {
161 *ptm = *lt; 156 *ptm = *lt;
162 return 0; 157 return 0;