github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/libsnap-confine-private/snap-test.c (about)

     1  /*
     2   * Copyright (C) 2017 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  #include "snap.h"
    19  #include "snap.c"
    20  
    21  #include <glib.h>
    22  
    23  static void test_sc_security_tag_validate(void)
    24  {
    25  	// First, test the names we know are good
    26  	g_assert_true(sc_security_tag_validate("snap.name.app", "name"));
    27  	g_assert_true(sc_security_tag_validate
    28  		      ("snap.network-manager.NetworkManager",
    29  		       "network-manager"));
    30  	g_assert_true(sc_security_tag_validate("snap.f00.bar-baz1", "f00"));
    31  	g_assert_true(sc_security_tag_validate("snap.foo.hook.bar", "foo"));
    32  	g_assert_true(sc_security_tag_validate("snap.foo.hook.bar-baz", "foo"));
    33  	g_assert_true(sc_security_tag_validate
    34  		      ("snap.foo_instance.bar-baz", "foo_instance"));
    35  	g_assert_true(sc_security_tag_validate
    36  		      ("snap.foo_instance.hook.bar-baz", "foo_instance"));
    37  	g_assert_true(sc_security_tag_validate
    38  		      ("snap.foo_bar.hook.bar-baz", "foo_bar"));
    39  
    40  	// Now, test the names we know are bad
    41  	g_assert_false(sc_security_tag_validate
    42  		       ("pkg-foo.bar.0binary-bar+baz", "bar"));
    43  	g_assert_false(sc_security_tag_validate("pkg-foo_bar_1.1", ""));
    44  	g_assert_false(sc_security_tag_validate("appname/..", ""));
    45  	g_assert_false(sc_security_tag_validate("snap", ""));
    46  	g_assert_false(sc_security_tag_validate("snap.", ""));
    47  	g_assert_false(sc_security_tag_validate("snap.name", "name"));
    48  	g_assert_false(sc_security_tag_validate("snap.name.", "name"));
    49  	g_assert_false(sc_security_tag_validate("snap.name.app.", "name"));
    50  	g_assert_false(sc_security_tag_validate("snap.name.hook.", "name"));
    51  	g_assert_false(sc_security_tag_validate("snap!name.app", "!name"));
    52  	g_assert_false(sc_security_tag_validate("snap.-name.app", "-name"));
    53  	g_assert_false(sc_security_tag_validate("snap.name!app", "name!"));
    54  	g_assert_false(sc_security_tag_validate("snap.name.-app", "name"));
    55  	g_assert_false(sc_security_tag_validate("snap.name.app!hook.foo", "name"));
    56  	g_assert_false(sc_security_tag_validate("snap.name.app.hook!foo", "name"));
    57  	g_assert_false(sc_security_tag_validate("snap.name.app.hook.-foo", "name"));
    58  	g_assert_false(sc_security_tag_validate("snap.name.app.hook.f00", "name"));
    59  	g_assert_false(sc_security_tag_validate("sna.pname.app", "pname"));
    60  	g_assert_false(sc_security_tag_validate("snap.n@me.app", "n@me"));
    61  	g_assert_false(sc_security_tag_validate("SNAP.name.app", "name"));
    62  	g_assert_false(sc_security_tag_validate("snap.Name.app", "Name"));
    63  	// This used to be false but it's now allowed.
    64  	g_assert_true(sc_security_tag_validate("snap.0name.app", "0name"));
    65  	g_assert_false(sc_security_tag_validate("snap.-name.app", "-name"));
    66  	g_assert_false(sc_security_tag_validate("snap.name.@app", "name"));
    67  	g_assert_false(sc_security_tag_validate(".name.app", "name"));
    68  	g_assert_false(sc_security_tag_validate("snap..name.app", ".name"));
    69  	g_assert_false(sc_security_tag_validate("snap.name..app", "name."));
    70  	g_assert_false(sc_security_tag_validate("snap.name.app..", "name"));
    71  	// These contain invalid instance key
    72  	g_assert_false(sc_security_tag_validate("snap.foo_.bar-baz", "foo"));
    73  	g_assert_false(sc_security_tag_validate
    74  		       ("snap.foo_toolonginstance.bar-baz", "foo"));
    75  	g_assert_false(sc_security_tag_validate
    76  		       ("snap.foo_inst@nace.bar-baz", "foo"));
    77  	g_assert_false(sc_security_tag_validate
    78  		       ("snap.foo_in-stan-ce.bar-baz", "foo"));
    79  	g_assert_false(sc_security_tag_validate("snap.foo_in stan.bar-baz", "foo"));
    80  
    81  	// Test names that are both good, but snap name doesn't match security tag
    82  	g_assert_false(sc_security_tag_validate("snap.foo.hook.bar", "fo"));
    83  	g_assert_false(sc_security_tag_validate("snap.foo.hook.bar", "fooo"));
    84  	g_assert_false(sc_security_tag_validate("snap.foo.hook.bar", "snap"));
    85  	g_assert_false(sc_security_tag_validate("snap.foo.hook.bar", "bar"));
    86  	g_assert_false(sc_security_tag_validate("snap.foo_instance.bar", "foo_bar"));
    87  
    88  	// Regression test 12to8
    89  	g_assert_true(sc_security_tag_validate("snap.12to8.128to8", "12to8"));
    90  	g_assert_true(sc_security_tag_validate("snap.123test.123test", "123test"));
    91  	g_assert_true(sc_security_tag_validate
    92  		      ("snap.123test.hook.configure", "123test"));
    93  
    94  	// regression test snap.eon-edg-shb-pulseaudio.hook.connect-plug-i2c
    95  	g_assert_true(sc_security_tag_validate
    96  		      ("snap.foo.hook.connect-plug-i2c", "foo"));
    97  
    98  	// Security tag that's too long. The extra +2 is for the string
    99  	// terminator and to allow us to make the tag too long to validate.
   100  	char long_tag[SNAP_SECURITY_TAG_MAX_LEN + 2];
   101  	memset(long_tag, 'b', sizeof long_tag);
   102  	memcpy(long_tag, "snap.foo.b", sizeof "snap.foo.b" - 1);
   103  	long_tag[sizeof long_tag - 1] = '\0';
   104  	g_assert_true(strlen(long_tag) == SNAP_SECURITY_TAG_MAX_LEN + 1);
   105  	g_assert_false(sc_security_tag_validate(long_tag, "foo"));
   106  
   107  	// If we make it one byte shorter it will be valid.
   108  	long_tag[sizeof long_tag - 2] = '\0';
   109  	g_assert_true(sc_security_tag_validate(long_tag, "foo"));
   110  
   111  }
   112  
   113  static void test_sc_is_hook_security_tag(void)
   114  {
   115  	// First, test the names we know are good
   116  	g_assert_true(sc_is_hook_security_tag("snap.foo.hook.bar"));
   117  	g_assert_true(sc_is_hook_security_tag("snap.foo.hook.bar-baz"));
   118  	g_assert_true(sc_is_hook_security_tag
   119  		      ("snap.foo_instance.hook.bar-baz"));
   120  	g_assert_true(sc_is_hook_security_tag("snap.foo_bar.hook.bar-baz"));
   121  
   122  	// Now, test the names we know are not valid hook security tags
   123  	g_assert_false(sc_is_hook_security_tag("snap.foo_instance.bar-baz"));
   124  	g_assert_false(sc_is_hook_security_tag("snap.name.app!hook.foo"));
   125  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook!foo"));
   126  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook.-foo"));
   127  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook.f00"));
   128  }
   129  
   130  static void test_sc_snap_or_instance_name_validate(gconstpointer data)
   131  {
   132  	typedef void (*validate_func_t)(const char *, sc_error **);
   133  
   134  	validate_func_t validate = (validate_func_t) data;
   135  	bool is_instance =
   136  	    (validate == sc_instance_name_validate) ? true : false;
   137  
   138  	sc_error *err = NULL;
   139  
   140  	// Smoke test, a valid snap name
   141  	validate("hello-world", &err);
   142  	g_assert_null(err);
   143  
   144  	// Smoke test: invalid character 
   145  	validate("hello world", &err);
   146  	g_assert_nonnull(err);
   147  	g_assert_true(sc_error_match
   148  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   149  	g_assert_cmpstr(sc_error_msg(err), ==,
   150  			"snap name must use lower case letters, digits or dashes");
   151  	sc_error_free(err);
   152  
   153  	// Smoke test: no letters
   154  	validate("", &err);
   155  	g_assert_nonnull(err);
   156  	g_assert_true(sc_error_match
   157  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   158  	g_assert_cmpstr(sc_error_msg(err), ==,
   159  			"snap name must contain at least one letter");
   160  	sc_error_free(err);
   161  
   162  	// Smoke test: leading dash
   163  	validate("-foo", &err);
   164  	g_assert_nonnull(err);
   165  	g_assert_true(sc_error_match
   166  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   167  	g_assert_cmpstr(sc_error_msg(err), ==,
   168  			"snap name cannot start with a dash");
   169  	sc_error_free(err);
   170  
   171  	// Smoke test: trailing dash
   172  	validate("foo-", &err);
   173  	g_assert_nonnull(err);
   174  	g_assert_true(sc_error_match
   175  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   176  	g_assert_cmpstr(sc_error_msg(err), ==,
   177  			"snap name cannot end with a dash");
   178  	sc_error_free(err);
   179  
   180  	// Smoke test: double dash
   181  	validate("f--oo", &err);
   182  	g_assert_nonnull(err);
   183  	g_assert_true(sc_error_match
   184  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   185  	g_assert_cmpstr(sc_error_msg(err), ==,
   186  			"snap name cannot contain two consecutive dashes");
   187  	sc_error_free(err);
   188  
   189  	// Smoke test: NULL name is not valid
   190  	validate(NULL, &err);
   191  	g_assert_nonnull(err);
   192  	// the only case when instance name validation diverges from snap name
   193  	// validation
   194  	if (!is_instance) {
   195  		g_assert_true(sc_error_match
   196  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   197  		g_assert_cmpstr(sc_error_msg(err), ==,
   198  				"snap name cannot be NULL");
   199  	} else {
   200  		g_assert_true(sc_error_match
   201  			      (err, SC_SNAP_DOMAIN,
   202  			       SC_SNAP_INVALID_INSTANCE_NAME));
   203  		g_assert_cmpstr(sc_error_msg(err), ==,
   204  				"snap instance name cannot be NULL");
   205  	}
   206  	sc_error_free(err);
   207  
   208  	const char *valid_names[] = {
   209  		"aa", "aaa", "aaaa",
   210  		"a-a", "aa-a", "a-aa", "a-b-c",
   211  		"a0", "a-0", "a-0a",
   212  		"01game", "1-or-2"
   213  	};
   214  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   215  		g_test_message("checking valid snap name: %s", valid_names[i]);
   216  		validate(valid_names[i], &err);
   217  		g_assert_null(err);
   218  	}
   219  	const char *invalid_names[] = {
   220  		// name cannot be empty
   221  		"",
   222  		// too short
   223  		"a",
   224  		// names cannot be too long
   225  		"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
   226  		"xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx",
   227  		"1111111111111111111111111111111111111111x",
   228  		"x1111111111111111111111111111111111111111",
   229  		"x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x",
   230  		// dashes alone are not a name
   231  		"-", "--",
   232  		// double dashes in a name are not allowed
   233  		"a--a",
   234  		// name should not end with a dash
   235  		"a-",
   236  		// name cannot have any spaces in it
   237  		"a ", " a", "a a",
   238  		// a number alone is not a name
   239  		"0", "123", "1-2-3",
   240  		// identifier must be plain ASCII
   241  		"日本語", "한글", "ру́сский язы́к",
   242  	};
   243  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   244  	     ++i) {
   245  		g_test_message("checking invalid snap name: >%s<",
   246  			       invalid_names[i]);
   247  		validate(invalid_names[i], &err);
   248  		g_assert_nonnull(err);
   249  		g_assert_true(sc_error_match
   250  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   251  		sc_error_free(err);
   252  	}
   253  	// Regression test: 12to8 and 123test
   254  	validate("12to8", &err);
   255  	g_assert_null(err);
   256  	validate("123test", &err);
   257  	g_assert_null(err);
   258  
   259  	// In case we switch to a regex, here's a test that could break things.
   260  	const char good_bad_name[] = "u-94903713687486543234157734673284536758";
   261  	char varname[sizeof good_bad_name] = { 0 };
   262  	for (size_t i = 3; i <= sizeof varname - 1; i++) {
   263  		g_assert_nonnull(memcpy(varname, good_bad_name, i));
   264  		varname[i] = 0;
   265  		g_test_message("checking valid snap name: >%s<", varname);
   266  		validate(varname, &err);
   267  		g_assert_null(err);
   268  		sc_error_free(err);
   269  	}
   270  }
   271  
   272  static void test_sc_snap_name_validate__respects_error_protocol(void)
   273  {
   274  	if (g_test_subprocess()) {
   275  		sc_snap_name_validate("hello world", NULL);
   276  		g_test_message("expected sc_snap_name_validate to return");
   277  		g_test_fail();
   278  		return;
   279  	}
   280  	g_test_trap_subprocess(NULL, 0, 0);
   281  	g_test_trap_assert_failed();
   282  	g_test_trap_assert_stderr
   283  	    ("snap name must use lower case letters, digits or dashes\n");
   284  }
   285  
   286  static void test_sc_instance_name_validate(void)
   287  {
   288  	sc_error *err = NULL;
   289  
   290  	sc_instance_name_validate("hello-world", &err);
   291  	g_assert_null(err);
   292  	sc_instance_name_validate("hello-world_foo", &err);
   293  	g_assert_null(err);
   294  
   295  	// just the separator
   296  	sc_instance_name_validate("_", &err);
   297  	g_assert_nonnull(err);
   298  	g_assert_true(sc_error_match
   299  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   300  	g_assert_cmpstr(sc_error_msg(err), ==,
   301  			"snap name must contain at least one letter");
   302  	sc_error_free(err);
   303  
   304  	// just name, with separator, missing instance key
   305  	sc_instance_name_validate("hello-world_", &err);
   306  	g_assert_nonnull(err);
   307  	g_assert_true(sc_error_match
   308  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_KEY));
   309  	g_assert_cmpstr(sc_error_msg(err), ==,
   310  			"instance key must contain at least one letter or digit");
   311  	sc_error_free(err);
   312  
   313  	// only separator and instance key, missing name
   314  	sc_instance_name_validate("_bar", &err);
   315  	g_assert_nonnull(err);
   316  	g_assert_true(sc_error_match
   317  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   318  	g_assert_cmpstr(sc_error_msg(err), ==,
   319  			"snap name must contain at least one letter");
   320  	sc_error_free(err);
   321  
   322  	sc_instance_name_validate("", &err);
   323  	g_assert_nonnull(err);
   324  	g_assert_true(sc_error_match
   325  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   326  	g_assert_cmpstr(sc_error_msg(err), ==,
   327  			"snap name must contain at least one letter");
   328  	sc_error_free(err);
   329  
   330  	// third separator
   331  	sc_instance_name_validate("foo_bar_baz", &err);
   332  	g_assert_nonnull(err);
   333  	g_assert_true(sc_error_match
   334  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_NAME));
   335  	g_assert_cmpstr(sc_error_msg(err), ==,
   336  			"snap instance name can contain only one underscore");
   337  	sc_error_free(err);
   338  
   339  	const char *valid_names[] = {
   340  		"aa", "aaa", "aaaa",
   341  		"aa_a", "aa_1", "aa_123", "aa_0123456789",
   342  	};
   343  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   344  		g_test_message("checking valid instance name: %s",
   345  			       valid_names[i]);
   346  		sc_instance_name_validate(valid_names[i], &err);
   347  		g_assert_null(err);
   348  	}
   349  	const char *invalid_names[] = {
   350  		// too short
   351  		"a",
   352  		// only letters and digits in the instance key
   353  		"a_--23))", "a_ ", "a_091234#", "a_123_456",
   354  		// up to 10 characters for the instance key
   355  		"a_01234567891", "a_0123456789123",
   356  		// snap name must not be more than 40 characters, regardless of instance
   357  		// key
   358  		"01234567890123456789012345678901234567890_foobar",
   359  		"01234567890123456789-01234567890123456789_foobar",
   360  		// instance key  must be plain ASCII
   361  		"foobar_日本語",
   362  		// way too many underscores
   363  		"foobar_baz_zed_daz",
   364  		"foobar______",
   365  	};
   366  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   367  	     ++i) {
   368  		g_test_message("checking invalid instance name: >%s<",
   369  			       invalid_names[i]);
   370  		sc_instance_name_validate(invalid_names[i], &err);
   371  		g_assert_nonnull(err);
   372  		sc_error_free(err);
   373  	}
   374  }
   375  
   376  static void test_sc_snap_drop_instance_key_no_dest(void)
   377  {
   378  	if (g_test_subprocess()) {
   379  		sc_snap_drop_instance_key("foo_bar", NULL, 0);
   380  		return;
   381  	}
   382  	g_test_trap_subprocess(NULL, 0, 0);
   383  	g_test_trap_assert_failed();
   384  
   385  }
   386  
   387  static void test_sc_snap_drop_instance_key_short_dest(void)
   388  {
   389  	if (g_test_subprocess()) {
   390  		char dest[10] = { 0 };
   391  		sc_snap_drop_instance_key("foo-foo-foo-foo-foo_bar", dest,
   392  					  sizeof dest);
   393  		return;
   394  	}
   395  	g_test_trap_subprocess(NULL, 0, 0);
   396  	g_test_trap_assert_failed();
   397  }
   398  
   399  static void test_sc_snap_drop_instance_key_short_dest2(void)
   400  {
   401  	if (g_test_subprocess()) {
   402  		char dest[3] = { 0 };	// "foo" sans the nil byte
   403  		sc_snap_drop_instance_key("foo", dest, sizeof dest);
   404  		return;
   405  	}
   406  	g_test_trap_subprocess(NULL, 0, 0);
   407  	g_test_trap_assert_failed();
   408  }
   409  
   410  static void test_sc_snap_drop_instance_key_no_name(void)
   411  {
   412  	if (g_test_subprocess()) {
   413  		char dest[10] = { 0 };
   414  		sc_snap_drop_instance_key(NULL, dest, sizeof dest);
   415  		return;
   416  	}
   417  	g_test_trap_subprocess(NULL, 0, 0);
   418  	g_test_trap_assert_failed();
   419  }
   420  
   421  static void test_sc_snap_drop_instance_key_short_dest_max(void)
   422  {
   423  	if (g_test_subprocess()) {
   424  		char dest[SNAP_NAME_LEN + 1] = { 0 };
   425  		/* 40 chars (max valid length), pretend dest is the same length, no space for terminator */
   426  		sc_snap_drop_instance_key
   427  		    ("01234567890123456789012345678901234567890", dest,
   428  		     sizeof dest - 1);
   429  		return;
   430  	}
   431  	g_test_trap_subprocess(NULL, 0, 0);
   432  	g_test_trap_assert_failed();
   433  }
   434  
   435  static void test_sc_snap_drop_instance_key_basic(void)
   436  {
   437  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   438  
   439  	sc_snap_drop_instance_key("foo_bar", name, sizeof name);
   440  	g_assert_cmpstr(name, ==, "foo");
   441  
   442  	memset(name, 0xff, sizeof name);
   443  	sc_snap_drop_instance_key("foo-bar_bar", name, sizeof name);
   444  	g_assert_cmpstr(name, ==, "foo-bar");
   445  
   446  	memset(name, 0xff, sizeof name);
   447  	sc_snap_drop_instance_key("foo-bar", name, sizeof name);
   448  	g_assert_cmpstr(name, ==, "foo-bar");
   449  
   450  	memset(name, 0xff, sizeof name);
   451  	sc_snap_drop_instance_key("_baz", name, sizeof name);
   452  	g_assert_cmpstr(name, ==, "");
   453  
   454  	memset(name, 0xff, sizeof name);
   455  	sc_snap_drop_instance_key("foo", name, sizeof name);
   456  	g_assert_cmpstr(name, ==, "foo");
   457  
   458  	memset(name, 0xff, sizeof name);
   459  	/* 40 chars - snap name length */
   460  	sc_snap_drop_instance_key("0123456789012345678901234567890123456789",
   461  				  name, sizeof name);
   462  	g_assert_cmpstr(name, ==, "0123456789012345678901234567890123456789");
   463  }
   464  
   465  static void test_sc_snap_split_instance_name_trailing_nil(void)
   466  {
   467  	if (g_test_subprocess()) {
   468  		char dest[3] = { 0 };
   469  		// pretend there is no place for trailing \0
   470  		sc_snap_split_instance_name("_", NULL, 0, dest, 0);
   471  		return;
   472  	}
   473  	g_test_trap_subprocess(NULL, 0, 0);
   474  	g_test_trap_assert_failed();
   475  }
   476  
   477  static void test_sc_snap_split_instance_name_short_instance_dest(void)
   478  {
   479  	if (g_test_subprocess()) {
   480  		char dest[10] = { 0 };
   481  		sc_snap_split_instance_name("foo_barbarbarbar", NULL, 0,
   482  					    dest, sizeof dest);
   483  		return;
   484  	}
   485  	g_test_trap_subprocess(NULL, 0, 0);
   486  	g_test_trap_assert_failed();
   487  }
   488  
   489  static void test_sc_snap_split_instance_name_basic(void)
   490  {
   491  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   492  	char instance[20] = { 0xff };
   493  
   494  	sc_snap_split_instance_name("foo_bar", name, sizeof name, instance,
   495  				    sizeof instance);
   496  	g_assert_cmpstr(name, ==, "foo");
   497  	g_assert_cmpstr(instance, ==, "bar");
   498  
   499  	memset(name, 0xff, sizeof name);
   500  	memset(instance, 0xff, sizeof instance);
   501  	sc_snap_split_instance_name("foo-bar_bar", name, sizeof name, instance,
   502  				    sizeof instance);
   503  	g_assert_cmpstr(name, ==, "foo-bar");
   504  	g_assert_cmpstr(instance, ==, "bar");
   505  
   506  	memset(name, 0xff, sizeof name);
   507  	memset(instance, 0xff, sizeof instance);
   508  	sc_snap_split_instance_name("foo-bar", name, sizeof name, instance,
   509  				    sizeof instance);
   510  	g_assert_cmpstr(name, ==, "foo-bar");
   511  	g_assert_cmpstr(instance, ==, "");
   512  
   513  	memset(name, 0xff, sizeof name);
   514  	memset(instance, 0xff, sizeof instance);
   515  	sc_snap_split_instance_name("_baz", name, sizeof name, instance,
   516  				    sizeof instance);
   517  	g_assert_cmpstr(name, ==, "");
   518  	g_assert_cmpstr(instance, ==, "baz");
   519  
   520  	memset(name, 0xff, sizeof name);
   521  	memset(instance, 0xff, sizeof instance);
   522  	sc_snap_split_instance_name("foo", name, sizeof name, instance,
   523  				    sizeof instance);
   524  	g_assert_cmpstr(name, ==, "foo");
   525  	g_assert_cmpstr(instance, ==, "");
   526  
   527  	memset(name, 0xff, sizeof name);
   528  	sc_snap_split_instance_name("foo_bar", name, sizeof name, NULL, 0);
   529  	g_assert_cmpstr(name, ==, "foo");
   530  
   531  	memset(instance, 0xff, sizeof instance);
   532  	sc_snap_split_instance_name("foo_bar", NULL, 0, instance,
   533  				    sizeof instance);
   534  	g_assert_cmpstr(instance, ==, "bar");
   535  
   536  	memset(name, 0xff, sizeof name);
   537  	memset(instance, 0xff, sizeof instance);
   538  	sc_snap_split_instance_name("hello_world_surprise", name, sizeof name,
   539  				    instance, sizeof instance);
   540  	g_assert_cmpstr(name, ==, "hello");
   541  	g_assert_cmpstr(instance, ==, "world_surprise");
   542  
   543  	memset(name, 0xff, sizeof name);
   544  	memset(instance, 0xff, sizeof instance);
   545  	sc_snap_split_instance_name("", name, sizeof name, instance,
   546  				    sizeof instance);
   547  	g_assert_cmpstr(name, ==, "");
   548  	g_assert_cmpstr(instance, ==, "");
   549  
   550  	memset(name, 0xff, sizeof name);
   551  	memset(instance, 0xff, sizeof instance);
   552  	sc_snap_split_instance_name("_", name, sizeof name, instance,
   553  				    sizeof instance);
   554  	g_assert_cmpstr(name, ==, "");
   555  	g_assert_cmpstr(instance, ==, "");
   556  
   557  	memset(name, 0xff, sizeof name);
   558  	memset(instance, 0xff, sizeof instance);
   559  	sc_snap_split_instance_name("foo_", name, sizeof name, instance,
   560  				    sizeof instance);
   561  	g_assert_cmpstr(name, ==, "foo");
   562  	g_assert_cmpstr(instance, ==, "");
   563  }
   564  
   565  static void __attribute__((constructor)) init(void)
   566  {
   567  	g_test_add_func("/snap/sc_security_tag_validate", test_sc_security_tag_validate);
   568  	g_test_add_func("/snap/sc_is_hook_security_tag",
   569  			test_sc_is_hook_security_tag);
   570  
   571  	g_test_add_data_func("/snap/sc_snap_name_validate",
   572  			     sc_snap_name_validate,
   573  			     test_sc_snap_or_instance_name_validate);
   574  	g_test_add_func("/snap/sc_snap_name_validate/respects_error_protocol",
   575  			test_sc_snap_name_validate__respects_error_protocol);
   576  
   577  	g_test_add_data_func("/snap/sc_instance_name_validate/just_name",
   578  			     sc_instance_name_validate,
   579  			     test_sc_snap_or_instance_name_validate);
   580  	g_test_add_func("/snap/sc_instance_name_validate/full",
   581  			test_sc_instance_name_validate);
   582  
   583  	g_test_add_func("/snap/sc_snap_drop_instance_key/basic",
   584  			test_sc_snap_drop_instance_key_basic);
   585  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_dest",
   586  			test_sc_snap_drop_instance_key_no_dest);
   587  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_name",
   588  			test_sc_snap_drop_instance_key_no_name);
   589  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest",
   590  			test_sc_snap_drop_instance_key_short_dest);
   591  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest2",
   592  			test_sc_snap_drop_instance_key_short_dest2);
   593  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest_max",
   594  			test_sc_snap_drop_instance_key_short_dest_max);
   595  
   596  	g_test_add_func("/snap/sc_snap_split_instance_name/basic",
   597  			test_sc_snap_split_instance_name_basic);
   598  	g_test_add_func("/snap/sc_snap_split_instance_name/trailing_nil",
   599  			test_sc_snap_split_instance_name_trailing_nil);
   600  	g_test_add_func("/snap/sc_snap_split_instance_name/short_instance_dest",
   601  			test_sc_snap_split_instance_name_short_instance_dest);
   602  }