@@ -9,6 +9,11 @@ public static class ContainerHelpers
9
9
10
10
private static Regex imageNameRegex = new Regex ( "^[a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*$" ) ;
11
11
12
+ /// <summary>
13
+ /// Matches if the string is not lowercase or numeric, or ., _, or -.
14
+ /// </summary>
15
+ private static Regex imageNameCharacters = new Regex ( "[^a-zA-Z0-9._-]" ) ;
16
+
12
17
/// <summary>
13
18
/// Given some "fully qualified" image name (e.g. mcr.microsoft.com/dotnet/runtime), return
14
19
/// a valid UriBuilder. This means appending 'https' if the URI is not absolute, otherwise UriBuilder will throw.
@@ -39,8 +44,8 @@ public static bool IsValidRegistry(string registryName)
39
44
{
40
45
// No scheme prefixed onto the registry
41
46
if ( string . IsNullOrEmpty ( registryName ) ||
42
- ( ! registryName . StartsWith ( "http://" ) &&
43
- ! registryName . StartsWith ( "https://" ) &&
47
+ ( ! registryName . StartsWith ( "http://" ) &&
48
+ ! registryName . StartsWith ( "https://" ) &&
44
49
! registryName . StartsWith ( "docker://" ) ) )
45
50
{
46
51
return false ;
@@ -89,9 +94,9 @@ public static bool IsValidImageTag(string imageTag)
89
94
/// <param name="containerName"></param>
90
95
/// <param name="containerTag"></param>
91
96
/// <returns>True if the parse was successful. When false is returned, all out vars are set to empty strings.</returns>
92
- public static bool TryParseFullyQualifiedContainerName ( string fullyQualifiedContainerName ,
93
- [ NotNullWhen ( true ) ] out string ? containerRegistry ,
94
- [ NotNullWhen ( true ) ] out string ? containerName ,
97
+ public static bool TryParseFullyQualifiedContainerName ( string fullyQualifiedContainerName ,
98
+ [ NotNullWhen ( true ) ] out string ? containerRegistry ,
99
+ [ NotNullWhen ( true ) ] out string ? containerName ,
95
100
[ NotNullWhen ( true ) ] out string ? containerTag )
96
101
{
97
102
Uri ? uri = ContainerImageToUri ( fullyQualifiedContainerName ) ;
@@ -115,4 +120,27 @@ public static bool TryParseFullyQualifiedContainerName(string fullyQualifiedCont
115
120
containerTag = indexOfColon == - 1 ? "" : image . Substring ( indexOfColon + 1 ) ;
116
121
return true ;
117
122
}
123
+
124
+ /// <summary>
125
+ /// Checks if a given container image name adheres to the image name spec. If not, and recoverable, then normalizes invalid characters.
126
+ /// </summary>
127
+ public static bool NormalizeImageName ( string containerImageName , [ NotNullWhen ( false ) ] out string ? normalizedImageName )
128
+ {
129
+ if ( IsValidImageName ( containerImageName ) )
130
+ {
131
+ normalizedImageName = null ;
132
+ return true ;
133
+ }
134
+ else
135
+ {
136
+ if ( Char . IsUpper ( containerImageName , 0 ) )
137
+ {
138
+ containerImageName = Char . ToLowerInvariant ( containerImageName [ 0 ] ) + containerImageName [ 1 ..] ;
139
+ } else if ( ! Char . IsLetterOrDigit ( containerImageName , 0 ) ) {
140
+ throw new ArgumentException ( "The first character of the image name must be a lowercase letter or a digit." ) ;
141
+ }
142
+ normalizedImageName = imageNameCharacters . Replace ( containerImageName , "-" ) ;
143
+ return false ;
144
+ }
145
+ }
118
146
}
0 commit comments