[Toybox] [PATCH] mktemp: yet more tests, and yet more fixes.

enh enh at google.com
Wed Dec 5 17:34:29 PST 2018


In particular this reuses the password.c code for random ASCII bytes.
---
 lib/lib.h         |  1 +
 lib/password.c    | 35 +++++++++++++++++++++--------------
 tests/mktemp.test |  6 ++++++
 toys/lsb/mktemp.c | 24 ++++++++++++++++++------
 4 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/lib/lib.h b/lib/lib.h
index 14bb7cf6..d51bad4a 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -306,6 +306,7 @@ int pollinate(int in1, int in2, int out1, int
out2, int timeout, int shutdown_ti
 char *ntop(struct sockaddr *sa);

 // password.c
+void get_random_ascii(char *buf, int buflen);
 int get_salt(char *salt, char * algo);

 // commas.c
diff --git a/lib/password.c b/lib/password.c
index b9cc1346..e3598989 100644
--- a/lib/password.c
+++ b/lib/password.c
@@ -8,6 +8,26 @@
 #include "toys.h"
 #include <time.h>

+void get_random_ascii(char *buf, int buflen)
+{
+  int i;
+
+  // Read appropriate number of random bytes for salt
+  xgetrandom(libbuf, ((buflen*6)+7)/8, 0);
+
+  // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z
+  for (i=0; i<buflen; i++) {
+    int bitpos = i*6, bits = bitpos/8;
+
+    bits = ((libbuf[i]+(libbuf[i+1]<<8)) >> (bitpos&7)) & 0x3f;
+    bits += 46;
+    if (bits > 57) bits += 7;
+    if (bits > 90) bits += 6;
+
+    buf[i] = bits;
+  }
+}
+
 // generate ID prefix and random salt for given encryption algorithm.
 int get_salt(char *salt, char *algo)
 {
@@ -23,20 +43,7 @@ int get_salt(char *salt, char *algo)

       if (al[i].id) s += sprintf(s, "$%c$", '0'+al[i].id);

-      // Read appropriate number of random bytes for salt
-      xgetrandom(libbuf, ((len*6)+7)/8, 0);
-
-      // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z
-      for (i=0; i<len; i++) {
-        int bitpos = i*6, bits = bitpos/8;
-
-        bits = ((libbuf[i]+(libbuf[i+1]<<8)) >> (bitpos&7)) & 0x3f;
-        bits += 46;
-        if (bits > 57) bits += 7;
-        if (bits > 90) bits += 6;
-
-        s[i] = bits;
-      }
+      get_random_ascii(s, len);
       salt[len] = 0;

       return s-salt;
diff --git a/tests/mktemp.test b/tests/mktemp.test
index ee023d6b..0c235469 100755
--- a/tests/mktemp.test
+++ b/tests/mktemp.test
@@ -37,3 +37,9 @@ testing "-p DIR -t TEMPLATE but no TMPDIR" "TMPDIR=
mktemp -u -p DIR -t hello.XX

 # mktemp -u doesn't need to be able to write to the directory.
 testing "-u" "mktemp -u -p /proc | grep -q '^/proc/tmp\...........$'
&& echo yes" "yes\n" "" ""
+
+# mktemp needs at least XX in the template.
+testing "bad template" "mktemp -u helloX || echo error" "error\n" "" ""
+
+# mktemp -q shouldn't print the path.
+testing "-q" "mktemp -p /proc -q || echo only-failure" "only-failure\n" "" ""
diff --git a/toys/lsb/mktemp.c b/toys/lsb/mktemp.c
index 57d1d118..b9e144dc 100644
--- a/toys/lsb/mktemp.c
+++ b/toys/lsb/mktemp.c
@@ -37,6 +37,7 @@ void mktemp_main(void)
   int template_dir = template && !!strchr(template, '/');
   int flags_dir = (toys.optflags & (FLAG_p|FLAG_t));
   int use_dir = flags_dir && !template_dir;
+  char *s, *e;

   if (template_dir && flags_dir) error_exit("conflicting directories given");

@@ -61,12 +62,23 @@ void mktemp_main(void)
   // TODO: coreutils cleans paths, so -p /t/// would result in /t/xxx...
   template = use_dir ? xmprintf("%s/%s", TT.p, template) : xstrdup(template);

-  if (toys.optflags & FLAG_u) {
-    template = mktemp(template);
-  } else if (toys.optflags & FLAG_d ? !mkdtemp(template) :
mkstemp(template) == -1) {
-    if (toys.optflags & FLAG_q) toys.exitval = 1;
-    else perror_exit("Failed to create %s %s/%s",
-        toys.optflags & FLAG_d ? "directory" : "file", TT.p, template);
+  // Point `s` and `e` to the start and end of the last region of XXXXXXes.
+  s = e = strrchr(template, 'X');
+  if (!e || e == template || *(e-1) != 'X') error_exit("need XX in template");
+  while (s >= template && *(s-1) == 'X') --s;
+
+  while (1) {
+    struct stat sb;
+
+    get_random_ascii(s, (e-s+1));
+    if ((FLAG(u) && lstat(template, &sb) == -1 && errno == ENOENT) ||
+        (FLAG(d) && mkdir(template, 0700) != -1) ||
+        (open(template, O_CREAT|O_CLOEXEC, 0500) != -1)) break;
+    if (errno == EEXIST) continue;
+    if (FLAG(q)) {
+      toys.exitval = 1;
+      return;
+    } else perror_exit("%s", template);
   }
   xputs(template);

-- 
2.20.0.rc1.387.gf8505762e3-goog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mktemp-yet-more-tests-and-yet-more-fixes.patch
Type: text/x-patch
Size: 4554 bytes
Desc: not available
URL: <http://lists.landley.net/pipermail/toybox-landley.net/attachments/20181205/67c79726/attachment-0002.bin>


More information about the Toybox mailing list