isomorphic-git 1.42.0 → 1.42.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +67 -39
- package/index.js +67 -39
- package/index.umd.min.js +1 -1
- package/index.umd.min.js.map +1 -1
- package/managers/index.cjs +50 -12
- package/managers/index.js +50 -12
- package/managers/index.umd.min.js +1 -1
- package/managers/index.umd.min.js.map +1 -1
- package/package.json +1 -1
package/managers/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
|
|
|
7
7
|
var ignore = _interopDefault(require('ignore'));
|
|
8
8
|
var Hash = _interopDefault(require('sha.js/sha1.js'));
|
|
9
9
|
var AsyncLock = _interopDefault(require('async-lock'));
|
|
10
|
+
var cleanGitRef = _interopDefault(require('clean-git-ref'));
|
|
10
11
|
var crc32 = _interopDefault(require('crc-32'));
|
|
11
12
|
var pako = _interopDefault(require('pako'));
|
|
12
13
|
var crypto$1 = require('crypto');
|
|
@@ -1883,6 +1884,22 @@ function compareRefNames(a, b) {
|
|
|
1883
1884
|
return tmp
|
|
1884
1885
|
}
|
|
1885
1886
|
|
|
1887
|
+
/*
|
|
1888
|
+
Adapted from is-git-ref-name-valid
|
|
1889
|
+
SPDX-License-Identifier: MIT
|
|
1890
|
+
Copyright © Vincent Weevers
|
|
1891
|
+
*/
|
|
1892
|
+
|
|
1893
|
+
// eslint-disable-next-line no-control-regex
|
|
1894
|
+
const bad = /(^|[/.])([/.]|$)|^@$|@{|[\x00-\x20\x7f~^:?*[\\]|\.lock(\/|$)/;
|
|
1895
|
+
|
|
1896
|
+
function isValidRef(name, onelevel) {
|
|
1897
|
+
if (typeof name !== 'string')
|
|
1898
|
+
throw new TypeError('Reference name must be a string')
|
|
1899
|
+
|
|
1900
|
+
return !bad.test(name) && (!!onelevel || name.includes('/'))
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1886
1903
|
// @see https://git-scm.com/docs/git-rev-parse.html#_specifying_revisions
|
|
1887
1904
|
const refpaths = ref => [
|
|
1888
1905
|
`${ref}`,
|
|
@@ -1904,6 +1921,13 @@ function assertWritableRef(ref) {
|
|
|
1904
1921
|
if (GIT_FILES.includes(ref)) {
|
|
1905
1922
|
throw new InvalidRefNameError(ref, `refs/heads/${ref}`)
|
|
1906
1923
|
}
|
|
1924
|
+
// A ref name is joined onto gitdir with `join()`, which collapses `..`
|
|
1925
|
+
// exactly like `path.join`. A server-supplied ref/tag name or the wildcard
|
|
1926
|
+
// capture of a refspec can therefore climb out of gitdir, or anywhere
|
|
1927
|
+
// beneath it, entirely unvalidated up to this point. See GHSA-h3c3-jh3g-8hcc.
|
|
1928
|
+
if (!isValidRef(ref, true)) {
|
|
1929
|
+
throw new InvalidRefNameError(ref, cleanGitRef.clean(ref))
|
|
1930
|
+
}
|
|
1907
1931
|
}
|
|
1908
1932
|
|
|
1909
1933
|
/**
|
|
@@ -1963,21 +1987,39 @@ class GitRefManager {
|
|
|
1963
1987
|
])) {
|
|
1964
1988
|
const symtarget = refspec.translateOne(symrefs.get(serverRef));
|
|
1965
1989
|
if (symtarget) {
|
|
1990
|
+
// The destination (translatedRef) is validated below, but the target
|
|
1991
|
+
// a symref points at is server-supplied too (the wire parser accepts
|
|
1992
|
+
// `symref=HEAD:(.*)` unrestricted) and only ever passed through the
|
|
1993
|
+
// refspec's plain string substitution, never checked. Left alone, a
|
|
1994
|
+
// `..`-laden target is written into the file content as-is and later
|
|
1995
|
+
// drives an out-of-gitdir read the next time something resolves it.
|
|
1996
|
+
// See GHSA-h3c3-jh3g-8hcc.
|
|
1997
|
+
assertWritableRef(symtarget);
|
|
1966
1998
|
symrefTranslations.push([translatedRef, `ref: ${symtarget}`]);
|
|
1967
1999
|
}
|
|
1968
2000
|
}
|
|
2001
|
+
// Tags aren't translated by a refspec, but they are still a server-supplied
|
|
2002
|
+
// name written straight to gitdir below, so they need the same check.
|
|
2003
|
+
// Computed here (pure, no I/O) so it can be validated up front and then
|
|
2004
|
+
// reused unchanged in the write step further down.
|
|
2005
|
+
const tagRefsToWrite = tags
|
|
2006
|
+
? [...refs.keys()].filter(
|
|
2007
|
+
serverRef =>
|
|
2008
|
+
serverRef.startsWith('refs/tags') && !serverRef.endsWith('^{}')
|
|
2009
|
+
)
|
|
2010
|
+
: [];
|
|
1969
2011
|
// The local side of a refspec is whatever `remote.<name>.fetch` says, so a
|
|
1970
2012
|
// config like `+refs/heads/main:index` lands a write on `.git/index`.
|
|
1971
2013
|
// Refuse it here rather than at the write loop: `pruneTags` and `prune`
|
|
1972
2014
|
// delete refs in between, so a later throw leaves the repository pruned
|
|
1973
|
-
// and not updated.
|
|
1974
|
-
// is never a system file, so nothing is missed by checking this early.
|
|
2015
|
+
// and not updated.
|
|
1975
2016
|
for (const [, translatedRef] of refTranslations) {
|
|
1976
2017
|
assertWritableRef(translatedRef);
|
|
1977
2018
|
}
|
|
1978
2019
|
for (const [translatedRef] of symrefTranslations) {
|
|
1979
2020
|
assertWritableRef(translatedRef);
|
|
1980
2021
|
}
|
|
2022
|
+
tagRefsToWrite.forEach(assertWritableRef);
|
|
1981
2023
|
// Delete all current tags if the pruneTags argument is true.
|
|
1982
2024
|
if (pruneTags) {
|
|
1983
2025
|
const tags = await GitRefManager.listRefs({
|
|
@@ -1992,16 +2034,12 @@ class GitRefManager {
|
|
|
1992
2034
|
});
|
|
1993
2035
|
}
|
|
1994
2036
|
// Add all tags if the fetch tags argument is true.
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
const oid = refs.get(serverRef);
|
|
2002
|
-
actualRefsToWrite.set(serverRef, oid);
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2037
|
+
for (const serverRef of tagRefsToWrite) {
|
|
2038
|
+
// Git's behavior is to only fetch tags that do not conflict with tags already present.
|
|
2039
|
+
if (!(await GitRefManager.exists({ fs, gitdir, ref: serverRef }))) {
|
|
2040
|
+
// Always use the object id of the tag itself, and not the peeled object id.
|
|
2041
|
+
const oid = refs.get(serverRef);
|
|
2042
|
+
actualRefsToWrite.set(serverRef, oid);
|
|
2005
2043
|
}
|
|
2006
2044
|
}
|
|
2007
2045
|
// Combine refs and symrefs giving symrefs priority
|
package/managers/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ignore from 'ignore';
|
|
2
2
|
import Hash from 'sha.js/sha1.js';
|
|
3
3
|
import AsyncLock from 'async-lock';
|
|
4
|
+
import cleanGitRef from 'clean-git-ref';
|
|
4
5
|
import crc32 from 'crc-32';
|
|
5
6
|
import pako from 'pako';
|
|
6
7
|
|
|
@@ -1876,6 +1877,22 @@ function compareRefNames(a, b) {
|
|
|
1876
1877
|
return tmp
|
|
1877
1878
|
}
|
|
1878
1879
|
|
|
1880
|
+
/*
|
|
1881
|
+
Adapted from is-git-ref-name-valid
|
|
1882
|
+
SPDX-License-Identifier: MIT
|
|
1883
|
+
Copyright © Vincent Weevers
|
|
1884
|
+
*/
|
|
1885
|
+
|
|
1886
|
+
// eslint-disable-next-line no-control-regex
|
|
1887
|
+
const bad = /(^|[/.])([/.]|$)|^@$|@{|[\x00-\x20\x7f~^:?*[\\]|\.lock(\/|$)/;
|
|
1888
|
+
|
|
1889
|
+
function isValidRef(name, onelevel) {
|
|
1890
|
+
if (typeof name !== 'string')
|
|
1891
|
+
throw new TypeError('Reference name must be a string')
|
|
1892
|
+
|
|
1893
|
+
return !bad.test(name) && (!!onelevel || name.includes('/'))
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1879
1896
|
// @see https://git-scm.com/docs/git-rev-parse.html#_specifying_revisions
|
|
1880
1897
|
const refpaths = ref => [
|
|
1881
1898
|
`${ref}`,
|
|
@@ -1897,6 +1914,13 @@ function assertWritableRef(ref) {
|
|
|
1897
1914
|
if (GIT_FILES.includes(ref)) {
|
|
1898
1915
|
throw new InvalidRefNameError(ref, `refs/heads/${ref}`)
|
|
1899
1916
|
}
|
|
1917
|
+
// A ref name is joined onto gitdir with `join()`, which collapses `..`
|
|
1918
|
+
// exactly like `path.join`. A server-supplied ref/tag name or the wildcard
|
|
1919
|
+
// capture of a refspec can therefore climb out of gitdir, or anywhere
|
|
1920
|
+
// beneath it, entirely unvalidated up to this point. See GHSA-h3c3-jh3g-8hcc.
|
|
1921
|
+
if (!isValidRef(ref, true)) {
|
|
1922
|
+
throw new InvalidRefNameError(ref, cleanGitRef.clean(ref))
|
|
1923
|
+
}
|
|
1900
1924
|
}
|
|
1901
1925
|
|
|
1902
1926
|
/**
|
|
@@ -1956,21 +1980,39 @@ class GitRefManager {
|
|
|
1956
1980
|
])) {
|
|
1957
1981
|
const symtarget = refspec.translateOne(symrefs.get(serverRef));
|
|
1958
1982
|
if (symtarget) {
|
|
1983
|
+
// The destination (translatedRef) is validated below, but the target
|
|
1984
|
+
// a symref points at is server-supplied too (the wire parser accepts
|
|
1985
|
+
// `symref=HEAD:(.*)` unrestricted) and only ever passed through the
|
|
1986
|
+
// refspec's plain string substitution, never checked. Left alone, a
|
|
1987
|
+
// `..`-laden target is written into the file content as-is and later
|
|
1988
|
+
// drives an out-of-gitdir read the next time something resolves it.
|
|
1989
|
+
// See GHSA-h3c3-jh3g-8hcc.
|
|
1990
|
+
assertWritableRef(symtarget);
|
|
1959
1991
|
symrefTranslations.push([translatedRef, `ref: ${symtarget}`]);
|
|
1960
1992
|
}
|
|
1961
1993
|
}
|
|
1994
|
+
// Tags aren't translated by a refspec, but they are still a server-supplied
|
|
1995
|
+
// name written straight to gitdir below, so they need the same check.
|
|
1996
|
+
// Computed here (pure, no I/O) so it can be validated up front and then
|
|
1997
|
+
// reused unchanged in the write step further down.
|
|
1998
|
+
const tagRefsToWrite = tags
|
|
1999
|
+
? [...refs.keys()].filter(
|
|
2000
|
+
serverRef =>
|
|
2001
|
+
serverRef.startsWith('refs/tags') && !serverRef.endsWith('^{}')
|
|
2002
|
+
)
|
|
2003
|
+
: [];
|
|
1962
2004
|
// The local side of a refspec is whatever `remote.<name>.fetch` says, so a
|
|
1963
2005
|
// config like `+refs/heads/main:index` lands a write on `.git/index`.
|
|
1964
2006
|
// Refuse it here rather than at the write loop: `pruneTags` and `prune`
|
|
1965
2007
|
// delete refs in between, so a later throw leaves the repository pruned
|
|
1966
|
-
// and not updated.
|
|
1967
|
-
// is never a system file, so nothing is missed by checking this early.
|
|
2008
|
+
// and not updated.
|
|
1968
2009
|
for (const [, translatedRef] of refTranslations) {
|
|
1969
2010
|
assertWritableRef(translatedRef);
|
|
1970
2011
|
}
|
|
1971
2012
|
for (const [translatedRef] of symrefTranslations) {
|
|
1972
2013
|
assertWritableRef(translatedRef);
|
|
1973
2014
|
}
|
|
2015
|
+
tagRefsToWrite.forEach(assertWritableRef);
|
|
1974
2016
|
// Delete all current tags if the pruneTags argument is true.
|
|
1975
2017
|
if (pruneTags) {
|
|
1976
2018
|
const tags = await GitRefManager.listRefs({
|
|
@@ -1985,16 +2027,12 @@ class GitRefManager {
|
|
|
1985
2027
|
});
|
|
1986
2028
|
}
|
|
1987
2029
|
// Add all tags if the fetch tags argument is true.
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
const oid = refs.get(serverRef);
|
|
1995
|
-
actualRefsToWrite.set(serverRef, oid);
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
2030
|
+
for (const serverRef of tagRefsToWrite) {
|
|
2031
|
+
// Git's behavior is to only fetch tags that do not conflict with tags already present.
|
|
2032
|
+
if (!(await GitRefManager.exists({ fs, gitdir, ref: serverRef }))) {
|
|
2033
|
+
// Always use the object id of the tag itself, and not the peeled object id.
|
|
2034
|
+
const oid = refs.get(serverRef);
|
|
2035
|
+
actualRefsToWrite.set(serverRef, oid);
|
|
1998
2036
|
}
|
|
1999
2037
|
}
|
|
2000
2038
|
// Combine refs and symrefs giving symrefs priority
|