gitee.com/mysnapcore/mysnapd@v0.1.0/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  	g_assert_true(sc_is_hook_security_tag("snap.foo_bar.hook.f00"));
   122  	g_assert_true(sc_is_hook_security_tag("snap.foo_bar.hook.f-0-0"));
   123  
   124  	// Now, test the names we know are not valid hook security tags
   125  	g_assert_false(sc_is_hook_security_tag("snap.foo_instance.bar-baz"));
   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!foo"));
   128  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook.-foo"));
   129  	g_assert_false(sc_is_hook_security_tag("snap.foo_bar.hook.0abcd"));
   130  	g_assert_false(sc_is_hook_security_tag("snap.foo.hook.abc--"));
   131  	g_assert_false(sc_is_hook_security_tag("snap.foo_bar.hook.!foo"));
   132  	g_assert_false(sc_is_hook_security_tag("snap.foo_bar.hook.-foo"));
   133  	g_assert_false(sc_is_hook_security_tag("snap.foo_bar.hook!foo"));
   134  	g_assert_false(sc_is_hook_security_tag("snap.foo_bar.!foo"));
   135  }
   136  
   137  static void test_sc_snap_or_instance_name_validate(gconstpointer data)
   138  {
   139  	typedef void (*validate_func_t)(const char *, sc_error **);
   140  
   141  	validate_func_t validate = (validate_func_t) data;
   142  	bool is_instance =
   143  	    (validate == sc_instance_name_validate) ? true : false;
   144  
   145  	sc_error *err = NULL;
   146  
   147  	// Smoke test, a valid snap name
   148  	validate("hello-world", &err);
   149  	g_assert_null(err);
   150  
   151  	// Smoke test: invalid character 
   152  	validate("hello world", &err);
   153  	g_assert_nonnull(err);
   154  	g_assert_true(sc_error_match
   155  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   156  	g_assert_cmpstr(sc_error_msg(err), ==,
   157  			"snap name must use lower case letters, digits or dashes");
   158  	sc_error_free(err);
   159  
   160  	// Smoke test: no letters
   161  	validate("", &err);
   162  	g_assert_nonnull(err);
   163  	g_assert_true(sc_error_match
   164  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   165  	g_assert_cmpstr(sc_error_msg(err), ==,
   166  			"snap name must contain at least one letter");
   167  	sc_error_free(err);
   168  
   169  	// Smoke test: leading dash
   170  	validate("-foo", &err);
   171  	g_assert_nonnull(err);
   172  	g_assert_true(sc_error_match
   173  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   174  	g_assert_cmpstr(sc_error_msg(err), ==,
   175  			"snap name cannot start with a dash");
   176  	sc_error_free(err);
   177  
   178  	// Smoke test: trailing dash
   179  	validate("foo-", &err);
   180  	g_assert_nonnull(err);
   181  	g_assert_true(sc_error_match
   182  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   183  	g_assert_cmpstr(sc_error_msg(err), ==,
   184  			"snap name cannot end with a dash");
   185  	sc_error_free(err);
   186  
   187  	// Smoke test: double dash
   188  	validate("f--oo", &err);
   189  	g_assert_nonnull(err);
   190  	g_assert_true(sc_error_match
   191  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   192  	g_assert_cmpstr(sc_error_msg(err), ==,
   193  			"snap name cannot contain two consecutive dashes");
   194  	sc_error_free(err);
   195  
   196  	// Smoke test: NULL name is not valid
   197  	validate(NULL, &err);
   198  	g_assert_nonnull(err);
   199  	// the only case when instance name validation diverges from snap name
   200  	// validation
   201  	if (!is_instance) {
   202  		g_assert_true(sc_error_match
   203  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   204  		g_assert_cmpstr(sc_error_msg(err), ==,
   205  				"snap name cannot be NULL");
   206  	} else {
   207  		g_assert_true(sc_error_match
   208  			      (err, SC_SNAP_DOMAIN,
   209  			       SC_SNAP_INVALID_INSTANCE_NAME));
   210  		g_assert_cmpstr(sc_error_msg(err), ==,
   211  				"snap instance name cannot be NULL");
   212  	}
   213  	sc_error_free(err);
   214  
   215  	const char *valid_names[] = {
   216  		"aa", "aaa", "aaaa",
   217  		"a-a", "aa-a", "a-aa", "a-b-c",
   218  		"a0", "a-0", "a-0a",
   219  		"01game", "1-or-2"
   220  	};
   221  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   222  		g_test_message("checking valid snap name: %s", valid_names[i]);
   223  		validate(valid_names[i], &err);
   224  		g_assert_null(err);
   225  	}
   226  	const char *invalid_names[] = {
   227  		// name cannot be empty
   228  		"",
   229  		// too short
   230  		"a",
   231  		// names cannot be too long
   232  		"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
   233  		"xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx",
   234  		"1111111111111111111111111111111111111111x",
   235  		"x1111111111111111111111111111111111111111",
   236  		"x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x",
   237  		// dashes alone are not a name
   238  		"-", "--",
   239  		// double dashes in a name are not allowed
   240  		"a--a",
   241  		// name should not end with a dash
   242  		"a-",
   243  		// name cannot have any spaces in it
   244  		"a ", " a", "a a",
   245  		// a number alone is not a name
   246  		"0", "123", "1-2-3",
   247  		// identifier must be plain ASCII
   248  		"日本語", "한글", "ру́сский язы́к",
   249  	};
   250  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   251  	     ++i) {
   252  		g_test_message("checking invalid snap name: >%s<",
   253  			       invalid_names[i]);
   254  		validate(invalid_names[i], &err);
   255  		g_assert_nonnull(err);
   256  		g_assert_true(sc_error_match
   257  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   258  		sc_error_free(err);
   259  	}
   260  	// Regression test: 12to8 and 123test
   261  	validate("12to8", &err);
   262  	g_assert_null(err);
   263  	validate("123test", &err);
   264  	g_assert_null(err);
   265  
   266  	// In case we switch to a regex, here's a test that could break things.
   267  	const char good_bad_name[] = "u-94903713687486543234157734673284536758";
   268  	char varname[sizeof good_bad_name] = { 0 };
   269  	for (size_t i = 3; i <= sizeof varname - 1; i++) {
   270  		g_assert_nonnull(memcpy(varname, good_bad_name, i));
   271  		varname[i] = 0;
   272  		g_test_message("checking valid snap name: >%s<", varname);
   273  		validate(varname, &err);
   274  		g_assert_null(err);
   275  		sc_error_free(err);
   276  	}
   277  }
   278  
   279  static void test_sc_snap_name_validate__respects_error_protocol(void)
   280  {
   281  	if (g_test_subprocess()) {
   282  		sc_snap_name_validate("hello world", NULL);
   283  		g_test_message("expected sc_snap_name_validate to return");
   284  		g_test_fail();
   285  		return;
   286  	}
   287  	g_test_trap_subprocess(NULL, 0, 0);
   288  	g_test_trap_assert_failed();
   289  	g_test_trap_assert_stderr
   290  	    ("snap name must use lower case letters, digits or dashes\n");
   291  }
   292  
   293  static void test_sc_instance_name_validate(void)
   294  {
   295  	sc_error *err = NULL;
   296  
   297  	sc_instance_name_validate("hello-world", &err);
   298  	g_assert_null(err);
   299  	sc_instance_name_validate("hello-world_foo", &err);
   300  	g_assert_null(err);
   301  
   302  	// just the separator
   303  	sc_instance_name_validate("_", &err);
   304  	g_assert_nonnull(err);
   305  	g_assert_true(sc_error_match
   306  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   307  	g_assert_cmpstr(sc_error_msg(err), ==,
   308  			"snap name must contain at least one letter");
   309  	sc_error_free(err);
   310  
   311  	// just name, with separator, missing instance key
   312  	sc_instance_name_validate("hello-world_", &err);
   313  	g_assert_nonnull(err);
   314  	g_assert_true(sc_error_match
   315  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_KEY));
   316  	g_assert_cmpstr(sc_error_msg(err), ==,
   317  			"instance key must contain at least one letter or digit");
   318  	sc_error_free(err);
   319  
   320  	// only separator and instance key, missing name
   321  	sc_instance_name_validate("_bar", &err);
   322  	g_assert_nonnull(err);
   323  	g_assert_true(sc_error_match
   324  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   325  	g_assert_cmpstr(sc_error_msg(err), ==,
   326  			"snap name must contain at least one letter");
   327  	sc_error_free(err);
   328  
   329  	sc_instance_name_validate("", &err);
   330  	g_assert_nonnull(err);
   331  	g_assert_true(sc_error_match
   332  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   333  	g_assert_cmpstr(sc_error_msg(err), ==,
   334  			"snap name must contain at least one letter");
   335  	sc_error_free(err);
   336  
   337  	// third separator
   338  	sc_instance_name_validate("foo_bar_baz", &err);
   339  	g_assert_nonnull(err);
   340  	g_assert_true(sc_error_match
   341  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_NAME));
   342  	g_assert_cmpstr(sc_error_msg(err), ==,
   343  			"snap instance name can contain only one underscore");
   344  	sc_error_free(err);
   345  
   346  	const char *valid_names[] = {
   347  		"aa", "aaa", "aaaa",
   348  		"aa_a", "aa_1", "aa_123", "aa_0123456789",
   349  	};
   350  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   351  		g_test_message("checking valid instance name: %s",
   352  			       valid_names[i]);
   353  		sc_instance_name_validate(valid_names[i], &err);
   354  		g_assert_null(err);
   355  	}
   356  	const char *invalid_names[] = {
   357  		// too short
   358  		"a",
   359  		// only letters and digits in the instance key
   360  		"a_--23))", "a_ ", "a_091234#", "a_123_456",
   361  		// up to 10 characters for the instance key
   362  		"a_01234567891", "a_0123456789123",
   363  		// snap name must not be more than 40 characters, regardless of instance
   364  		// key
   365  		"01234567890123456789012345678901234567890_foobar",
   366  		"01234567890123456789-01234567890123456789_foobar",
   367  		// instance key  must be plain ASCII
   368  		"foobar_日本語",
   369  		// way too many underscores
   370  		"foobar_baz_zed_daz",
   371  		"foobar______",
   372  	};
   373  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   374  	     ++i) {
   375  		g_test_message("checking invalid instance name: >%s<",
   376  			       invalid_names[i]);
   377  		sc_instance_name_validate(invalid_names[i], &err);
   378  		g_assert_nonnull(err);
   379  		sc_error_free(err);
   380  	}
   381  }
   382  
   383  static void test_sc_snap_drop_instance_key_no_dest(void)
   384  {
   385  	if (g_test_subprocess()) {
   386  		sc_snap_drop_instance_key("foo_bar", NULL, 0);
   387  		return;
   388  	}
   389  	g_test_trap_subprocess(NULL, 0, 0);
   390  	g_test_trap_assert_failed();
   391  
   392  }
   393  
   394  static void test_sc_snap_drop_instance_key_short_dest(void)
   395  {
   396  	if (g_test_subprocess()) {
   397  		char dest[10] = { 0 };
   398  		sc_snap_drop_instance_key("foo-foo-foo-foo-foo_bar", dest,
   399  					  sizeof dest);
   400  		return;
   401  	}
   402  	g_test_trap_subprocess(NULL, 0, 0);
   403  	g_test_trap_assert_failed();
   404  }
   405  
   406  static void test_sc_snap_drop_instance_key_short_dest2(void)
   407  {
   408  	if (g_test_subprocess()) {
   409  		char dest[3] = { 0 };	// "foo" sans the nil byte
   410  		sc_snap_drop_instance_key("foo", dest, sizeof dest);
   411  		return;
   412  	}
   413  	g_test_trap_subprocess(NULL, 0, 0);
   414  	g_test_trap_assert_failed();
   415  }
   416  
   417  static void test_sc_snap_drop_instance_key_no_name(void)
   418  {
   419  	if (g_test_subprocess()) {
   420  		char dest[10] = { 0 };
   421  		sc_snap_drop_instance_key(NULL, dest, sizeof dest);
   422  		return;
   423  	}
   424  	g_test_trap_subprocess(NULL, 0, 0);
   425  	g_test_trap_assert_failed();
   426  }
   427  
   428  static void test_sc_snap_drop_instance_key_short_dest_max(void)
   429  {
   430  	if (g_test_subprocess()) {
   431  		char dest[SNAP_NAME_LEN + 1] = { 0 };
   432  		/* 40 chars (max valid length), pretend dest is the same length, no space for terminator */
   433  		sc_snap_drop_instance_key
   434  		    ("01234567890123456789012345678901234567890", dest,
   435  		     sizeof dest - 1);
   436  		return;
   437  	}
   438  	g_test_trap_subprocess(NULL, 0, 0);
   439  	g_test_trap_assert_failed();
   440  }
   441  
   442  static void test_sc_snap_drop_instance_key_basic(void)
   443  {
   444  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   445  
   446  	sc_snap_drop_instance_key("foo_bar", name, sizeof name);
   447  	g_assert_cmpstr(name, ==, "foo");
   448  
   449  	memset(name, 0xff, sizeof name);
   450  	sc_snap_drop_instance_key("foo-bar_bar", name, sizeof name);
   451  	g_assert_cmpstr(name, ==, "foo-bar");
   452  
   453  	memset(name, 0xff, sizeof name);
   454  	sc_snap_drop_instance_key("foo-bar", name, sizeof name);
   455  	g_assert_cmpstr(name, ==, "foo-bar");
   456  
   457  	memset(name, 0xff, sizeof name);
   458  	sc_snap_drop_instance_key("_baz", name, sizeof name);
   459  	g_assert_cmpstr(name, ==, "");
   460  
   461  	memset(name, 0xff, sizeof name);
   462  	sc_snap_drop_instance_key("foo", name, sizeof name);
   463  	g_assert_cmpstr(name, ==, "foo");
   464  
   465  	memset(name, 0xff, sizeof name);
   466  	/* 40 chars - snap name length */
   467  	sc_snap_drop_instance_key("0123456789012345678901234567890123456789",
   468  				  name, sizeof name);
   469  	g_assert_cmpstr(name, ==, "0123456789012345678901234567890123456789");
   470  }
   471  
   472  static void test_sc_snap_split_instance_name_trailing_nil(void)
   473  {
   474  	if (g_test_subprocess()) {
   475  		char dest[3] = { 0 };
   476  		// pretend there is no place for trailing \0
   477  		sc_snap_split_instance_name("_", NULL, 0, dest, 0);
   478  		return;
   479  	}
   480  	g_test_trap_subprocess(NULL, 0, 0);
   481  	g_test_trap_assert_failed();
   482  }
   483  
   484  static void test_sc_snap_split_instance_name_short_instance_dest(void)
   485  {
   486  	if (g_test_subprocess()) {
   487  		char dest[10] = { 0 };
   488  		sc_snap_split_instance_name("foo_barbarbarbar", NULL, 0,
   489  					    dest, sizeof dest);
   490  		return;
   491  	}
   492  	g_test_trap_subprocess(NULL, 0, 0);
   493  	g_test_trap_assert_failed();
   494  }
   495  
   496  static void test_sc_snap_split_instance_name_basic(void)
   497  {
   498  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   499  	char instance[20] = { 0xff };
   500  
   501  	sc_snap_split_instance_name("foo_bar", name, sizeof name, instance,
   502  				    sizeof instance);
   503  	g_assert_cmpstr(name, ==, "foo");
   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_bar", name, sizeof name, instance,
   509  				    sizeof instance);
   510  	g_assert_cmpstr(name, ==, "foo-bar");
   511  	g_assert_cmpstr(instance, ==, "bar");
   512  
   513  	memset(name, 0xff, sizeof name);
   514  	memset(instance, 0xff, sizeof instance);
   515  	sc_snap_split_instance_name("foo-bar", name, sizeof name, instance,
   516  				    sizeof instance);
   517  	g_assert_cmpstr(name, ==, "foo-bar");
   518  	g_assert_cmpstr(instance, ==, "");
   519  
   520  	memset(name, 0xff, sizeof name);
   521  	memset(instance, 0xff, sizeof instance);
   522  	sc_snap_split_instance_name("_baz", name, sizeof name, instance,
   523  				    sizeof instance);
   524  	g_assert_cmpstr(name, ==, "");
   525  	g_assert_cmpstr(instance, ==, "baz");
   526  
   527  	memset(name, 0xff, sizeof name);
   528  	memset(instance, 0xff, sizeof instance);
   529  	sc_snap_split_instance_name("foo", name, sizeof name, instance,
   530  				    sizeof instance);
   531  	g_assert_cmpstr(name, ==, "foo");
   532  	g_assert_cmpstr(instance, ==, "");
   533  
   534  	memset(name, 0xff, sizeof name);
   535  	sc_snap_split_instance_name("foo_bar", name, sizeof name, NULL, 0);
   536  	g_assert_cmpstr(name, ==, "foo");
   537  
   538  	memset(instance, 0xff, sizeof instance);
   539  	sc_snap_split_instance_name("foo_bar", NULL, 0, instance,
   540  				    sizeof instance);
   541  	g_assert_cmpstr(instance, ==, "bar");
   542  
   543  	memset(name, 0xff, sizeof name);
   544  	memset(instance, 0xff, sizeof instance);
   545  	sc_snap_split_instance_name("hello_world_surprise", name, sizeof name,
   546  				    instance, sizeof instance);
   547  	g_assert_cmpstr(name, ==, "hello");
   548  	g_assert_cmpstr(instance, ==, "world_surprise");
   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("_", name, sizeof name, instance,
   560  				    sizeof instance);
   561  	g_assert_cmpstr(name, ==, "");
   562  	g_assert_cmpstr(instance, ==, "");
   563  
   564  	memset(name, 0xff, sizeof name);
   565  	memset(instance, 0xff, sizeof instance);
   566  	sc_snap_split_instance_name("foo_", name, sizeof name, instance,
   567  				    sizeof instance);
   568  	g_assert_cmpstr(name, ==, "foo");
   569  	g_assert_cmpstr(instance, ==, "");
   570  }
   571  
   572  static void __attribute__((constructor)) init(void)
   573  {
   574  	g_test_add_func("/snap/sc_security_tag_validate", test_sc_security_tag_validate);
   575  	g_test_add_func("/snap/sc_is_hook_security_tag",
   576  			test_sc_is_hook_security_tag);
   577  
   578  	g_test_add_data_func("/snap/sc_snap_name_validate",
   579  			     sc_snap_name_validate,
   580  			     test_sc_snap_or_instance_name_validate);
   581  	g_test_add_func("/snap/sc_snap_name_validate/respects_error_protocol",
   582  			test_sc_snap_name_validate__respects_error_protocol);
   583  
   584  	g_test_add_data_func("/snap/sc_instance_name_validate/just_name",
   585  			     sc_instance_name_validate,
   586  			     test_sc_snap_or_instance_name_validate);
   587  	g_test_add_func("/snap/sc_instance_name_validate/full",
   588  			test_sc_instance_name_validate);
   589  
   590  	g_test_add_func("/snap/sc_snap_drop_instance_key/basic",
   591  			test_sc_snap_drop_instance_key_basic);
   592  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_dest",
   593  			test_sc_snap_drop_instance_key_no_dest);
   594  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_name",
   595  			test_sc_snap_drop_instance_key_no_name);
   596  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest",
   597  			test_sc_snap_drop_instance_key_short_dest);
   598  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest2",
   599  			test_sc_snap_drop_instance_key_short_dest2);
   600  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest_max",
   601  			test_sc_snap_drop_instance_key_short_dest_max);
   602  
   603  	g_test_add_func("/snap/sc_snap_split_instance_name/basic",
   604  			test_sc_snap_split_instance_name_basic);
   605  	g_test_add_func("/snap/sc_snap_split_instance_name/trailing_nil",
   606  			test_sc_snap_split_instance_name_trailing_nil);
   607  	g_test_add_func("/snap/sc_snap_split_instance_name/short_instance_dest",
   608  			test_sc_snap_split_instance_name_short_instance_dest);
   609  }