public void EncodingFullyCapitalizedStringOfMaxLengthShouldNotExceedMaxLinuxFileNameLength() { var fullyCapitalizedTag = new string('A', OciArtifactModuleReference.MaxTagLength); var encoded = TagEncoder.Encode(fullyCapitalizedTag); encoded.Length.Should().BeLessOrEqualTo(255); encoded.Should().EndWith("$ffffffffffffffffffffffffffffffff"); }
protected override string GetModuleDirectoryPath(OciArtifactModuleReference reference) { // cachePath is already set to %userprofile%\.bicep\br or ~/.bicep/br by default depending on OS // we need to split each component of the reference into a sub directory to fit within the max file name length limit on linux and mac // TODO: Need to deal with IDNs (internationalized domain names) // domain names can only contain alphanumeric chars, _, -, and numbers (example.azurecr.io or example.azurecr.io:443) // IPV4 addresses only contain dots and numbers (127.0.0.1 or 127.0.0.1:5000) // IPV6 addresses are hex digits with colons (2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF or [2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF]:5000) // the only problematic character is the colon, which we will replace with $ which is not allowed in any of the possible registry values // we will also normalize casing for registries since they are case-insensitive var registry = reference.Registry.Replace(':', '$').ToLowerInvariant(); // modules can have mixed hierarchy depths so we will flatten a repository into a single directory name // however to do this we must get rid of slashes (not a valid file system char on windows and a directory separator on linux/mac) // the replacement char must one that is not valid in a repository string but is valid in common type systems var repository = reference.Repository.Replace('/', '$'); string?tagOrDigest; if (reference.Tag is not null) { // tags are case-sensitive with length up to 128 tagOrDigest = TagEncoder.Encode(reference.Tag); } else if (reference.Digest is not null) { // digests are strings like "sha256:e207a69d02b3de40d48ede9fd208d80441a9e590a83a0bc915d46244c03310d4" // and are already guaranteed to be lowercase // the only problematic character is the : which we will replace with a # // however the encoding we choose must not be ambiguous with the tag encoding tagOrDigest = reference.Digest.Replace(':', '#'); } else { throw new InvalidOperationException("Module reference is missing both tag and digest."); } //var packageDir = WebUtility.UrlEncode(reference.UnqualifiedReference); return(Path.Combine(this.cachePath, registry, repository, tagOrDigest)); }
private string GetModuleDirectoryPath(OciArtifactModuleReference reference) { // cachePath is already set to %userprofile%\.bicep\br or ~/.bicep/br by default depending on OS // we need to split each component of the reference into a sub directory to fit within the max file name length limit on linux and mac // TODO: Need to deal with IDNs (internationalized domain names) // domain names can only contain alphanumeric chars, _, -, and numbers (example.azurecr.io or example.azurecr.io:443) // IPV4 addresses only contain dots and numbers (127.0.0.1 or 127.0.0.1:5000) // IPV6 addresses are hex digits with colons (2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF or [2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF]:5000) // the only problematic character is the colon, which we will replace with $ which is not allowed in any of the possible registry values // we will also normalize casing for registries since they are case-insensitive var registry = reference.Registry.Replace(':', '$').ToLowerInvariant(); // modules can have mixed hierarchy depths so we will flatten a repository into a single directory name // however to do this we must get rid of slashes (not a valid file system char on windows and a directory separator on linux/mac) // the replacement char must one that is not valid in a repository string but is valid in common type systems var repository = reference.Repository.Replace('/', '$'); // tags are case-sensitive with length up to 128 var tag = TagEncoder.Encode(reference.Tag); //var packageDir = WebUtility.UrlEncode(reference.UnqualifiedReference); return(Path.Combine(this.cachePath, registry, repository, tag)); }
public void EncoderShouldThrowWhenMaxTagLengthIsExceeded() => FluentActions .Invoking(() => TagEncoder.Encode(OciArtifactModuleReferenceTests.ExampleTagOfMaxLength + 'A')) .Should() .Throw <ArgumentException>() .WithMessage("The specified tag '*' exceeds max length of 128.");
public void EncoderShouldProduceExpectedOutut(string tag, string expected) => TagEncoder.Encode(tag).Should().Be(expected);