Skip to content

Commit abe9551

Browse files
authored
Merge pull request #259 from gitonomy/dto
Security fixes, and align both drivers with git
2 parents 6c8f58c + c95f405 commit abe9551

75 files changed

Lines changed: 3750 additions & 468 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitattributes‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
/.php-cs-fixer.php export-ignore
99
/benchmark.php export-ignore
1010
/castor.php export-ignore
11-
/phpstan-baseline.neon export-ignore
1211
/phpstan.neon export-ignore
1312
/phpunit.xml.dist export-ignore
1413
/test-git-versions.php export-ignore

‎.github/workflows/tests.yml‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
uses: actions/checkout@v7
2828

2929
- name: Setup PHP
30-
uses: shivammathur/setup-php@v2
30+
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0
3131
with:
3232
php-version: '8.4'
3333

@@ -55,7 +55,7 @@ jobs:
5555
uses: actions/checkout@v7
5656

5757
- name: Setup PHP
58-
uses: shivammathur/setup-php@v2
58+
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0
5959
with:
6060
php-version: '8.4'
6161

@@ -87,7 +87,7 @@ jobs:
8787
uses: actions/checkout@v7
8888

8989
- name: Setup PHP
90-
uses: shivammathur/setup-php@v2
90+
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0
9191
with:
9292
php-version: ${{ matrix.php }}
9393

@@ -137,7 +137,7 @@ jobs:
137137
make -C "git-${{ matrix.git }}" prefix="$HOME/git" CFLAGS='-std=gnu17 -O2' NO_OPENSSL=1 NO_CURL=1 NO_EXPAT=1 NO_GETTEXT=1 NO_PERL=1 NO_PYTHON=1 NO_TCLTK=1 --jobs="$(nproc)" install
138138
139139
- name: Setup PHP
140-
uses: shivammathur/setup-php@v2
140+
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0
141141
with:
142142
php-version: '8.4'
143143

@@ -185,7 +185,7 @@ jobs:
185185
cmake --install libgit2-build
186186
187187
- name: Setup PHP
188-
uses: shivammathur/setup-php@v2
188+
uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0
189189
with:
190190
php-version: ${{ matrix.php }}
191191
extensions: ffi

‎CHANGELOG.md‎

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ deprecated until 3.0.
2020
lines and logs are typed objects; the subject of a message is its first paragraph. See
2121
[UPGRADE-2.0.md](UPGRADE-2.0.md) for every change.
2222
([#253](https://github.com/gitonomy/gitlib/pull/253))
23-
- Require PHP 8.4 or later, Symfony 6.4/7.4/8.1+: most classes are `final` (some `readonly`),
23+
- Return the dates of commits and tags at the UTC offset of their author, committer or tagger,
24+
like `git log` shows them, instead of in UTC: the instant doesn't change, but `format()`
25+
returns their local time.
26+
- Require PHP 8.4 or later, Symfony 7.4/8.1+: most classes are `final` (some `readonly`),
2427
and every method has native types. ([#238](https://github.com/gitonomy/gitlib/pull/238))
2528
- Remove `Gitonomy\Git\Util\StringHelper`, replaced by `symfony/string`, and its configurable
2629
encoding: gitlib reads everything in UTF-8. ([#252](https://github.com/gitonomy/gitlib/pull/252))
@@ -30,16 +33,31 @@ deprecated until 3.0.
3033
- `Diff::parse()` throws for a diff without its raw information, deprecated since 1.6.0
3134
([#229](https://github.com/gitonomy/gitlib/pull/229)): parse the output of
3235
`git diff --raw --patch`. ([#253](https://github.com/gitonomy/gitlib/pull/253))
36+
- The constructors of `Commit`, `Tree`, `Blob`, `Revision`, the references and `ReferenceBag`
37+
are internal: get these objects from `Repository`, which returns the same commit, tree or
38+
blob while the application uses it, and reads the references again after its writes.
39+
Extending `Revision` or `Reference` isn't supported anymore.
40+
- `ProcessException` has a message of one line, with the error of git, the first line of its
41+
error output starting with `fatal:` or `error:`, after the warnings:
42+
`The git command "clone" failed (exit 128): fatal: ...`. The command line, the rest of the
43+
error output and the output are no longer in the message: `getErrorOutput()` and
44+
`getOutput()` return the outputs of git.
45+
- When git can't start, a missing binary for instance, `CliDriver` throws a `DriverException`
46+
instead of a `ProcessException`, with a message of one line, without the command line:
47+
`The git command "clone" could not start: ...`.
48+
- `WorkingCopy::checkout()` throws a `ReferenceNotFoundException` for a name that no revision has,
49+
with both drivers: the name of a remote branch alone, like `feature` for `origin/feature`,
50+
created the local branch. Use `checkoutNewBranch()`.
3351

3452
### Features
3553

3654
- Add an experimental `Driver\Ffi\LibGit2Driver`, running libgit2 1.9 in-process through PHP's
3755
FFI extension, as an alternative to the default `Driver\Cli\CliDriver`: pass it as the driver of
3856
`Repository`. It avoids spawning a `git` process for every operation; see
3957
["Choosing a driver"](doc/repository.md#choosing-a-driver) for its requirements, its
40-
differences with `CliDriver`, and when it is faster. `benchmark.php` compares both drivers
41-
on a repository. With php-fpm, `LibGit2Driver::preload()` keeps libgit2 loaded from
42-
`opcache.preload`. ([#253](https://github.com/gitonomy/gitlib/pull/253))
58+
differences with `CliDriver`, and when it is faster. `benchmark.php`, from a clone of gitlib,
59+
compares both drivers on a repository. With php-fpm, `LibGit2Driver::preload()` keeps libgit2
60+
loaded from `opcache.preload`. ([#253](https://github.com/gitonomy/gitlib/pull/253))
4361
- `Repository` takes the working directory and the driver as arguments: a `Driver\Cli\CliDriver`
4462
by default, configured through its constructor (git binary, environment, timeout and logger,
4563
which gets every command, clones included), or any `Driver\DriverInterface`, to replace it in
@@ -52,7 +70,8 @@ deprecated until 3.0.
5270
`isValidRepository()` and `isValidRepositoryAndBranch()`; see
5371
["Create and access git repositories"](doc/admin.md).
5472
([#253](https://github.com/gitonomy/gitlib/pull/253))
55-
- Add `Repository::getDiff($from, $to)`, `Repository::getMergeBase()` and `WorkingCopy::getDiff()`,
73+
- Add `Repository::getDiff($from, $to)`, `Repository::getMergeBase()`,
74+
`Repository::getSizeInBytes()` and `WorkingCopy::getDiff()`,
5675
`WorkingCopy::checkoutNewBranch()`, `Branch::moveTo()` and `Branch::isMergedInto()`,
5776
`Log::withOffset()` and `withLimit()`, `Blame::getHunks()` and the line numbers of
5877
`Blame\Line`, `TreeEntry` and `Submodule`, `Diff\DiffLine` and `Diff\DiffLineType`,
@@ -99,9 +118,52 @@ All are removed in 3.0; see [UPGRADE-2.0.md](UPGRADE-2.0.md).
99118
`WorkingCopy::merge()`.
100119
- `Commit::getShortMessage()` and `getFixedShortHash()`, `Repository::shell()`,
101120
`PushReference::getReference()` and `getRevision()`.
121+
- `Repository::getSize()`, in kilobytes: use `getSizeInBytes()`.
122+
- `Exception\UnexpectedValueException`, which gitlib no longer throws.
123+
124+
### Security
125+
126+
- Refuse a revision, a reference, a hash or a URL starting with a dash, which git read as an
127+
option: `getRevision('--output=/path')`, `WorkingCopy::checkout()` or `merge()` could write
128+
a file, and `Repository::isValidRepository('--upload-pack=...')` run a command. A path may
129+
start with a dash: `init()` and the clones end the options of git with `--`.
130+
- Refuse an `ext::` URL, like `ext::sh -c ...`, whose command git runs, by default before git
131+
2.12.
132+
- Refuse an ssh URL whose host or user starts with a dash, even encoded (`%2D`), like
133+
`ssh://-oProxyCommand=.../repository`: git before 2.14.1 passes it to ssh, which reads it as an
134+
option and runs the command (CVE-2017-1000117). A `git://` URL whose host starts with a dash
135+
is refused too: git passes it to the command of `core.gitProxy`.
136+
- Hide the credentials of URLs (`https://user:token@host`), a password holding a `#` or a `?`
137+
included, in the messages of exceptions, in their traces (`#[\SensitiveParameter]`), and in
138+
the logs. The exceptions of Symfony Process, which hold the command line, no longer leak, not
139+
even as the previous exception.
140+
- Refuse a hook name that isn't the one of a file of the hooks directory:
141+
`Hooks::set('../config', ...)` and `remove('../config')` wrote and deleted the
142+
configuration of the repository.
143+
- Fix `Hooks` writing through a symbolic link to a missing file, out of the hooks directory:
144+
`has()` returned `false` for it, and `set()` followed it.
145+
- Ignore the replacements of objects (`git replace`, `refs/replace/`) with `CliDriver`, like
146+
`LibGit2Driver`: whoever could push such a reference to a repository changed the message of a
147+
commit, or the content of a blob, gitlib read for a hash.
148+
- Fix `WorkingCopy::checkout()` of a path, like `checkout('README.md')`, discarding the changes
149+
of the file: a path is no revision, and throws a `ReferenceNotFoundException`.
150+
- Fix moving or deleting a symbolic reference, which changed the branch it points to instead:
151+
`ReferenceBag::delete('refs/remotes/origin/HEAD')` deleted `origin/main`.
152+
- Fix `ReferenceBag::delete('HEAD')` deleting `HEAD`, which left no repository: a name outside
153+
`refs/` throws an `InvalidArgumentException`.
102154

103155
### Bug fixes
104156

157+
- Fix the configuration of the user changing what `CliDriver` reads: `color.ui=always`,
158+
`log.showSignature`, `diff.noprefix`, `diff.external`, `diff.submodule`, textconv filters,
159+
`column.ui`... made reads throw or return wrong data, and `diff.algorithm`, `diff.context`,
160+
`diff.orderFile`, `log.follow` or `branch.sort` changed diffs, logs and the branches of a
161+
commit. gitlib sets them back to git's defaults; see
162+
["Git configuration"](doc/repository.md#git-configuration).
163+
- Fix `Commit::getShortHash()`, `Commit::getDiff()` and `Repository::getDiff()` failing when a
164+
file of the working tree has the name of the revision they read, which git found ambiguous.
165+
- Fix logs of thousands of revisions exceeding the limit of the command line: `CliDriver` passes
166+
them to git on its standard input.
105167
- Fix `Commit::getDiff()` returning an empty diff for a root commit, and throwing for a merge
106168
commit (`CliDriver`). ([#253](https://github.com/gitonomy/gitlib/pull/253))
107169
- Fix `Repository::getDiff()`, `WorkingCopy::getDiffPending()` and `WorkingCopy::getDiffStaged()`
@@ -132,6 +194,9 @@ All are removed in 3.0; see [UPGRADE-2.0.md](UPGRADE-2.0.md).
132194
- Fix blame lines numbered from 1 for a range of lines. ([#253](https://github.com/gitonomy/gitlib/pull/253))
133195
- Fix `Hooks` failing silently, in a repository without hooks directory, and writing the hooks
134196
of a linked worktree where git doesn't run them. ([#253](https://github.com/gitonomy/gitlib/pull/253))
197+
- Fix `Repository::getSize()` throwing for a link to a missing file in the git directory, like
198+
a hook not deployed yet: it no longer follows links. A file git deletes meanwhile, like a lock
199+
during a `gc` or a push, no longer makes it throw either.
135200
- Fix blame lines starting with a TAB character (`Blame\Line::getContent()`): code removing it
136201
must stop doing so. ([#253](https://github.com/gitonomy/gitlib/pull/253))
137202
- Fix reading a commit whose `encoding` header isn't UTF-8, which threw: its message, author and
@@ -166,8 +231,13 @@ All are removed in 3.0; see [UPGRADE-2.0.md](UPGRADE-2.0.md).
166231
### Minor
167232

168233
- CI tests git 1.8.4 and 2.25.1, analyses the tests and the libgit2 driver with PHPStan,
169-
checks the archive Composer installs, and the suite deletes what it creates, in any order.
234+
without baseline, checks the archive Composer installs, pins the third-party actions by
235+
commit, and the suite deletes what it creates, in any order.
170236
([#253](https://github.com/gitonomy/gitlib/pull/253))
237+
- The tests run with a git configuration of their own, whatever the developer's
238+
(`tests/fixtures/home`), which sets what gitlib sets back to git's defaults, and without the
239+
variables of git of their environment: run from a hook, they wrote the repository of the hook
240+
(`GIT_DIR`, `GIT_INDEX_FILE`...).
171241
- Add a regression test for reading a blob's content in a tree that also contains a
172242
submodule. ([#243](https://github.com/gitonomy/gitlib/pull/243))
173243
- Replace the network-dependent test fixture (cloned from GitHub on every run) with a local,

0 commit comments

Comments
 (0)