Skip to content

It doesn't handle small files (at least diff) #294

Description

@x-yuri
#!/bin/sh -eu
docker run --rm -it alpine:3.18 sh -euxc '
    apk add git git-crypt
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    mkdir r
    cd r
    git init
    git-crypt init
    echo "a filter=git-crypt diff=git-crypt" > .gitattributes
    git add .gitattributes && git commit -m .gitattributes
    echo a > a && git add a && git commit -m a
    git --no-pager show
'

Output:

...
+ git --no-pager show
commit c48eb1dd9139fffc07777256b8ac1b37c08c944f (HEAD -> master)
Author: Your Name <you@example.com>
Date:   Mon Jun 19 17:04:22 2023 +0000

    a

diff --git a/a b/a
new file mode 100644
index 0000000..722e550

Apparently it exits with non-zero status here. Since in.fail():

If the input sequence runs out of characters to extract (i.e., the end-of-file is reached) before n characters have been successfully read, the array pointed to by s contains all the characters read until that point, and both the eofbit and failbit flags are set for the stream.

https://cplusplus.com/reference/istream/istream/read/

#!/bin/sh -eu
docker run --rm -it alpine:3.18 sh -euxc '
    apk add git build-base openssl-dev
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
    git clone https://github.com/AGWA/git-crypt
    cd git-crypt
    nl=$(echo -e \\nx)
    nl=${nl%x}
    sed -Ei -e "/std::cout << in.rdbuf\(\);/{iif(!in.fail()){${nl}a}${nl}}" commands.cpp
    make CXXFLAGS=-DOPENSSL_API_COMPAT=0x30000000L install
    cd /
    mkdir r
    cd r
    git init
    git-crypt init
    echo "a filter=git-crypt diff=git-crypt" > .gitattributes
    git add .gitattributes && git commit -m .gitattributes
    echo a > a && git add a && git commit -m a
    git --no-pager show
'

Output:

...
+ git --no-pager show
commit c48eb1dd9139fffc07777256b8ac1b37c08c944f (HEAD -> master)
Author: Your Name <you@example.com>
Date:   Mon Jun 19 17:04:22 2023 +0000

    a

diff --git a/a b/a
new file mode 100644
index 0000000..722e550
--- /dev/null
+++ b/a
@@ -0,0 +1 @@
+a
diff --git a/commands.cpp b/commands.cpp
index 6b3c498..5bd9584 100644
--- a/commands.cpp
+++ b/commands.cpp
@@ -937,7 +937,9 @@ int diff (int argc, const char** argv)
        if (in.gcount() != sizeof(header) || std::memcmp(header, "\0GITCRYPT\0", 10) != 0) {
                // File not encrypted - just copy it out to stdout
                std::cout.write(reinterpret_cast<char*>(header), in.gcount()); // include the bytes which we alre ady read
+               if (!in.fail()) {
                        std::cout << in.rdbuf();
+               }
                return 0;
        }

It fails with files that are less than 22 bytes long (sizeof(header)).

I'm not a cpp programmer, so there might be a more appropriate solution.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions