vcs-svn: More dump format sanity checks
authorJonathan Nieder <jrnieder@gmail.com>
Sat, 20 Nov 2010 00:53:34 +0000 (18:53 -0600)
committerJunio C Hamano <gitster@pobox.com>
Wed, 24 Nov 2010 22:52:51 +0000 (14:52 -0800)
Node-action: change is not appropriate when switching between file and
directory or adding a new file.  Current svn-fe silently accepts such
nodes and the resulting tree has missing files in the "changed when
meant to add" case.

Node-action: add requires some content (text or directory); there is
no such thing as an "intent to add" node in svn dumps.  Current svn-fe
accepts such contentless adds but produces an invalid fast-import
stream that refers to nonexistent mark :0 in response.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t9010-svn-fe.sh
vcs-svn/svndump.c

index cb9a236245695fb723f9466e9c0d5d98709d7027..f1e8799bbd5e39ec28829aa30c42010c68b6dbf4 100755 (executable)
@@ -272,6 +272,27 @@ test_expect_success 'node without action' '
        test_must_fail test-svn-fe inaction.dump
 '
 
+test_expect_success 'action: add node without text' '
+       cat >textless.dump <<-\EOF &&
+       SVN-fs-dump-format-version: 3
+
+       Revision-number: 1
+       Prop-content-length: 10
+       Content-length: 10
+
+       PROPS-END
+
+       Node-path: textless
+       Node-kind: file
+       Node-action: add
+       Prop-content-length: 10
+       Content-length: 10
+
+       PROPS-END
+       EOF
+       test_must_fail test-svn-fe textless.dump
+'
+
 test_expect_failure 'change file mode but keep old content' '
        reinit_git &&
        cat >expect <<-\EOF &&
index 0af8ac6807c289599237ccc73a0eeed9fad5277a..ab4ccfc55fbd88750a5787d64e918c866c478aae 100644 (file)
@@ -181,12 +181,22 @@ static void handle_node(void)
        if (mark && type == REPO_MODE_DIR)
                die("invalid dump: directories cannot have text attached");
 
-       if (node_ctx.action == NODEACT_CHANGE)
-               node_ctx.type = repo_modify_path(node_ctx.dst, 0, mark);
-       else if (node_ctx.action == NODEACT_ADD)
+       if (node_ctx.action == NODEACT_CHANGE) {
+               uint32_t mode = repo_modify_path(node_ctx.dst, 0, mark);
+               if (!mode)
+                       die("invalid dump: path to be modified is missing");
+               if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR)
+                       die("invalid dump: cannot modify a directory into a file");
+               if (mode != REPO_MODE_DIR && type == REPO_MODE_DIR)
+                       die("invalid dump: cannot modify a file into a directory");
+               node_ctx.type = mode;
+       } else if (node_ctx.action == NODEACT_ADD) {
+               if (!mark && type != REPO_MODE_DIR)
+                       die("invalid dump: adds node without text");
                repo_add(node_ctx.dst, type, mark);
-       else
+       } else {
                die("invalid dump: Node-path block lacks Node-action");
+       }
 
        if (have_props) {
                const uint32_t old_mode = node_ctx.type;