Repository navigation
Releases: jelmer/dulwich
Release list
dulwich-1.2.17
- Define
__all__in all modules, listing the public names each module defines. (Jelmer VernooΔ³) - Deprecate importing
LOCAL_TAG_PREFIX,SYMREF,check_ref_format,read_packed_refs,read_packed_refs_with_peeledandwrite_packed_refsfromdulwich.repo; import them fromdulwich.refsinstead. LikewiseBundleList,fetch_bundle_uriandparse_bundle_listshould be imported fromdulwich.bundle_urirather thandulwich.client. (Jelmer VernooΔ³) - Restore
dulwich.index.SHA1Readeranddulwich.index.SHA1Writer, which were dropped in 1.2.16, as deprecated aliases for the classes indulwich.pack. (Jelmer VernooΔ³) - Refuse to write a loose ref through a symref whose target escapes the ref store. (Kartik Kenchi, Jelmer VernooΔ³)
dulwich-1.2.16
- Add
PackIndex.object_sha_at_positionto look up an object by its position in the sorted index, and use it when loading a.bitmapinstead of re-scanning the index for every entry, which made loading quadratic in the pack size, unlike git. (Kartik Kenchi) - Fix applying patches without content changes, such as mode changes and added or deleted empty files. They have no
---/+++lines and failed with "Patch has no file path". (Jelmer VernooΔ³) - Fix applying binary patches produced by
git diff --binary. Their paths are now taken from thediff --gitline,literaldata is inflated, base85 line lengths are decoded correctly and binary deletions remove the file. (Jelmer VernooΔ³) - Support
deltabinary patches, binary changes combined with a rename or copy and reverse application of binary patches inapply_patches. (Jelmer VernooΔ³) - Unquote C-style quoted file names (as git emits for names with special or non-ASCII characters) when parsing patches. (Jelmer VernooΔ³)
- SECURITY: Validate index paths in sparse checkout, mixed reset,
lfs_pullandlfs_migrate, so that a malicious repository can no longer write files outside the work tree via..entries or symlinks. (Jelmer VernooΔ³, reported by Choudhry Shehryar) - SECURITY: Don't write through symlinks in
apply_patches. A tracked symlink such astrap -> .git/hooks/pre-commitwas followed when writing, soporcelain.am/apply_patchcould install a hook. Symlinks are now patched as links, like git does, and a patch whose mode doesn't match the type in the work tree or that adds a file over an existing path is refused. (Jelmer VernooΔ³, reported by @manus-pi) - Apply a mode change in
build_file_from_blobwhen the content is unchanged. (Jelmer VernooΔ³) - Fix parsing of a rename or copy without content changes followed by another patch, which swallowed the next patch. (Jelmer VernooΔ³)
- Honour
\ No newline at end of filemarkers when applying patches, which previously made patches to files without a trailing newline fail. (Jelmer VernooΔ³) - Ignore a
multi-pack-indexentry whose pack has been removed when answering whether an object is present. After a prune the stale index madesha in repo.object_storedisagree withrepo.object_store[sha]. (Kartik Kenchi) - Don't follow a symlink when reading
.gitignoreor.gitattributesfrom the work tree. A tree could point either name at a file outside the repository and have its contents drive dulwich. (Kartik Kenchi) - Honour
GIT_OPTIONAL_LOCKS=0indulwich status, skipping the index stat-cache refresh that would otherwise lock the index. (Jelmer VernooΔ³, #1861) - Preserve original URL in remote origin configuration when cloning, matching C git behavior. (Suprovo Ghosh, #2428)
- Report conflicts in criss-cross merges where the merge bases disagree on a file. The recursive merge silently kept one base's blob as the virtual base, so the final three-way merge published the other side's content without recording a conflict. (Jelmer VernooΔ³, #2419)
- Record merge conflicts in the index with stages 1/2/3 and write MERGE_HEAD/MERGE_MSG when
porcelain.mergeleaves conflicts, so the working tree matches git's state andgit commitcan finish the merge. (Jelmer VernooΔ³) - Preserve index entries that differ only by case when loading the index, resetting mixed, or restoring a stashed index tree under core.ignorecase. (Jelmer VernooΔ³, #2434)
- Fix a crash in
dulwich log <path>on merge commits where the path is unchanged relative to one parent.tree_changes_for_mergereportsNonefor such parents, which the walker and the--name-statusand--name-onlyoutput wrongly assumed to be aTreeChange. (Jelmer VernooΔ³, #2412) dulwich log <path>now applies git's default history simplification. Pass--full-historyfor the old behavior.Walkerandget_walkergain asimplify_historyflag. (Jelmer VernooΔ³, #2414)- Carry the repository's object format through the index and the work tree.
addandcommiton a SHA-256 repository wrote SHA-1 identities into the index, trees and refs, leaving a repository neither dulwich nor git could read back. (Jelmer VernooΔ³, #2416) - Honour the
eolgitattribute. Line ending conversion is now resolved per path from thetext/crlfandeolattributes, falling back tocore.autocrlfandcore.eolonly where the attributes are silent, soeol=crlfandeol=lftake precedence over the configuration as they do in git. (Jelmer VernooΔ³, #2403) - Write carriage returns in configuration values literally rather than as a
\rescape. (Jelmer VernooΔ³) - Strip leading blank lines in
stripspacein a single pass. The previouspop(0)loop made an all-blank input O(n^2); it is now linear like git. (Kartik Kenchi)
dulwich-1.2.15
- Detect delta cycles in
Pack.resolve_object: a crafted pack with REF_DELTA objects that name each other sentget_rawinto an unbounded loop. Such chains now raiseDeltaCycle. - Fix
porcelain.cleanwhen the target directory and the repository path are spelled differently, such as via a relative path or a symlink. (Jelmer VernooΔ³) - Memoize tag peeling on the object store, so refs sharing an annotated tag chain no longer re-walk it once per ref.
show_ref --dereferenceand the ref advertisement were quadratic. (Jelmer VernooΔ³, #2406) - Give a
.gitignorein a subdirectory precedence over one closer to the root, matching git. A negation in a deeper file no longer loses to a rule at the root, and a nested negation no longer re-includes a path whose parent directory stays excluded. (Jelmer VernooΔ³, #2399) - Reject reftable
tables.listentries that contain a path separator or are absolute, so a hostile repository cannot make a ref lookup open a file outside the reftable directory. (netliomax25-code) - Support
dulwich commit -C/--reuse-messageand-c/--reedit-messageto reuse a commit's message, author and author date, optionally editing the message. The committer and new commit ancestry remain independent. (eunwoo song, #1845) - List local branches for bare
dulwich branchand standalonedulwich branch --list [pattern]. Listing empty repositories or patterns with no matches succeeds without changing refs. (be-student, #1847) - Add
dulwich commit --author="Name <email>"to override the author of a new or amended commit. (kudala-bharani, #1845) - Set
branch.<name>.remoteandbranch.<name>.mergefor the branch checked out by a clone, so that a subsequentgit pullwith no arguments has tracking information. (Jelmer VernooΔ³, #2376) - Keep relative paths relative in
SSHGitClient.get_url, emitting git'sssh://host/~/pathform. Cloning from an scp-style URL likeuser@host:git/repo.gitpreviously storedssh://user@host/git/repo.gitas the remote URL, which points at a different repository. (Jelmer VernooΔ³, #2375) - Name a symlink by its own path in
porcelain.path_to_tree_path, rather than by the path of its target.porcelain.statuslisted a tracked symlink as untracked whenever the file it pointed at was itself untracked or missing, so a modified symlink was reported twice. (Jerry Xiao) - Ignore gitignore lines that carry no pattern, such as a bare
!or/. A bare!previously re-included a directory that an earlier pattern in the same file had ignored. (Jelmer VernooΔ³, #2398) - Avoid quadratic cost in
PktLineParser.parse, which resliced its remaining buffer once per pkt-line. (Jelmer VernooΔ³, #2408)
dulwich-1.2.14
Collapse consecutive ** segments in wildmatch translation, matching git's behavior and avoiding catastrophic regex backtracking on patterns like a/**/**/**/z from untrusted repositories. (netliomax25-code)
dulwich-1.2.13
-
Make concurrent
Pack.get_rawcalls thread-safe by synchronizing
PackData's resolved-object offset cache.
(Bojan Zivanovic) -
Speed up cached
PackData.get_object_atlookups by acquiring the
offset-cache lock directly instead of through awithstatement.
(Bojan Zivanovic) -
Bound fetch negotiation the way C Git's
MAX_IN_VAINdoes: give up
after 256 unacknowledged "have" lines instead of draining the whole
graph walker into stateless (HTTP) requests. (Bojan Zivanovic, #2343) -
Add
repo.sanitize_user_identity, which builds an identity from a
name and an email sanitized the way git'sfmt_identdoes, for
callers who cannot reject invalid input viacheck_user_identity.
(Bojan Zivanovic, #2342) -
Make concurrent
PackDatareads thread-safe by mmap-ing pack contents
and indexing the mapping at explicit offsets instead of sharing the file
position. Newunpack_object_at,read_pack_header_at,
read_zlib_chunks_at,take_msb_bytes_atandcompute_buffer_sha
read from a buffer; the existing read-callable variants remain for streams.
(Bojan Zivanovic, Jelmer VernooΔ³) -
Deduplicate the commit walk in
find_shallowandget_depth
(dulwich.object_store). Both re-expanded a commit once per path that
reached it, so a merge-heavy history walked in exponential time.
(netliomax25-code) -
SECURITY: Don't follow symlinks when writing messages in
porcelain.format_patch,mbox.split_mboxandmbox.split_maildir.
A symlink pre-planted at an output filename was followed, writing the
message outside the output
directory. (Jelmer VernooΔ³; Reported by wzc) -
Only reject reserved Windows device names (
aux,nul,con, ...)
when actually running on Windows. C git confines this check to its Windows
compat layer, so repositories carrying such paths could not be cloned
elsewhere. (Jelmer VernooΔ³, #2351) -
Fix
ignoreandattrsmatching for patterns ending in**/. The
trailing slash was dropped when translating the pattern, sofoo/**/also
matchedfoo/itself and every file directly inside it. Git only ignores
the directories belowfoo. (adarshsm) -
Catch
PackFileDisappearedin the bitmap probe in
get_reachability_provider, which only guardedFileNotFoundError.
(Jelmer VernooΔ³, #2344) -
SECURITY: Widen modes for
core.sharedRepositoryas git does rather than
chmodding to a precomputed one, which left.git/hooksand.git/refs
world-writable forall. (netliomax25-code, Jelmer VernooΔ³, #2323) -
parse_shared_repositorynow returns aSharedPerm, and
DiskObjectStore,IndexandGitFiletake ashared_perm
argument in place offile_mode/dir_mode. (Jelmer VernooΔ³) -
Fix commit-graph extra edge indexing: the stored value is a position in a
list of 4-byte entries, not a byte offset, so every octopus merge after
the first got a wrong parent list. (netliomax25-code) -
Refresh the mtime of an existing loose object in
DiskObjectStore.add_object(), so that a concurrentgit gccannot
prune an object that was just reported as present.
(Bojan Zivanovic, #2340) -
HARDEN: Validate shallow object ids received from the remote.
(netliomax25-code) -
SECURITY: Refuse patch targets addressing the
.gitcontrol directory.
apply_patches(viaporcelain.am/apply_patch) previously wrote and
ran.git/hooks/pre-commit. (Jelmer VernooΔ³, reported by @bhaswanthc) -
Extend the
verify_leading_dirssymlink guard to
update_working_tree(used bypull,mergeandcheckout).
The 1.2.12 fix only coveredbuild_index_from_tree, so a tree pairing a
symlinkxwith a descendantx/configcould still write through the
link and overwrite.git/configon pull.
(Jelmer VernooΔ³, reported by Hugh Lewis) -
Translate
.gitignore/.gitattributesbracket expressions with Git's
wildmatch()semantics:[^...]negation, POSIX classes, backslash
escapes and malformed-class handling.ignoreandattrsnow share
one translator, the new publicdulwich.wildmatch.
(Vincent Gao, #2326) -
Always single-quote the repository path in the SSH command, matching git's
sq_quote().shlex.quoteleft paths without shell metacharacters
bare, which broke cloning from servers that parse the command themselves
rather than handing it to a shell, such as Bitbucket Server.
(Jelmer VernooΔ³, #2319)
dulwich-1.2.12
-
SECURITY: Refuse to write a checkout entry whose leading path resolves
through a symlink. `build_index_from_tree` (used by `reset_index` and
thus by `clone`/`checkout`) materialized a tree in sorted order without
checking leading components, so a tree pairing a symlink `link` with a
descendant `link/foo` wrote `foo` through the link to an arbitrary
absolute path. The same `verify_leading_dirs` guard already used by
porcelain and stash is now applied here.
(Jelmer VernooΔ³, reported by Hugh Lewis) -
Fix `Bundle.store_objects()` silently dropping every OFS_DELTA/REF_DELTA
object in the bundle's pack instead of resolving it, leaving the target
object store missing most objects with no error raised. Delta resolution
now goes through `PackInflater`, matching how packs are ingested
elsewhere in the object store code.
(theVinchi, #2312)
dulwich-1.2.11
Security and hardening
- Apply
core.protectHFSandcore.protectNTFStogether when selecting the checkout path-element validator. Previously only the NTFS validator ran whenprotectNTFSwas on (the default), so on macOS an HFS+ spelling of.gitusing ignorable code points could pass validation and poison.giton checkout. - Canonicalize file modes in
git archivetarballs, so a crafted tree entry can no longer carry setuid/setgid/sticky bits into an extracted file. - Collapse embedded whitespace in reflog messages, so a crafted multi-line commit message can no longer forge additional reflog entries with attacker-chosen SHAs.
- Verify that a
.bitmapindex matches the pack it is loaded for, so a stale or swapped-in bitmap can't produce a wrong reachable-object set during fetch negotiation. - Parse commit-message trailers in linear time, fixing a cubic blowup where a crafted commit message could tie up CPU for minutes to hours.
Features and fixes
- Honour
core.worktree, so the working tree can live outside the parent of the control directory. - Porcelain functions now take an
envargument, and readGIT_PROTOCOL,GIT_SSH_COMMAND/GIT_SSHwhen called as a library rather than only from the CLI (fixes a regression since 1.2.1 whereporcelain.clone()silently ignored the SSH variables). porcelain.archive()gained aremoteargument.- Recurse into subtrees when merging trees, so non-overlapping changes under a shared directory merge cleanly.
- Clear
core.barewhen setting up a submodule's working tree.
Security and hardening fixes in this release were contributed by Kartik Kenchi (@netliomax25-code).
dulwich-1.2.10
- Fix regression in 1.2.9 where loose objects whose content inflates to
more than 8192 bytes failed to parse with `zlib.error: object header
exceeds maximum size`. (Jelmer VernooΔ³, #2292)
dulwich-1.2.9
Highlights of this release:
Security fixes
- Reject checkout paths whose leading component is a DOS drive-letter prefix on Windows (e.g.
C:), whichos.path.joinwould otherwise treat as absolute and let a crafted tree write outside the work tree. (reported by Luke Baton) - Bound zlib decompression of pack entries and loose objects against decompression-bomb DoS.
read_zlib_chunksnow caps the inflated size at the declareddecomp_len, and loose-object parsing acceptsmax_sizedefaulting to git'score.bigFileThreshold(512 MiB). (reported by Luke Bento) - Reject
OFS_DELTApack entries whosedelta_base_offsetis zero. Such an entry references itself, soPack.resolve_objectwould loop forever growing its delta stack until OOM. (reported by Luke Banto) - Bound
Transfer-Encoding: chunkedrequest bodies indulwich.web: strip chunk extensions, reject negative sizes, enforce per-chunk and per-request size limits, and cap requests that omitContent-Length. - Bound the running length when decoding EWAH bitmaps so a corrupt or malformed
.bitmapindex raisesValueErrorinstead of hanging in an unbounded loop that exhausts memory.
Other changes
- web: Reject smart HTTP
git-upload-pack/git-receive-packPOSTs whoseContent-Typeis not the exactapplication/x-<service>-requestvalue, matchinggit http-backend. dulwich.web: Warn at startup that runningpython3 -m dulwich.webis not intended as a production web server (no authentication, etc.).
See NEWS for the full list.
dulwich-1.2.8
Security
- GHSA-8w8g-wq8h-fq33: Write files through
build_file_from_blobin path-restrictedporcelain.checkout(paths=...)instead of a rawos.open. The old path followed a symlink left at the target, so a crafted repository could write attacker content outside the work tree (e.g. into.git/hooks) oncheckout. - GHSA-5fqc-mrg8-w798: Build the temporary index for
filter-branch --index-filterin memory instead of materializing tree entries into CWD. Persisted entries between commits let a symlink from an ancestor commit redirect a descendant's writes outside the work tree. - Refuse to write a stash entry through an intermediate symlink on
stash.pop. The oldos.path.existscheck followed symlinks, so a crafted stash whose parent path was a symlink already present in the worktree (e.g.link->.git/hooks) let the subsequent write land outside the work tree. - Refuse path-restricted
porcelain.checkout,restoreandreset_filewrites whose leading directory is an existing symlink, so a crafted repository can no longer landsubas a link to.git/hooksand have a write tosub/anythingtraverse it. - Canonicalize file modes to
0o644/0o755beforechmodon checkout and patch apply, matching git. An untrusted tree entry or patch `new file mode` could otherwise set setuid/setgid/sticky or world-writable bits on a materialized file. - Reject non-hex pkt-line length prefixes in the protocol parser.
int(sizestr, 16)accepted a leading-, whose negative length made the following `read(size - 4)` slurp the rest of the stream and caused `PktLineParser` to loop without consuming its buffer. (#2267) - Escape the repository path passed to the remote in the SSH client, so a path containing a single quote can no longer close the quoting and have the remainder interpreted by the remote shell. (#2254)
- Reject an option-like host in
TCPGitClientbefore invoking thecore.gitProxycommand, matching theSubprocessSSHVendorguard, so a URL like `git://-oProxyCommand=...` can no longer be interpreted as a flag by the proxy program. (#2240) - Validate object ids in the object store and refs container. An id containing path separators would previously be joined into a filename by `DiskObjectStore._get_shafile_path` (escaping the objects directory) or stored as a ref value. (#2256)
- Validate the object id in LFS server request handlers before it reaches the store, so a request path containing
..cannot escape the LFS directory. (#2255) - Don't expand config
include/includeIfdirectives when parsing bundle lists served by an untrusted bundle-uri host, matching the handling of `.gitmodules`. (#2243) - Read the signing key from gpg's
--status-fd(VALIDSIG) in `GPGCliSignatureVendor.verify` instead of the human-readable stderr text, which could be spoofed by embedding a matching line in the signed payload. (#2245) - Raise
UntrustedSignaturefromverify_commit/verify_tagwhenkeyidsis set and the object carries no signature, instead of silently accepting it. (#2238) - Fix quadratic backtracking in
_find_scissors_lineso a crafted patch can no longer stallmailinfo/git am --scissors. (#2239) - Collapse consecutive
*wildcards to at most**in.gitattributes,.gitignoreand config glob translation to avoid catastrophic backtracking (ReDoS). (#2237) - Fix quadratic buffering in
web.ChunkReader.read. (#2262) - Skip invalid tree paths (containing
..,.git, etc.) in `diff_working_tree_to_tree` instead of joining them onto the work tree; a working-tree diff against an untrusted commit could otherwise read a file outside the work tree and disclose its contents. (#2261) - Fix quadratic header accumulation in
ShaFile._parse_message. (#2273)
Fixes
- Enumerate the objects to push before the HTTP
git-receive-packrequest body starts streaming. `generate_pack_data` previously ran lazily inside the body generator, after the header pkt-lines were already on the wire, so on large repositories the request stalled mid-body while objects were counted and servers such as GitHub aborted the push with a timeout / broken pipe. (#2248) - Replace a symlink left at the target path with a fresh regular file in
build_file_from_blobinstead of writing through it, matching git on checkout. (#2259) - Raise
GitProtocolErrorcarrying the server's message when the fetch/send-pack tail loop sees a fatal side-band channel (\x03), instead of crashing with `AssertionError: Invalid sideband channel 3` and swallowing the server's error text. - Use
ThreadingHTTPServerand advertise HTTP/1.1 inlfs_serverso urllib3's keep-alive pool doesn't race a torn-down connection intoRemoteDisconnected.
Other
- Support
http.postBuffer. (#2248) - Support pyo3 0.29.
- Deprecate
dulwich.objects.filename_to_hex, which is unused.