diff --git a/checkin_notes b/checkin_notes index 2f8b602aa0..09415d5830 100755 --- a/checkin_notes +++ b/checkin_notes @@ -25360,3 +25360,28 @@ Rom 27 Feb 2005 main.C lib/ diagnostics.C, .h + +David 27 Feb 2005 + If you attached to a project and give a URL like "a.b.c//", + two bad things happen: + 1) canonicalize_master_url() strips off everything before the //, + leaving an empty URL + 2) it will write an account file account_.xml + and make an entry in the client state file + 3) next time the core client starts up, it errors out + trying to create the project directory. + Fixes: + - canonicalize_master_url(): check before "://", not "//" + - is_account_file(): tighten up. + Old: anything starting with account_ is considered an account file. + New: must match account_A.B.xml where A and B are nonempty + - invalid_url(): + Old: must match http://X, X nonempty + New: must match http://X.Y/, X and Y nonempty + rename to valid_master_url() and invert sense + + client/ + cs_account.C + file_names.C + lib/ + util.C,h diff --git a/client/cs_account.C b/client/cs_account.C index 39832d3119..229f8224a9 100644 --- a/client/cs_account.C +++ b/client/cs_account.C @@ -230,7 +230,7 @@ int CLIENT_STATE::add_project(const char* master_url, const char* _auth) { safe_strcpy(canonical_master_url, master_url); strip_whitespace(canonical_master_url); canonicalize_master_url(canonical_master_url); - if (invalid_url(canonical_master_url)) { + if (!valid_master_url(canonical_master_url)) { msg_printf(0, MSG_ERROR, "Invalid project URL: %s", canonical_master_url); return ERR_INVALID_URL; } diff --git a/client/file_names.C b/client/file_names.C index bd1f99befa..a35e643a14 100644 --- a/client/file_names.C +++ b/client/file_names.C @@ -133,8 +133,33 @@ void get_account_filename(char* master_url, char* path) { sprintf(path, "account_%s.xml", buf); } +static bool bad_account_filename(const char* filename) { + msg_printf(NULL, MSG_ERROR, "Invalid account file: %s", filename); + return false; +} + +// account filenames are of the form +// account_URL.xml +// where URL is master URL with slashes replaced by underscores +// bool is_account_file(const char* filename) { - return (strstr(filename, "account_") == filename); + const char* p, *q; + p = strstr(filename, "account_"); + if (p != filename) return false; + q = filename + strlen("account_"); + + p = strstr(q, "."); + if (!p) return bad_account_filename(filename); + if (p == q) return bad_account_filename(filename); + + q = p+1; + p = strstr(q, ".xml"); + if (!p) return bad_account_filename(filename); + if (p == q) return bad_account_filename(filename); + + q = p + strlen(".xml"); + if (strlen(q)) return bad_account_filename(filename); + return true; } int check_unique_instance() { diff --git a/lib/util.C b/lib/util.C index 3064e84718..99eb232390 100755 --- a/lib/util.C +++ b/lib/util.C @@ -420,7 +420,7 @@ void escape_url_readable(char *in, char* out) { } // Canonicalize a master url. -// - Convert the first part of a URL (before the "//") to http://, +// - Convert the first part of a URL (before the "://") to http://, // or prepend it // - Remove double slashes in the rest // - Add a trailing slash if necessary @@ -429,9 +429,9 @@ void canonicalize_master_url(char* url) { char buf[1024]; size_t n; - char *p = strstr(url, "//"); + char *p = strstr(url, "://"); if (p) { - strcpy(buf, p+2); + strcpy(buf, p+3); } else { strcpy(buf, url); } @@ -447,11 +447,24 @@ void canonicalize_master_url(char* url) { sprintf(url, "http://%s", buf); } +// is the string a valid master URL, in canonical form? +// +bool valid_master_url(char* buf) { + char* p, *q; + int n; -bool invalid_url(char* p) { - if (strstr(p, "http://") != p) return true; - if (strlen(p) == strlen("http://")) return true; - return false; + p = strstr(buf, "http://"); + if (p != buf) return false; + q = p+strlen("http://"); + p = strstr(q, "."); + if (!p) return false; + if (p == q) return false; + q = p+1; + p = strstr(q, "/"); + if (!p) return false; + if (p == q) return false; + n = strlen(buf); + if (buf[n-1] != '/') return false; } void safe_strncpy(char* dst, const char* src, int len) { diff --git a/lib/util.h b/lib/util.h index 12269bca96..96c3d0e37e 100755 --- a/lib/util.h +++ b/lib/util.h @@ -48,7 +48,7 @@ extern void strip_whitespace(std::string&); extern void unescape_url(char *url); extern void escape_url(char *in, char*out); extern void escape_url_readable(char* in, char* out); -extern bool invalid_url(char*); +extern bool valid_master_url(char*); extern void canonicalize_master_url(char *url); extern void safe_strncpy(char*, const char*, int); #define safe_strcpy(x, y) safe_strncpy(x, y, sizeof(x))