lib/core: Add ostree_validate_remote_name() for remote names
authorPhilip Withnall <withnall@endlessm.com>
Wed, 14 Jun 2017 11:28:52 +0000 (12:28 +0100)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 20 Jun 2017 21:52:22 +0000 (21:52 +0000)
There are a few places in the code where ad-hoc validation was being
performed. Might as well formalise it a bit more.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #948
Approved by: cgwalters

apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-core.c
src/libostree/ostree-core.h
src/libostree/ostree-repo.c
tests/test-basic-c.c

index 116c50e83dcda6ff2fbd09caf25caf4556b96cad..47f351d226b27733f533314abc9e2f0d8c113507 100644 (file)
@@ -118,6 +118,7 @@ ostree_checksum_b64_inplace_from_bytes
 ostree_checksum_b64_inplace_to_bytes
 ostree_cmp_checksum_bytes
 ostree_validate_rev
+ostree_validate_remote_name
 ostree_parse_refspec
 ostree_object_type_to_string
 ostree_object_type_from_string
index a9c3f61026bda9c2eaac61cdaacbf19849ce05cf..d2bc83991b7607a0234c67216bca0f1712a59c58 100644 (file)
@@ -19,7 +19,9 @@
 
 /* Add new symbols here.  Release commits should copy this section into -released.sym. */
 LIBOSTREE_2017.8 {
-};
+global:
+  ostree_validate_remote_name;
+} LIBOSTREE_2017.7;
 
 /* Stub section for the stable release *after* this development one; don't
  * edit this other than to update the last number.  This is just a copy/paste
index 54e01bcb63f236513294a1e4b13c9a015e6c9a1b..3eb35c3f10de9f21f9ca6eccfe7f4ff4ceefce82 100644 (file)
@@ -101,6 +101,7 @@ ostree_validate_checksum_string (const char *sha256,
 
 #define OSTREE_REF_FRAGMENT_REGEXP "[-._\\w\\d]+"
 #define OSTREE_REF_REGEXP "(?:" OSTREE_REF_FRAGMENT_REGEXP "/)*" OSTREE_REF_FRAGMENT_REGEXP
+#define OSTREE_REMOTE_NAME_REGEXP OSTREE_REF_FRAGMENT_REGEXP
 
 /**
  * ostree_parse_refspec:
@@ -125,7 +126,7 @@ ostree_parse_refspec (const char   *refspec,
   static gsize regex_initialized;
   if (g_once_init_enter (&regex_initialized))
     {
-      regex = g_regex_new ("^(" OSTREE_REF_FRAGMENT_REGEXP ":)?(" OSTREE_REF_REGEXP ")$", 0, 0, NULL);
+      regex = g_regex_new ("^(" OSTREE_REMOTE_NAME_REGEXP ":)?(" OSTREE_REF_REGEXP ")$", 0, 0, NULL);
       g_assert (regex);
       g_once_init_leave (&regex_initialized, 1);
     }
@@ -180,6 +181,35 @@ ostree_validate_rev (const char *rev,
   return TRUE;
 }
 
+/**
+ * ostree_validate_remote_name:
+ * @remote_name: A remote name
+ * @error: Error
+ *
+ * Returns: %TRUE if @remote_name is a valid remote name
+ * Since: 2017.7
+ */
+gboolean
+ostree_validate_remote_name (const char  *remote_name,
+                             GError     **error)
+{
+  g_autoptr(GMatchInfo) match = NULL;
+
+  static gsize regex_initialized;
+  static GRegex *regex;
+  if (g_once_init_enter (&regex_initialized))
+    {
+      regex = g_regex_new ("^" OSTREE_REMOTE_NAME_REGEXP "$", 0, 0, NULL);
+      g_assert (regex);
+      g_once_init_leave (&regex_initialized, 1);
+    }
+
+  if (!g_regex_match (regex, remote_name, 0, &match))
+    return glnx_throw (error, "Invalid remote name %s", remote_name);
+
+  return TRUE;
+}
+
 GVariant *
 _ostree_file_header_new (GFileInfo         *file_info,
                          GVariant          *xattrs)
index c1e014e2678c1416cef2218d46beb728c7c72a64..dc64d89b2486f4cf65321849ef1d40ac564da386 100644 (file)
@@ -242,6 +242,9 @@ int ostree_cmp_checksum_bytes (const guchar *a, const guchar *b);
 _OSTREE_PUBLIC
 gboolean ostree_validate_rev (const char *rev, GError **error);
 
+_OSTREE_PUBLIC
+gboolean ostree_validate_remote_name (const char *remote_name, GError **error);
+
 _OSTREE_PUBLIC
 gboolean ostree_parse_refspec (const char *refspec,
                                char      **out_remote,
index e556e4646b0c034c2fc7ad20101869a53007e0bd..6bcc8e0d723d6f9b39ef8298527682dbe6246ed4 100644 (file)
@@ -876,8 +876,8 @@ impl_repo_remote_add (OstreeRepo     *self,
   g_return_val_if_fail (url != NULL, FALSE);
   g_return_val_if_fail (options == NULL || g_variant_is_of_type (options, G_VARIANT_TYPE ("a{sv}")), FALSE);
 
-  if (strchr (name, '/') != NULL)
-    return glnx_throw (error, "Invalid character '/' in remote name: %s", name);
+  if (!ostree_validate_remote_name (name, error))
+    return FALSE;
 
   g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, NULL);
   if (remote != NULL && if_not_exists)
@@ -1005,8 +1005,8 @@ impl_repo_remote_delete (OstreeRepo     *self,
 {
   g_return_val_if_fail (name != NULL, FALSE);
 
-  if (strchr (name, '/') != NULL)
-    return glnx_throw (error, "Invalid character '/' in remote name: %s", name);
+  if (!ostree_validate_remote_name (name, error))
+    return FALSE;
 
   g_autoptr(OstreeRemote) remote = NULL;
   if (if_exists)
index dbab087eda9dc82fdcf033476c75cb449a8341a9..dc6d33f27e4b34c80dbbebba21e2f6643d85a421 100644 (file)
@@ -185,6 +185,25 @@ static gboolean hi_content_stream_new (GInputStream **out_stream,
   return ostree_raw_file_to_content_stream ((GInputStream*)hi_memstream, finfo, NULL, out_stream, out_length, NULL, error);
 }
 
+static void
+test_validate_remotename (void)
+{
+  const char *valid[] = {"foo", "hello-world"};
+  const char *invalid[] = {"foo/bar", ""};
+  for (guint i = 0; i < G_N_ELEMENTS(valid); i++)
+    {
+      g_autoptr(GError) error = NULL;
+      g_assert (ostree_validate_remote_name (valid[i], &error));
+      g_assert_no_error (error);
+    }
+  for (guint i = 0; i < G_N_ELEMENTS(invalid); i++)
+    {
+      g_autoptr(GError) error = NULL;
+      g_assert (!ostree_validate_remote_name (invalid[i], &error));
+      g_assert (error != NULL);
+    }
+}
+
 static void
 test_object_writes (gconstpointer data)
 {
@@ -232,6 +251,7 @@ int main (int argc, char **argv)
   g_test_add_data_func ("/repo-not-system", repo, test_repo_is_not_system);
   g_test_add_data_func ("/raw-file-to-archive-z2-stream", repo, test_raw_file_to_archive_z2_stream);
   g_test_add_data_func ("/objectwrites", repo, test_object_writes);
+  g_test_add_func ("/remotename", test_validate_remotename);
 
   return g_test_run();
  out: