Skip to content

Commit

Permalink
Implement ObjectChecker.check_path/2. (#154)
Browse files Browse the repository at this point in the history
Closes #131.
  • Loading branch information
scouten authored May 30, 2019
1 parent 872a389 commit 5c74e27
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 48 deletions.
78 changes: 31 additions & 47 deletions lib/xgit/lib/object_checker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -574,55 +574,39 @@ defmodule Xgit.Lib.ObjectChecker do
defp skip_object_id?(nil, _object_id), do: false
defp skip_object_id?(skiplist, object_id), do: MapSet.member?(skiplist, object_id)

# TO DO: https://github.com/elixir-git/xgit/issues/131

# /**
# * Check tree path entry for validity.
# * <p>
# * Unlike {@link #checkPathSegment(byte[], int, int)}, this version scans a
# * multi-directory path string such as {@code "src/main.c"}.
# *
# * @param path
# * path string to scan.
# * @throws org.eclipse.jgit.errors.CorruptObjectException
# * path is invalid.
# * @since 3.6
# */
# public void checkPath(String path) throws CorruptObjectException {
# byte[] buf = Constants.encode(path);
# checkPath(buf, 0, buf.length);
# }
#
# /**
# * Check tree path entry for validity.
# * <p>
# * Unlike {@link #checkPathSegment(byte[], int, int)}, this version scans a
# * multi-directory path string such as {@code "src/main.c"}.
# *
# * @param raw
# * buffer to scan.
# * @param ptr
# * offset to first byte of the name.
# * @param end
# * offset to one past last byte of name.
# * @throws org.eclipse.jgit.errors.CorruptObjectException
# * path is invalid.
# * @since 3.6
# */
# public void checkPath(byte[] raw, int ptr, int end)
# throws CorruptObjectException {
# int start = ptr;
# for (; ptr < end; ptr++) {
# if (raw[ptr] == '/') {
# checkPathSegment(raw, start, ptr);
# start = ptr + 1;
# }
# }
# checkPathSegment(raw, start, end);
# }

@doc ~S"""
Check tree path entry for validity.
`path` may be either a `String` or a byte list.
Unlike `check_path_segment/2`, this version scans a multi-directory path
string such as `"src/main.c"`.
Raises `CorruptObjectError` if the path is invalid.
"""
def check_path!(checker, path)

def check_path!(%__MODULE__{} = checker, path) when is_binary(path),
do: check_path!(checker, String.to_charlist(path))

def check_path!(%__MODULE__{} = _checker, []),
do: raise(CorruptObjectError, why: "empty path")

def check_path!(%__MODULE__{} = _checker, [?/ | _]),
do: raise(CorruptObjectError, why: "absolute path")

def check_path!(%__MODULE__{} = checker, path) when is_list(path) do
if Enum.any?(path, &(&1 == ?/)) do
{this, remainder} = Enum.split_while(path, &(&1 != ?/))
check_path_segment(checker, this)
check_path!(checker, Enum.drop(remainder, 1))
else
check_path_segment(checker, path)
end
end

@doc ~S"""
Check tree path segment for validity.
"""
def check_path_segment(%__MODULE__{} = checker, data) when is_list(data) do
if Enum.any?(data, &(&1 == 0)),
Expand Down
2 changes: 1 addition & 1 deletion lib/xgit/util/system_reader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ defprotocol Xgit.Util.SystemReader do

# PORTING NOTE: We do not implement check_path in SystemReader.
# Callers should instead create an instance of ObjectReader and call
# check_path_segment on that instance intead.
# check_path/2 using that instance intead.
end

defimpl Xgit.Util.SystemReader, for: Any do
Expand Down
23 changes: 23 additions & 0 deletions test/xgit/lib/object_checker_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,29 @@ defmodule Xgit.Lib.ObjectCheckerTest do
end
end

test "check_path/2" do
assert valid_path?("a")
assert valid_path?("a/b")
assert valid_path?("ab/cd/ef")

refute valid_path?("")
refute valid_path?("/a")
refute valid_path?("a//b")
refute valid_path?("ab/cd//ef")
refute valid_path?("a/")
refute valid_path?("ab/cd/ef/")
refute valid_path?("a\u0000b")
end

defp valid_path?(path) do
try do
ObjectChecker.check_path!(%ObjectChecker{}, path)
true
rescue
_ -> false
end
end

describe "check_path_segment/2" do
test "bug 477090" do
checker = %ObjectChecker{macosx?: true}
Expand Down

0 comments on commit 5c74e27

Please sign in to comment.