Validate container name
continuous-integration/drone/push Build is passing Details

master
Clément FRÉVILLE 2 years ago
parent fa62c57585
commit e0ea7ef8fb

@ -52,4 +52,20 @@ pub fn build(b: *std.Build) void {
// This will evaluate the `run` step rather than the default, which is "install".
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
// Creates a step for unit testing. This only builds the test executable
// but does not run it.
const unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);
// Similar to creating the run step earlier, this exposes a `test` step to
// the `zig build --help` menu, providing a way for the user to request
// running the unit tests.
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}

@ -1,16 +1,12 @@
const std = @import("std");
const validate = @import("validate.zig");
const allocator = std.heap.page_allocator;
var client: std.http.Client = .{ .allocator = allocator };
const Command = enum { list, logs, create, delete, start };
const ForwardedUser = "X-Forwarded-User";
const PluginError = error{
InvalidUser,
InvalidCommand,
NoContainerName,
InvalidImage,
};
const PluginError = error{ InvalidUser, InvalidCommand, NoContainerName, InvalidImage, Unprocessable };
const CodefirstAuth = struct {
proxyScheme: []const u8,
@ -104,7 +100,25 @@ pub fn run() !void {
.proxyHost = std.os.getenv("PROXYHOST") orelse "dockerproxy:8080",
.user = std.os.getenv("DRONE_REPO_OWNER") orelse return PluginError.InvalidUser,
};
const containerName = std.os.getenv("PLUGIN_CONTAINER") orelse return PluginError.NoContainerName;
var containerNameEnv = std.os.getenv("PLUGIN_CONTAINER") orelse return PluginError.NoContainerName;
var shortUser = try std.mem.replaceOwned(u8, allocator, auth.user, ".", "");
defer allocator.free(shortUser);
var containerName = try std.fmt.allocPrint(allocator, "{s}-{s}", .{ shortUser, containerNameEnv });
defer allocator.free(containerName);
var idx: usize = 0;
validate.validateDockerContainerName(containerName, &idx) catch |err| {
switch (err) {
validate.NamingError.IllegalChar => {
std.log.err("Invalid container name at index {}: {}", .{ idx, err });
},
else => {
std.log.err("Invalid container name: {}", .{err});
return PluginError.Unprocessable;
},
}
return PluginError.Unprocessable;
};
var envs = std.ArrayList([]const u8).init(allocator);
defer envs.deinit();

@ -0,0 +1,37 @@
const std = @import("std");
const ascii = std.ascii;
pub const NamingError = error{ Empty, IllegalChar, TooLong };
pub fn validateDockerContainerName(name: []const u8, error_index: *usize) !void {
// [a-zA-Z0-9][a-zA-Z0-9_.-]
if (name.len == 0) {
return NamingError.Empty;
}
if (name.len > 30) {
return NamingError.TooLong;
}
if (!ascii.isAlphanumeric(name[0])) {
error_index.* = 0;
return NamingError.IllegalChar;
}
for (name, 0..) |c, idx| {
if (!ascii.isAlphanumeric(c) and c != '.' and c != '_' and c != '-') {
error_index.* = idx;
return NamingError.IllegalChar;
}
}
}
test "valid name" {
var error_index: usize = 0;
try validateDockerContainerName("hello", &error_index);
try std.testing.expect(error_index == 0);
}
test "indicate non ascii letter" {
var error_index: usize = 0;
try std.testing.expectError(NamingError.IllegalChar, validateDockerContainerName("hello😀", &error_index));
try std.testing.expect(error_index == 5);
}
Loading…
Cancel
Save