add repoName check

main
cyhhao 2 years ago
parent b0ff3488c2
commit 9e079c8818

@ -46,8 +46,26 @@ contract Git3 is LargeStorageManager {
return _get(keccak256(bytes.concat(repoName, "/", path))); return _get(keccak256(bytes.concat(repoName, "/", path)));
} }
function createRepo(bytes memory repoName) external{ function createRepo(bytes memory repoName) external {
require(repoNameToOwner[repoName] == address(0),"RepoName already exist"); require(
repoName.length > 0 && repoName.length <= 100,
"RepoName length must be 1-100"
);
for (uint i; i < repoName.length; i++) {
bytes1 char = repoName[i];
require(
(char >= 0x61 && char <= 0x7A) || //a-z
(char >= 0x41 && char <= 0x5A) || //A-Z
(char >= 0x30 && char <= 0x39) || //0-9
(char == 0x2D || char == 0x2E || char == 0x5F), //-._
"RepoName must be alphanumeric or -._"
);
}
require(
repoNameToOwner[repoName] == address(0),
"RepoName already exist"
);
repoNameToOwner[repoName] = msg.sender; repoNameToOwner[repoName] = msg.sender;
} }
@ -55,7 +73,7 @@ contract Git3 is LargeStorageManager {
bytes memory repoName, bytes memory repoName,
bytes memory path, bytes memory path,
bytes calldata data bytes calldata data
) external payable onlyOwner(repoName){ ) external payable onlyOwner(repoName) {
_putChunkFromCalldata( _putChunkFromCalldata(
keccak256(bytes.concat(repoName, "/", path)), keccak256(bytes.concat(repoName, "/", path)),
0, 0,
@ -69,7 +87,7 @@ contract Git3 is LargeStorageManager {
bytes memory path, bytes memory path,
uint256 chunkId, uint256 chunkId,
bytes calldata data bytes calldata data
) external payable onlyOwner(repoName){ ) external payable onlyOwner(repoName) {
_putChunkFromCalldata( _putChunkFromCalldata(
keccak256(bytes.concat(repoName, "/", path)), keccak256(bytes.concat(repoName, "/", path)),
chunkId, chunkId,
@ -100,10 +118,15 @@ contract Git3 is LargeStorageManager {
return _countChunks(keccak256(bytes.concat(repoName, "/", name))); return _countChunks(keccak256(bytes.concat(repoName, "/", name)));
} }
function listRefs(bytes memory repoName) public view returns (refData[] memory list) { function listRefs(
bytes memory repoName
) public view returns (refData[] memory list) {
list = new refData[](repoNameToRefs[repoName].length); list = new refData[](repoNameToRefs[repoName].length);
for (uint index = 0; index < repoNameToRefs[repoName].length; index++) { for (uint index = 0; index < repoNameToRefs[repoName].length; index++) {
list[index] = _convertRefInfo(repoName,nameToRefInfo[repoNameToRefs[repoName][index]]); list[index] = _convertRefInfo(
repoName,
nameToRefInfo[repoNameToRefs[repoName][index]]
);
} }
} }
@ -111,7 +134,7 @@ contract Git3 is LargeStorageManager {
bytes memory repoName, bytes memory repoName,
bytes memory name, bytes memory name,
bytes20 refHash bytes20 refHash
) public onlyOwner(repoName){ ) public onlyOwner(repoName) {
bytes memory fullName = bytes.concat(repoName, "/", name); bytes memory fullName = bytes.concat(repoName, "/", name);
// only execute `sload` once to reduce gas consumption // only execute `sload` once to reduce gas consumption
refInfo memory srs; refInfo memory srs;
@ -152,8 +175,11 @@ contract Git3 is LargeStorageManager {
require(srs.index < refsLen, "System Error: Invalid index"); require(srs.index < refsLen, "System Error: Invalid index");
if (srs.index < refsLen - 1) { if (srs.index < refsLen - 1) {
repoNameToRefs[repoName][srs.index] = repoNameToRefs[repoName][refsLen - 1]; repoNameToRefs[repoName][srs.index] = repoNameToRefs[repoName][
nameToRefInfo[repoNameToRefs[repoName][refsLen - 1]].index = srs.index; refsLen - 1
];
nameToRefInfo[repoNameToRefs[repoName][refsLen - 1]].index = srs
.index;
} }
repoNameToRefs[repoName].pop(); repoNameToRefs[repoName].pop();
delete nameToRefInfo[fullName]; delete nameToRefInfo[fullName];

@ -13,26 +13,27 @@ describe("Git3 Test", function () {
let singer; let singer;
[singer] = await ethers.getSigners(); [singer] = await ethers.getSigners();
const repoName = Buffer.from("test");
await git3.createRepo("0x11"); await git3.createRepo(repoName);
await git3.upload("0x11", "0x616263", "0x112233"); await git3.upload(repoName, "0x616263", "0x112233");
expect(await git3.download("0x11", "0x616263")).to.eql(["0x112233", true]); expect(await git3.download(repoName, "0x616263")).to.eql(["0x112233", true]);
let data = Array.from({ length: 40 }, () => let data = Array.from({ length: 40 }, () =>
Math.floor(Math.random() * 256) Math.floor(Math.random() * 256)
); );
await git3.upload("0x11", "0x616263", data); await git3.upload(repoName, "0x616263", data);
expect(await git3.download("0x11", "0x616263")).to.eql([ expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data), ethers.utils.hexlify(data),
true, true,
]); ]);
expect(await git3.size("0x11", "0x616263")).to.eql([ToBig(40), ToBig(1)]); expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(40), ToBig(1)]);
await git3.remove("0x11", "0x616263"); await git3.remove(repoName, "0x616263");
expect(await git3.size("0x11", "0x616263")).to.eql([ToBig(0), ToBig(0)]); expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(0), ToBig(0)]);
}); });
it("upload/download/remove chunks", async function () { it("upload/download/remove chunks", async function () {
@ -40,15 +41,16 @@ describe("Git3 Test", function () {
const git3 = await Git3.deploy(); const git3 = await Git3.deploy();
await git3.deployed(); await git3.deployed();
await git3.createRepo("0x11"); const repoName = Buffer.from("test");
await git3.createRepo(repoName);
expect(await git3.countChunks("0x11", "0x616263")).to.eql(ToBig(0)); expect(await git3.countChunks(repoName, "0x616263")).to.eql(ToBig(0));
let data0 = Array.from({ length: 10 }, () => let data0 = Array.from({ length: 10 }, () =>
Math.floor(Math.random() * 256) Math.floor(Math.random() * 256)
); );
await git3.uploadChunk("0x11", "0x616263", 0, data0); await git3.uploadChunk(repoName, "0x616263", 0, data0);
expect(await git3.download("0x11", "0x616263")).to.eql([ expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0), ethers.utils.hexlify(data0),
true, true,
]); ]);
@ -56,16 +58,16 @@ describe("Git3 Test", function () {
let data1 = Array.from({ length: 20 }, () => let data1 = Array.from({ length: 20 }, () =>
Math.floor(Math.random() * 256) Math.floor(Math.random() * 256)
); );
await git3.uploadChunk("0x11", "0x616263", 1, data1); await git3.uploadChunk(repoName, "0x616263", 1, data1);
expect(await git3.download("0x11", "0x616263")).to.eql([ expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0.concat(data1)), ethers.utils.hexlify(data0.concat(data1)),
true, true,
]); ]);
await git3.remove("0x11", "0x616263"); // should succeed await git3.remove(repoName, "0x616263"); // should succeed
expect(await git3.size("0x11", "0x616263")).to.eql([ToBig(0), ToBig(0)]); expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(0), ToBig(0)]);
expect(await git3.download("0x11", "0x616263")).to.eql(["0x", false]); expect(await git3.download(repoName, "0x616263")).to.eql(["0x", false]);
expect(await git3.countChunks("0x11", "0x616263")).to.eql(ToBig(0)); expect(await git3.countChunks(repoName, "0x616263")).to.eql(ToBig(0));
}); });
it("set/update/list/remove Reference", async function () { it("set/update/list/remove Reference", async function () {
@ -73,22 +75,22 @@ describe("Git3 Test", function () {
const git3 = await Git3.deploy(); const git3 = await Git3.deploy();
await git3.deployed(); await git3.deployed();
let repoName = "0x11"; let repoName = Buffer.from("test");
await git3.createRepo(repoName); await git3.createRepo(repoName);
function concatHexStr(s1, s2) { function concatHexStr(s1, s2) {
return s1.concat("2f").concat(s2.slice(2)); return "0x" + Buffer.concat([s1, Buffer.from("/"), s2]).toString("hex");
} }
let key0 = "0x616263"; let key0 = Buffer.from("refs/heads/master");
let data0 = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; let data0 = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
await git3.setRef(repoName, key0, data0); await git3.setRef(repoName, key0, data0);
let key1 = "0x717273"; let key1 = Buffer.from("refs/heads/dev");
let data1 = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; let data1 = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
await git3.setRef(repoName, key1, data1); await git3.setRef(repoName, key1, data1);
let key2 = "0x818283"; let key2 = Buffer.from("refs/heads/main");
let data2 = "0xcccccccccccccccccccccccccccccccccccccccc"; let data2 = "0xcccccccccccccccccccccccccccccccccccccccc";
await git3.setRef(repoName, key2, data2); await git3.setRef(repoName, key2, data2);
@ -124,19 +126,34 @@ describe("Git3 Test", function () {
let singer; let singer;
let user1; let user1;
[singer,user1,] = await ethers.getSigners(); [singer, user1,] = await ethers.getSigners();
const repoName = Buffer.from("test")
await git3.connect(singer).createRepo(repoName);
await git3.connect(singer).createRepo("0x11"); await expect(git3.connect(user1).upload(repoName, "0x616263", "0x112233")).to.be.revertedWith("only owner");
await expect(git3.connect(user1).uploadChunk(repoName, "0x616263", 0, "0x112233")).to.be.revertedWith("only owner");
await expect(git3.connect(user1).setRef(repoName, "0x616263", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")).to.be.revertedWith("only owner");
await expect(git3.connect(user1).upload("0x11", "0x616263", "0x112233")).to.be.revertedWith("only owner"); await git3.connect(singer).upload(repoName, "0x616263", "0x112233")
await expect(git3.connect(user1).uploadChunk("0x11", "0x616263", 0,"0x112233")).to.be.revertedWith("only owner"); expect(await git3.download(repoName, "0x616263")).to.eql(["0x112233", true]);
await expect(git3.connect(user1).setRef("0x11", "0x616263", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")).to.be.revertedWith("only owner"); await git3.connect(singer).setRef(repoName, "0x616263", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
await expect(git3.connect(user1).remove(repoName, "0x616263")).to.be.revertedWith("only owner");
await expect(git3.connect(user1).delRef(repoName, "0x616263")).to.be.revertedWith("only owner");
await git3.connect(singer).upload("0x11", "0x616263", "0x112233")
expect(await git3.download("0x11", "0x616263")).to.eql(["0x112233", true]);
await git3.connect(singer).setRef("0x11", "0x616263", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
await expect(git3.connect(user1).remove("0x11", "0x616263")).to.be.revertedWith("only owner");
await expect(git3.connect(user1).delRef("0x11", "0x616263")).to.be.revertedWith("only owner");
}); });
it("RepoName Check", async function () {
const Git3 = await ethers.getContractFactory("Git3");
const git3 = await Git3.deploy();
await git3.deployed();
let repoName = Buffer.from("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_");
await git3.createRepo(repoName);
await expect(git3.createRepo(repoName)).to.be.revertedWith("RepoName already exist");
await expect(git3.createRepo(Buffer.from("a/b"))).to.be.revertedWith("RepoName must be alphanumeric or -._");
await expect(git3.createRepo(Buffer.from("a".repeat(101)))).to.be.revertedWith("RepoName length must be 1-100");
})
}); });

Loading…
Cancel
Save