diff --git a/fileserver/fileop.go b/fileserver/fileop.go index 87a7ab5..46511f2 100644 --- a/fileserver/fileop.go +++ b/fileserver/fileop.go @@ -1472,6 +1472,11 @@ func postMultiFiles(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, canonPath := getCanonPath(parentDir) + if !replace && checkFilesWithSameName(repo, canonPath, fileNames) { + msg := "Too many files with same name.\n" + return &appError{nil, msg, http.StatusBadRequest} + } + for _, fileName := range fileNames { if shouldIgnoreFile(fileName) { msg := fmt.Sprintf("invalid fileName: %s.\n", fileName) @@ -1558,6 +1563,26 @@ func postMultiFiles(rsp http.ResponseWriter, r *http.Request, repoID, parentDir, return nil } +func checkFilesWithSameName(repo *repomgr.Repo, canonPath string, fileNames []string) bool { + commit, err := commitmgr.Load(repo.ID, repo.HeadCommitID) + if err != nil { + return false + } + dir, err := fsmgr.GetSeafdirByPath(repo.StoreID, commit.RootID, canonPath) + if err != nil { + return false + } + + for _, name := range fileNames { + uniqueName := genUniqueName(name, dir.Entries) + if uniqueName == "" { + return true + } + } + + return false +} + func postFilesAndGenCommit(fileNames []string, repoID string, user, canonPath string, replace bool, ids []string, sizes []int64) (string, error) { repo := repomgr.Get(repoID) if repo == nil { diff --git a/include/seafile-error.h b/include/seafile-error.h index 8a3e26d..1564760 100644 --- a/include/seafile-error.h +++ b/include/seafile-error.h @@ -23,5 +23,6 @@ #define POST_FILE_ERR_BLOCK_MISSING 518 #define POST_FILE_ERR_QUOTA_FULL 519 #define SEAF_ERR_CONCURRENT_UPLOAD 520 +#define SEAF_ERR_FILES_WITH_SAME_NAME 521 #endif diff --git a/server/repo-op.c b/server/repo-op.c index d34718b..7c97bf3 100644 --- a/server/repo-op.c +++ b/server/repo-op.c @@ -1018,6 +1018,47 @@ format_json_ret (GList *name_list, GList *id_list, GList *size_list) return ret; } +static gboolean +check_files_with_same_name (SeafRepo *repo, const char *parent_dir, GList *filenames) +{ + char *canon_path = NULL; + SeafCommit *commit = NULL; + SeafDir *dir = NULL; + GError *error = NULL; + gboolean ret = FALSE; + + GET_COMMIT_OR_FAIL(commit, repo->id, repo->version, repo->head->commit_id); + + canon_path = get_canonical_path (parent_dir); + + dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, + repo->store_id, repo->version, + commit->root_id, + canon_path, &error); + if (!dir) { + goto out; + } + + GList *ptr; + for (ptr = filenames; ptr; ptr = ptr->next) { + char *name = ptr->data; + char *unique_name = NULL; + unique_name = generate_unique_filename (name, dir->entries); + if (!unique_name) { + ret = TRUE; + goto out; + } + g_free (unique_name); + } +out: + g_clear_error (&error); + g_free (canon_path); + seaf_dir_free (dir); + seaf_commit_unref (commit); + + return ret; +} + int seaf_repo_manager_post_multi_files (SeafRepoManager *mgr, const char *repo_id, @@ -1053,6 +1094,13 @@ seaf_repo_manager_post_multi_files (SeafRepoManager *mgr, goto out; } + if (!replace_existed && check_files_with_same_name (repo, parent_dir, filenames)) { + seaf_debug ("[post files] Too many files with same name.\n"); + g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_FILES_WITH_SAME_NAME, "Too many files with same name"); + ret = -1; + goto out; + } + /* Check inputs. */ for (ptr = filenames; ptr; ptr = ptr->next) { filename = ptr->data; diff --git a/server/upload-file.c b/server/upload-file.c index d41346c..c860fb3 100755 --- a/server/upload-file.c +++ b/server/upload-file.c @@ -584,6 +584,9 @@ upload_api_cb(evhtp_request_t *req, void *arg) if (error) { if (error->code == POST_FILE_ERR_FILENAME) { error_code = ERROR_FILENAME; + } else if (error->code == SEAF_ERR_FILES_WITH_SAME_NAME) { + error_code = -1; + send_error_reply (req, EVHTP_RES_BADREQ, "Too many files with same name.\n"); } g_clear_error (&error); } @@ -1196,6 +1199,9 @@ upload_ajax_cb(evhtp_request_t *req, void *arg) if (error) { if (error->code == POST_FILE_ERR_FILENAME) { error_code = ERROR_FILENAME; + } else if (error->code == SEAF_ERR_FILES_WITH_SAME_NAME) { + error_code = -1; + send_error_reply (req, EVHTP_RES_BADREQ, "Too many files with same name.\n"); } g_clear_error (&error); }