Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement symlink functionality with filepath.EvalSymlinks() #55

Merged
merged 13 commits into from
Jun 23, 2020

Conversation

shibumi
Copy link
Collaborator

@shibumi shibumi commented Jun 5, 2020

Please fill in the fields below to submit a pull request. The more
information that is provided, the better.

Fixes issue #:
#32
as well as PR #37

Description of pull request:
We are using filepath.EvalSymlinks() here, because it will
give us the last element in a symlink chain.
Therefore we don't need to worry about stack size
or recursion cycles.

Please verify and check that the pull request fulfills the following
requirements
:

  • Tests have been added for the bug fix or new feature
  • Docs have been added for the bug fix or new feature

We are using filepath.EvalSymlinks() here, because it will
give us the last element in a symlink chain.
Therefore we don't need to worry about stack size
or recursion cycles.
@shibumi shibumi closed this Jun 5, 2020
@shibumi shibumi reopened this Jun 5, 2020
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 5, 2020

mh ok this is weird.. when I run these tests locally they work...:

=== RUN   TestSymlinkToFile
--- PASS: TestSymlinkToFile (0.00s)
=== RUN   TestSymlinkToFolder
--- PASS: TestSymlinkToFolder (0.00s)

is this again some Windows related stuff?

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 5, 2020

mhh looks like an error in path translation between Linux paths and Windows paths?!

json: unsupported type: func(*testing.T)
open bad/path: The system cannot find the path specified.
--- FAIL: TestSymlinkToFolder (0.00s)
    runlib_test.go:82: RecordArtifacts returned '(map[symTest\symTest2\symTmpfile:map[sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad]], %!s(<nil>))', expected '(map[symTest/symTest2/symTmpfile:map[sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad]], nil)'

I have also no idea where this "%!s(<nil>)" comes from

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 5, 2020

Doesn't windows support SymLinks?

EDIT: no.. then the symlink wouldn't work at all.. right now it's calculating the hash correct

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 5, 2020

I think I fixed the file path matching via using: filepath.FromSlash().. I am just wondering why this works for all the other tests.. lol.

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 7, 2020

Mh I think I will add 1-2 more tests to the symlink code. I am not convinced yet, that it's secure without a max recursion parameter

-> draft

@shibumi shibumi changed the title implement symlink functionality with filepath.EvalSymlinks() WI{P: implement symlink functionality with filepath.EvalSymlinks() Jun 7, 2020
@shibumi shibumi marked this pull request as draft June 7, 2020 15:55
@shibumi shibumi changed the title WI{P: implement symlink functionality with filepath.EvalSymlinks() WIP: implement symlink functionality with filepath.EvalSymlinks() Jun 7, 2020
I knew it.. looks like we are running in a cycle, so we really need a recursion counter or some sort of history where we log visited files?
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 9, 2020

I've added a test for this PR.. seems I were wrong and filepath.EvalSym() can not detect symlinks. :S
The newest test proofs this.

I could re-implement the recursion counter from the other PR or create a history or something.

We also introduce our first custom error called "SymCycleErr".
If we detect a symlink cycle, we are now failing completely.
Symlink cycles should not exist.
@shibumi shibumi marked this pull request as ready for review June 9, 2020 11:46
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 9, 2020

@lukpueh Can you have a look on this PR, too? I have reimplemented most of the PR #37.
The only difference here is that we return an error if detect a symlink cycle instead of going further.
I really think there should be no valid reason why a software project or any other project should build cycles with symlinks

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 9, 2020

@lukpueh I have also added our first custom error. The error handling got some nice changes in go 1.13, we can use these changes and return our own library specific errors instead. This makes developers life easier, because they don't need to compare strings anymore.
They can just do:

if err == errors.Is(err, OurCustomErr){ ..}

@shibumi shibumi changed the title WIP: implement symlink functionality with filepath.EvalSymlinks() implement symlink functionality with filepath.EvalSymlinks() Jun 9, 2020
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 9, 2020

Shall I squash this PR into one commit? would make it easier, if we encounter problems to revert it.

@lukpueh lukpueh mentioned this pull request Jun 11, 2020
2 tasks
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib_test.go Show resolved Hide resolved
@lukpueh
Copy link
Member

lukpueh commented Jun 11, 2020

Many thanks for the great work, @shibumi. I left a few minor suggestions and questions.

We need to follow our style guide and use 80 as
max length for non-GoDocs comments.
move global variables to the top for better visibility
Our former method of symlink detection has been
with recursion depth. The new method introduces
a symlink history with a hashset. This should
has a better performance
Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for coming up with and implementing this new approach, @shibumi! It looks a lot better than what we had before. Will this also work if we called RecordArtifacts twice? I think you need to reset visitedSymlinks at some point.

Thanks for addressing my review comment regarding line width. Is there a reason why you now sometimes wrap quite a bit before 80 chars? IMO you can use the full 80 chars for code comments.

in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
in_toto/runlib.go Outdated Show resolved Hide resolved
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 15, 2020

I will squash the last 2 nonsense commits from github UI to one 'refactor comments' commit. Shouldn't use github for applying changes directly .. sigh

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 15, 2020

Thanks for coming up with and implementing this new approach, @shibumi! It looks a lot better than what we had before. Will this also work if we called RecordArtifacts twice? I think you need to reset visitedSymlinks at some point.

We could pass a set as argument, that way we could control the passed set and on recursion depth 0 devs would need to pass an empty set as initialization. It's the only solution I come up with, but I will think about this till Friday afternoon.

@lukpueh
Copy link
Member

lukpueh commented Jun 15, 2020

💯 Thanks, that's what I usually do. I like the feature from a reviewer's perspective, but I also think there should be no "Update XYZ" commits.

@lukpueh
Copy link
Member

lukpueh commented Jun 15, 2020

We could pass a set as argument, that way we could control the passed set and on recursion depth 0 devs would need to pass an empty set as initialization.

Sounds like a good idea. Or we add a wrapper like so:

# pseudo-code
function RecordArtifacts(paths):
  setup global var
  _recordArtifacts(paths) # recurse but don't visit symlinks more than once
  tear down global var

@shibumi
Copy link
Collaborator Author

shibumi commented Jun 15, 2020

I like the wrapper variant. This is better than passing a map. We could do it like the other big Golang libraries and just write recordArtifacts, for example os.Rename(): https://golang.org/src/os/file.go?s=9921:9963#L313

@shibumi shibumi force-pushed the shibumi/add-symlink-support branch from 1a7d28c to 4e877f7 Compare June 20, 2020 00:28
We need to make sure to initialize + tear down our global variable.
Therefore we move the RecordArtifacts functionality to recordArtifacts and build a wrapper around it called RecordArtifacts. Moreover we do not need to reimplement the
set, we can just the set from util.Set
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 20, 2020

@lukpueh I am not sure if visitedSymlinks = nil is enough for 'removing' the variable and tearing it down correctly. This should work, if we want to be sure I could also implement a RemoveAll function for our Set and call that one. 5min of Google said setting it nil should be enough.

@shibumi shibumi requested a review from lukpueh June 21, 2020 00:14
Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks for implementing the wrapper approach and for adding extensive testing. I have one question left (inline). Let me know what you think.

in_toto/runlib.go Outdated Show resolved Hide resolved
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 23, 2020

@lukpueh I've fixed the nil check for the visitedSymlinks hashset. Ping me if you find something else :)

@shibumi shibumi force-pushed the shibumi/add-symlink-support branch from 97d0ad2 to 2a845b1 Compare June 23, 2020 08:59
@shibumi
Copy link
Collaborator Author

shibumi commented Jun 23, 2020

@lukpueh checks passed, ready to merge. When merged, I will use the current master as base for the intoto-run implementation.

Copy link
Member

@lukpueh lukpueh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quality contribution, @shibumi!

@lukpueh lukpueh merged commit 1868def into in-toto:master Jun 23, 2020
@shibumi shibumi deleted the shibumi/add-symlink-support branch June 23, 2020 09:08
lukpueh added a commit to lukpueh/in-toto-golang that referenced this pull request Jun 24, 2020
Symlink walk support in RecordArtifacts was kindly added by
@shibumi in in-toto#55, fixing in-toto#32. This commit removes the note that it
is not yet supported.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants