Skip to content

Commit 612f76f

Browse files
committed
Check parameters before performing reset
If a promise is passed down to the native C++ layer, v8 will crash. To ensure that this does not happen, a check will be performed in the JavaScript layer to verify that the repository is the same as the repository of the commit object. While logically the commit of one repository instance is the same as a commit of another repository instance (if they point to the same .git folder), programmatically they are not equivalent as a check is done on libgit2's side to ensure that they come from the same thing. As a result, the check on the JavaScript side purely compares the pointers over some other logical piece of information (such as its path or working directory). Signed-off-by: Remy Suen <remy.suen@gmail.com>
1 parent d292ed8 commit 612f76f

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

lib/reset.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ Reset.default = function(repo, target, pathspecs) {
4545
*/
4646
Reset.reset = function(repo, target, resetType, opts) {
4747
opts = normalizeOptions(opts, NodeGit.CheckoutOptions);
48-
48+
if (repo !== target.repo) {
49+
// this is the same that is performed on libgit2's side
50+
// https://github.com/nodegit/libgit2/blob/8d89e409616831b7b30a5ca7b89354957137b65e/src/reset.c#L120-L124
51+
throw new Error("Repository and target commit's repository does not match");
52+
}
4953
return _reset.call(this, repo, target, resetType, opts);
5054
};
5155

test/tests/reset.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,43 @@ describe("Reset", function() {
269269
return Reset.reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
270270
});
271271
});
272+
273+
it("reset fails if parameter is not a Commit object", function() {
274+
var test = this;
275+
var commit = test.repo.getReferenceCommit("master");
276+
try {
277+
Reset.reset(test.repo, commit, Reset.TYPE.HARD);
278+
assert.fail(
279+
"Should not be able to pass a Promise (Commit) into the function"
280+
);
281+
} catch (err) {
282+
// ok
283+
assert.equal(
284+
"Repository and target commit's repository does not match",
285+
err.message
286+
);
287+
}
288+
});
289+
290+
it("reset fails if originating repository is not the same", function() {
291+
var test = this;
292+
var testCommit = null;
293+
return test.repo.getReferenceCommit("master")
294+
.then(function(commit) {
295+
testCommit = commit;
296+
return Repository.open(reposPath);
297+
})
298+
.then(function(repo) {
299+
return Reset.reset(repo, testCommit, Reset.TYPE.HARD);
300+
})
301+
.then(function() {
302+
assert.fail("Different source repository instance should fail");
303+
})
304+
.catch(function(err) {
305+
assert.equal(
306+
"Repository and target commit's repository does not match",
307+
err.message
308+
);
309+
});
310+
});
272311
});

0 commit comments

Comments
 (0)