#include "manage.h"
#include "crypto.h"
#include "route.h"
+#include "win32.h"
#include "memdbg.h"
if (safe_filename
&& strcmp (safe_filename, ".")
- && strcmp (safe_filename, ".."))
+ && strcmp (safe_filename, "..")
+#ifdef WIN32
+ && win_safe_filename (safe_filename)
+#endif
+ )
{
struct buffer out = alloc_buf_gc (256, gc);
char dirsep[2];
return NULL;
}
+/*
+ * Return true if filename is safe to be used on Windows,
+ * by avoiding the following reserved names:
+ *
+ * CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9,
+ * LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9, and CLOCK$
+ *
+ * See: http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ * and http://msdn.microsoft.com/en-us/library/86k9f82k(VS.80).aspx
+ */
+
+static bool
+cmp_prefix (const char *str, const bool n, const char *pre)
+{
+ const size_t len = strlen (pre);
+ size_t i = 0;
+
+ if (!str)
+ return false;
+
+ while (true)
+ {
+ const int c1 = pre[i];
+ int c2 = str[i];
+ ++i;
+ if (c1 == '\0')
+ {
+ if (n)
+ {
+ if (isdigit (c2))
+ c2 = str[i];
+ else
+ return false;
+ }
+ return c2 == '\0' || c2 == '.';
+ }
+ else if (c2 == '\0')
+ return false;
+ if (c1 != tolower(c2))
+ return false;
+ }
+}
+
+bool
+win_safe_filename (const char *fn)
+{
+ if (cmp_prefix (fn, false, "con"))
+ return false;
+ if (cmp_prefix (fn, false, "prn"))
+ return false;
+ if (cmp_prefix (fn, false, "aux"))
+ return false;
+ if (cmp_prefix (fn, false, "nul"))
+ return false;
+ if (cmp_prefix (fn, true, "com"))
+ return false;
+ if (cmp_prefix (fn, true, "lpt"))
+ return false;
+ if (cmp_prefix (fn, false, "clock$"))
+ return false;
+ return true;
+}
+
#endif