int oci_registry_is_valid(const char *n) {
int r;
- if (!n)
+ if (isempty(n))
return false;
const char *colon = strchr(n, ':');
if (!colon)
return dns_name_is_valid(n);
+ if (colon == n) /* empty host, e.g. ":5000" */
+ return false;
+
_cleanup_free_ char *s = strndup(n, colon - n);
if (!s)
return -ENOMEM;
return r;
uint16_t port;
- return safe_atou16(s, &port) >= 0 && port != 0;
+ return safe_atou16_full(colon + 1,
+ 10 | SAFE_ATO_REFUSE_LEADING_WHITESPACE |
+ SAFE_ATO_REFUSE_PLUS_MINUS | SAFE_ATO_REFUSE_LEADING_ZERO,
+ &port) >= 0 && port != 0;
}
bool oci_tag_is_valid(const char *n) {
test_urlescape_one("müffel", "m%c3%bcffel");
}
+TEST(oci_registry_is_valid) {
+ /* plain hostname — valid */
+ assert_se(oci_registry_is_valid("localhost") > 0);
+ assert_se(oci_registry_is_valid("registry.example.com") > 0);
+
+ /* host:port — valid */
+ assert_se(oci_registry_is_valid("localhost:5000") > 0);
+ assert_se(oci_registry_is_valid("registry.example.com:443") > 0);
+ assert_se(oci_registry_is_valid("registry.io:1") > 0);
+ assert_se(oci_registry_is_valid("registry.io:65535") > 0);
+
+ /* port 0 — invalid */
+ assert_se(oci_registry_is_valid("localhost:0") == 0);
+
+ /* port overflow */
+ assert_se(oci_registry_is_valid("localhost:65536") == 0);
+
+ /* non-decimal port forms — rejected */
+ assert_se(oci_registry_is_valid("localhost:0x50") == 0); /* hex */
+ assert_se(oci_registry_is_valid("localhost:017") == 0); /* leading zero */
+ assert_se(oci_registry_is_valid("localhost:+80") == 0); /* plus sign */
+ assert_se(oci_registry_is_valid("localhost: 80") == 0); /* leading space */
+
+ /* invalid hostname */
+ assert_se(oci_registry_is_valid(":5000") == 0);
+ assert_se(oci_registry_is_valid("") == 0);
+ assert_se(oci_registry_is_valid(NULL) == 0);
+}
+
DEFINE_TEST_MAIN(LOG_DEBUG);