utils: Allow passing sizes to more utils

These now take (optional) string length args:
  flatpak_id_has_subref_suffix()
  flatpak_levenshtein_distance()
  flatpak_is_valid_name()
  flatpak_is_valid_branch()
This commit is contained in:
Alexander Larsson 2020-10-28 09:12:25 +01:00 committed by Alexander Larsson
parent f147df908a
commit 7483a98769
18 changed files with 116 additions and 65 deletions

View File

@ -653,10 +653,10 @@ flatpak_builtin_build_bundle (int argc, char **argv, GCancellable *cancellable,
full_branch = g_strdup (name);
else
{
if (!flatpak_is_valid_name (name, &my_error))
if (!flatpak_is_valid_name (name, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid name: %s"), name, my_error->message);
if (!flatpak_is_valid_branch (branch, &my_error))
if (!flatpak_is_valid_branch (branch, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);
if (opt_runtime)

View File

@ -316,10 +316,10 @@ flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancella
*rebase_new = 0;
rebase_new++;
if (!flatpak_is_valid_name (rebase_old, error))
if (!flatpak_is_valid_name (rebase_old, -1, error))
return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_old);
if (!flatpak_is_valid_name (rebase_new, error))
if (!flatpak_is_valid_name (rebase_new, -1, error))
return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_new);
opt_endoflife_rebase_new[i] = rebase_new;

View File

@ -820,7 +820,7 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable,
goto out;
}
if (!flatpak_is_valid_branch (branch, &my_error))
if (!flatpak_is_valid_branch (branch, -1, &my_error))
{
flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);
goto out;
@ -1028,7 +1028,7 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable,
g_auto(GStrv) full_ref_parts = g_strsplit (full_branch, "/", 0);
g_autofree char *rebased_ref = g_build_filename (full_ref_parts[0], opt_endoflife_rebase, full_ref_parts[2], full_ref_parts[3], NULL);
if (!flatpak_is_valid_name (opt_endoflife_rebase, error))
if (!flatpak_is_valid_name (opt_endoflife_rebase, -1, error))
return glnx_prefix_error (error, "Invalid name in --end-of-life-rebase");
g_variant_dict_insert_value (&metadata_dict, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE,

View File

@ -588,7 +588,7 @@ update_metadata (GFile *base, FlatpakContext *arg_context, gboolean is_runtime,
goto out;
}
if (!flatpak_is_valid_name (elements[0], error))
if (!flatpak_is_valid_name (elements[0], -1, error))
{
glnx_prefix_error (error, _("Invalid extension name %s"), elements[0]);
goto out;

View File

@ -232,7 +232,7 @@ flatpak_builtin_build_init (int argc, char **argv, GCancellable *cancellable, GE
else
is_app = TRUE;
if (!flatpak_is_valid_name (app_id, &my_error))
if (!flatpak_is_valid_name (app_id, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid application name: %s"), app_id, my_error->message);
@ -449,7 +449,7 @@ flatpak_builtin_build_init (int argc, char **argv, GCancellable *cancellable, GE
if (g_strv_length (elements) < 2)
return flatpak_fail (error, _("Too few elements in --extension argument %s, format should be NAME=VAR[=VALUE]"), opt_extensions[i]);
if (!flatpak_is_valid_name (elements[0], error))
if (!flatpak_is_valid_name (elements[0], -1, error))
return glnx_prefix_error (error, _("Invalid extension name %s"), elements[0]);
groupname = g_strconcat (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION,

View File

@ -83,10 +83,10 @@ flatpak_builtin_build_sign (int argc, char **argv, GCancellable *cancellable, GE
else
branch = "master";
if (id != NULL && !flatpak_is_valid_name (id, &my_error))
if (id != NULL && !flatpak_is_valid_name (id, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid name: %s"), id, my_error->message);
if (!flatpak_is_valid_branch (branch, &my_error))
if (!flatpak_is_valid_branch (branch, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message);
if (opt_gpg_key_ids == NULL)

View File

@ -459,7 +459,7 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
}
/* Backwards compat for old "REMOTE NAME [BRANCH]" argument version */
if (argc == 4 && flatpak_is_valid_name (argv[2], NULL) && looks_like_branch (argv[3]))
if (argc == 4 && flatpak_is_valid_name (argv[2], -1, NULL) && looks_like_branch (argv[3]))
{
target_branch = g_strdup (argv[3]);
n_prefs = 1;
@ -501,7 +501,7 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
&matched_kinds, &id, &arch, &branch);
/* We used _novalidate so that the id can be partial, but we can still validate the branch */
if (branch != NULL && !flatpak_is_valid_branch (branch, &local_error))
if (branch != NULL && !flatpak_is_valid_branch (branch, -1, &local_error))
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), branch, local_error->message);
if (opt_no_pull)

View File

@ -241,7 +241,7 @@ print_table_for_refs (gboolean print_apps,
}
if (!opt_all && strcmp (parts[0], "runtime") == 0 &&
flatpak_id_has_subref_suffix (parts[1]))
flatpak_id_has_subref_suffix (parts[1], -1))
{
g_autofree char *prefix_partial_ref = NULL;
char *last_dot = strrchr (parts[1], '.');

View File

@ -75,7 +75,7 @@ flatpak_builtin_override (int argc, char **argv, GCancellable *cancellable, GErr
if (argc >= 2)
{
app = argv[1];
if (!flatpak_is_valid_name (app, &my_error))
if (!flatpak_is_valid_name (app, -1, &my_error))
return flatpak_fail (error, _("'%s' is not a valid application name: %s"), app, my_error->message);
}
else

View File

@ -203,7 +203,7 @@ ls_remote (GHashTable *refs_hash, const char **arches, const char *app_runtime,
if (!opt_all &&
strcmp (parts[0], "runtime") == 0 &&
flatpak_id_has_subref_suffix (parts[1]))
flatpak_id_has_subref_suffix (parts[1], -1))
{
g_autofree char *prefix_partial_ref = NULL;
char *last_dot = strrchr (parts[1], '.');

View File

@ -173,7 +173,7 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
n_prefs = argc - 1;
/* Backwards compat for old "NAME [BRANCH]" argument version */
if (argc == 3 && flatpak_is_valid_name (argv[1], NULL) && looks_like_branch (argv[2]))
if (argc == 3 && flatpak_is_valid_name (argv[1], -1, NULL) && looks_like_branch (argv[2]))
{
default_branch = argv[2];
n_prefs = 1;
@ -287,7 +287,7 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
&matched_kinds, &id, &arch, &branch);
/* We used _novalidate so that the id can be partial, but we can still validate the branch */
if (branch != NULL && !flatpak_is_valid_branch (branch, &local_error))
if (branch != NULL && !flatpak_is_valid_branch (branch, -1, &local_error))
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), branch, local_error->message);
ref_dir_pairs = g_ptr_array_new_with_free_func ((GDestroyNotify) ref_dir_pair_free);

View File

@ -76,7 +76,7 @@ looks_like_branch (const char *branch)
/* In particular, / is not a valid branch char, so
this lets us distinguish full or partial refs as
non-branches. */
if (!flatpak_is_valid_branch (branch, NULL))
if (!flatpak_is_valid_branch (branch, -1, NULL))
return FALSE;
/* Dots are allowed in branches, but not really used much, while

View File

@ -231,7 +231,7 @@ flatpak_complete_partial_ref (FlatpakCompletion *completion,
if (!g_str_has_prefix (parts[element], cur_parts[element]))
continue;
if (flatpak_id_has_subref_suffix (parts[element]))
if (flatpak_id_has_subref_suffix (parts[element], -1))
{
char *last_dot = strrchr (parts[element], '.');

View File

@ -550,7 +550,7 @@ find_similar_command (const char *word,
if (!commands[i].fn)
continue;
int d1 = flatpak_levenshtein_distance (word, commands[i].name);
int d1 = flatpak_levenshtein_distance (word, -1, commands[i].name, -1);
if (d1 < d)
{
d = d1;
@ -563,7 +563,7 @@ find_similar_command (const char *word,
{
for (i = 0; entries[k][i].long_name; i++)
{
int d1 = flatpak_levenshtein_distance (word, entries[k][i].long_name);
int d1 = flatpak_levenshtein_distance (word, -1, entries[k][i].long_name, -1);
if (d1 < d)
{
d = d1;

View File

@ -12097,13 +12097,13 @@ find_matching_refs (GHashTable *refs,
arches = opt_arches;
if (opt_name && !(flags & FIND_MATCHING_REFS_FLAGS_FUZZY) &&
!flatpak_is_valid_name (opt_name, &local_error))
!flatpak_is_valid_name (opt_name, -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid name: %s"), opt_name, local_error->message);
return NULL;
}
if (opt_branch && !flatpak_is_valid_branch (opt_branch, &local_error))
if (opt_branch && !flatpak_is_valid_branch (opt_branch, -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid branch name: %s"), opt_branch, local_error->message);
return NULL;
@ -12136,12 +12136,12 @@ find_matching_refs (GHashTable *refs,
if (parts == NULL)
continue;
if ((flags & FIND_MATCHING_REFS_FLAGS_FUZZY) && !flatpak_id_has_subref_suffix (parts[1]))
if ((flags & FIND_MATCHING_REFS_FLAGS_FUZZY) && !flatpak_id_has_subref_suffix (parts[1], -1))
{
/* See if the given name looks similar to this ref name. The
* Levenshtein distance constant was chosen pretty arbitrarily. */
if (opt_name != NULL && strcasestr (parts[1], opt_name) == NULL &&
flatpak_levenshtein_distance (opt_name, parts[1]) > 2)
flatpak_levenshtein_distance (opt_name, -1, parts[1], -1) > 2)
continue;
}
else

View File

@ -199,14 +199,17 @@ gboolean flatpak_get_allowed_exports (const char *source_path,
gboolean *require_exact_match_out);
gboolean flatpak_is_valid_name (const char *string,
gssize len,
GError **error);
gboolean flatpak_is_valid_branch (const char *string,
gssize len,
GError **error);
gboolean flatpak_has_name_prefix (const char *string,
const char *name);
char * flatpak_make_valid_id_prefix (const char *orig_id);
gboolean flatpak_id_has_subref_suffix (const char *id);
gboolean flatpak_id_has_subref_suffix (const char *id,
gssize id_len);
char **flatpak_decompose_ref (const char *ref,
GError **error);
@ -932,7 +935,9 @@ gboolean flatpak_check_required_version (const char *ref,
GError **error);
int flatpak_levenshtein_distance (const char *s,
const char *t);
gssize ls,
const char *t,
gssize lt);
char * flatpak_dconf_path_for_app_id (const char *app_id);
gboolean flatpak_dconf_path_is_similar (const char *path1,

View File

@ -706,9 +706,23 @@ is_valid_name_character (gint c, gboolean allow_dash)
(c >= '0' && c <= '9');
}
static const char *
find_last_char (const char *str, gsize len, int c)
{
const char *p = str + len - 1;
while (p >= str)
{
if (*p == c)
return p;
p--;
}
return NULL;
}
/**
* flatpak_is_valid_name:
* @string: The string to check
* @len: The string length, or -1 for null-terminated
* @error: Return location for an error
*
* Checks if @string is a valid application name.
@ -735,9 +749,9 @@ is_valid_name_character (gint c, gboolean allow_dash)
*/
gboolean
flatpak_is_valid_name (const char *string,
gssize len,
GError **error)
{
guint len;
gboolean ret;
const gchar *s;
const gchar *end;
@ -749,7 +763,8 @@ flatpak_is_valid_name (const char *string,
ret = FALSE;
len = strlen (string);
if (len < 0)
len = strlen (string);
if (G_UNLIKELY (len == 0))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
@ -766,7 +781,7 @@ flatpak_is_valid_name (const char *string,
end = string + len;
last_dot = strrchr (string, '.');
last_dot = find_last_char (string, len, '.');
last_element = FALSE;
s = string;
@ -1004,6 +1019,7 @@ is_valid_branch_character (gint c)
/**
* flatpak_is_valid_branch:
* @string: The string to check
* @len: The string length, or -1 for null-terminated
* @error: return location for an error
*
* Checks if @string is a valid branch name.
@ -1019,9 +1035,9 @@ is_valid_branch_character (gint c)
*/
gboolean
flatpak_is_valid_branch (const char *string,
gssize len,
GError **error)
{
guint len;
gboolean ret;
const gchar *s;
const gchar *end;
@ -1030,7 +1046,8 @@ flatpak_is_valid_branch (const char *string,
ret = FALSE;
len = strlen (string);
if (len < 0)
len = strlen (string);
if (G_UNLIKELY (len == 0))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME,
@ -1086,13 +1103,31 @@ flatpak_make_valid_id_prefix (const char *orig_id)
return id;
}
gboolean
flatpak_id_has_subref_suffix (const char *id)
static gboolean
str_has_suffix (const gchar *str, gsize str_len,
const gchar *suffix)
{
gsize suffix_len;
suffix_len = strlen (suffix);
if (str_len < suffix_len)
return FALSE;
return strcmp (str + str_len - suffix_len, suffix) == 0;
}
gboolean
flatpak_id_has_subref_suffix (const char *id,
gssize id_len)
{
if (id_len < 0)
id_len = strlen (id);
return
g_str_has_suffix (id, ".Locale") ||
g_str_has_suffix (id, ".Debug") ||
g_str_has_suffix (id, ".Sources");
str_has_suffix (id, id_len, ".Locale") ||
str_has_suffix (id, id_len, ".Debug") ||
str_has_suffix (id, id_len, ".Sources");
}
@ -1403,7 +1438,7 @@ flatpak_decompose_ref (const char *full_ref,
return NULL;
}
if (!flatpak_is_valid_name (parts[1], &local_error))
if (!flatpak_is_valid_name (parts[1], -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid name %s: %s"), parts[1], local_error->message);
return NULL;
@ -1415,7 +1450,7 @@ flatpak_decompose_ref (const char *full_ref,
return NULL;
}
if (!flatpak_is_valid_branch (parts[3], &local_error))
if (!flatpak_is_valid_branch (parts[3], -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), parts[3], local_error->message);
return NULL;
@ -1503,7 +1538,7 @@ _flatpak_split_partial_ref_arg (const char *partial_ref,
id_end = next_element (&partial_ref);
id = g_strndup (id_start, id_end - id_start);
if (validate && !flatpak_is_valid_name (id, &local_error))
if (validate && !flatpak_is_valid_name (id, -1, &local_error))
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid id %s: %s"), id, local_error->message);
arch_start = partial_ref;
@ -1520,7 +1555,7 @@ _flatpak_split_partial_ref_arg (const char *partial_ref,
else
branch = g_strdup (default_branch);
if (validate && branch != NULL && !flatpak_is_valid_branch (branch, &local_error))
if (validate && branch != NULL && !flatpak_is_valid_branch (branch, -1, &local_error))
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch %s: %s"), branch, local_error->message);
if (out_kinds)
@ -1590,13 +1625,13 @@ flatpak_compose_ref (gboolean app,
{
g_autoptr(GError) local_error = NULL;
if (!flatpak_is_valid_name (name, &local_error))
if (!flatpak_is_valid_name (name, -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid name: %s"), name, local_error->message);
return NULL;
}
if (branch && !flatpak_is_valid_branch (branch, &local_error))
if (branch && !flatpak_is_valid_branch (branch, -1, &local_error))
{
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("'%s' is not a valid branch name: %s"), branch, local_error->message);
return NULL;
@ -8290,13 +8325,20 @@ dist (const char *s, int ls, const char *t, int lt, int i, int j, int *d)
}
int
flatpak_levenshtein_distance (const char *s, const char *t)
flatpak_levenshtein_distance (const char *s,
gssize ls,
const char *t,
gssize lt)
{
int ls = strlen (s);
int lt = strlen (t);
int i, j;
int *d;
if (ls < 0)
ls = strlen (s);
if (lt < 0)
lt = strlen (t);
d = alloca (sizeof (int) * (ls + 1) * (lt + 1));
for (i = 0; i <= ls; i++)

View File

@ -77,23 +77,27 @@ test_extension_matches (void)
static void
test_valid_name (void)
{
g_assert_false (flatpak_is_valid_name ("", NULL));
g_assert_false (flatpak_is_valid_name ("org", NULL));
g_assert_false (flatpak_is_valid_name ("org.", NULL));
g_assert_false (flatpak_is_valid_name ("org..", NULL));
g_assert_false (flatpak_is_valid_name ("org..test", NULL));
g_assert_false (flatpak_is_valid_name ("org.flatpak", NULL));
g_assert_false (flatpak_is_valid_name ("org.1flatpak.test", NULL));
g_assert_false (flatpak_is_valid_name ("org.flat-pak.test", NULL));
g_assert_false (flatpak_is_valid_name ("org.-flatpak.test", NULL));
g_assert_false (flatpak_is_valid_name ("org.flat,pak.test", NULL));
g_assert_false (flatpak_is_valid_name ("", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org..", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org..test", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.flatpak", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.1flatpak.test", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.flat-pak.test", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.-flatpak.test", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.flat,pak.test", -1, NULL));
g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 0, NULL));
g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 3, NULL));
g_assert_false (flatpak_is_valid_name ("org.flatpak.test", 4, NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak.test", NULL));
g_assert_true (flatpak_is_valid_name ("org.FlatPak.TEST", NULL));
g_assert_true (flatpak_is_valid_name ("org0.f1atpak.test", NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak.-test", NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak._test", NULL));
g_assert_true (flatpak_is_valid_name ("org.flat_pak__.te--st", NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak.test", -1, NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak.test", strlen("org.flatpak.test"), NULL));
g_assert_true (flatpak_is_valid_name ("org.FlatPak.TEST", -1, NULL));
g_assert_true (flatpak_is_valid_name ("org0.f1atpak.test", -1, NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak.-test", -1, NULL));
g_assert_true (flatpak_is_valid_name ("org.flatpak._test", -1, NULL));
g_assert_true (flatpak_is_valid_name ("org.flat_pak__.te--st", -1, NULL));
}
typedef struct
@ -201,8 +205,8 @@ test_levenshtein (void)
{
Levenshtein *data = &levenshtein_tests[idx];
g_assert_cmpint (flatpak_levenshtein_distance (data->a, data->b), ==, data->distance);
g_assert_cmpint (flatpak_levenshtein_distance (data->b, data->a), ==, data->distance);
g_assert_cmpint (flatpak_levenshtein_distance (data->a, -1, data->b, -1), ==, data->distance);
g_assert_cmpint (flatpak_levenshtein_distance (data->b, -1, data->a, -1), ==, data->distance);
}
}