All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Iooss <nicolas.iooss@m4x.org>
To: selinux@tycho.nsa.gov
Subject: [PATCH 5/7] libsemanage: add semanage_str_replace() utility function
Date: Mon, 19 Dec 2016 14:04:02 +0100	[thread overview]
Message-ID: <20161219130404.11496-6-nicolas.iooss@m4x.org> (raw)
In-Reply-To: <20161219130404.11496-1-nicolas.iooss@m4x.org>

This function will be used in the next commit.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
 libsemanage/src/utilities.c        | 55 ++++++++++++++++++++++++++++++++++++++
 libsemanage/src/utilities.h        | 10 +++++++
 libsemanage/tests/test_utilities.c | 34 +++++++++++++++++++++++
 3 files changed, 99 insertions(+)

diff --git a/libsemanage/src/utilities.c b/libsemanage/src/utilities.c
index b5b92b085310..0b4ee5e654be 100644
--- a/libsemanage/src/utilities.c
+++ b/libsemanage/src/utilities.c
@@ -235,6 +235,61 @@ void semanage_rtrim(char *str, char trim_to)
 	}
 }
 
+char *semanage_str_replace(const char *search, const char *replace,
+			   const char *src, size_t lim)
+{
+	size_t count = 0, slen, rlen, newsize;
+	char *p, *pres, *result;
+	const char *psrc;
+
+	slen = strlen(search);
+	rlen = strlen(replace);
+
+	/* Do not support empty search strings */
+	if (slen == 0)
+		return NULL;
+
+	/* Count the occurences of search in src and compute the new size */
+	for (p = strstr(src, search); p != NULL; p = strstr(p + slen, search)) {
+		count += 1;
+		if (lim && count >= lim)
+			break;
+	}
+	if (!count)
+		return strdup(src);
+
+	/* Allocate the result string */
+	newsize = strlen(src) + 1 + count * (rlen - slen);
+	result = malloc(newsize);
+	if (!result)
+		return NULL;
+
+	/* Fill the result */
+	psrc = src;
+	pres = result;
+	for (p = strstr(src, search); p != NULL; p = strstr(psrc, search)) {
+		/* Copy the part which has not been modified */
+		if (p != psrc) {
+			size_t length = (size_t)(p - psrc);
+			memcpy(pres, psrc, length);
+			pres += length;
+		}
+		/* Copy the replacement part */
+		if (rlen != 0) {
+			memcpy(pres, replace, rlen);
+			pres += rlen;
+		}
+		psrc = p + slen;
+		count -= 1;
+		if (!count)
+			break;
+	}
+	/* Copy the last part, after doing a sanity check */
+	assert(pres + strlen(psrc) + 1 == result + newsize);
+	strcpy(pres, psrc);
+	return result;
+}
+
 /* list_addafter_controlmem does *NOT* duplicate the data argument
  * use at your own risk, I am building a list out of malloc'd memory and
  * it is only going to get stored into this list, thus when I destroy it
diff --git a/libsemanage/src/utilities.h b/libsemanage/src/utilities.h
index 5fa15efd08d0..f2ff31f0f5b6 100644
--- a/libsemanage/src/utilities.h
+++ b/libsemanage/src/utilities.h
@@ -116,6 +116,16 @@ int semanage_str_count(char *data, char what);
 void semanage_rtrim(char *str, char trim_to);
 
 /**
+ * @param      value being searched for
+ * @param      replacement value that replaces found search values
+ * @param      string being searched and replaced on
+ * @param      maximum number of value occurences (zero for unlimited)
+ * @return     newly-allocated string with the replaced values
+ */
+char *semanage_str_replace(const char *search, const char *replace,
+			   const char *src, size_t lim);
+
+/**
  * @param data    some string
  * @return  modifies the string such that the first whitespace char becomes
  *	    '\0', ending the string.
diff --git a/libsemanage/tests/test_utilities.c b/libsemanage/tests/test_utilities.c
index 27fa70dc2a57..7a83596e1566 100644
--- a/libsemanage/tests/test_utilities.c
+++ b/libsemanage/tests/test_utilities.c
@@ -40,6 +40,7 @@ void test_semanage_split(void);
 void test_semanage_list(void);
 void test_semanage_str_count(void);
 void test_semanage_rtrim(void);
+void test_semanage_str_replace(void);
 void test_semanage_findval(void);
 void test_slurp_file_filter(void);
 
@@ -101,6 +102,10 @@ int semanage_utilities_add_tests(CU_pSuite suite)
 	if (NULL == CU_add_test(suite, "semanage_rtrim", test_semanage_rtrim)) {
 		goto err;
 	}
+	if (NULL == CU_add_test(suite, "semanage_str_replace",
+				test_semanage_str_replace)) {
+		goto err;
+	}
 	if (NULL == CU_add_test(suite, "semanage_findval",
 				test_semanage_findval)) {
 		goto err;
@@ -257,6 +262,35 @@ void test_semanage_rtrim(void)
 	free(str);
 }
 
+void test_semanage_str_replace(void)
+{
+	const char *test_str = "Hello, I am %{USERNAME} and my id is %{USERID}";
+	char *str1, *str2;
+
+	str1 = semanage_str_replace("%{USERNAME}", "root", test_str, 0);
+	CU_ASSERT_STRING_EQUAL(str1, "Hello, I am root and my id is %{USERID}");
+
+	str2 = semanage_str_replace("%{USERID}", "0", str1, 1);
+	CU_ASSERT_STRING_EQUAL(str2, "Hello, I am root and my id is 0");
+	free(str1);
+	free(str2);
+
+	str1 = semanage_str_replace(":(", ";)", "Test :( :) ! :(:(:))(:(", 0);
+	CU_ASSERT_STRING_EQUAL(str1, "Test ;) :) ! ;);):))(;)");
+	free(str1);
+
+	str1 = semanage_str_replace(":(", ";)", "Test :( :) ! :(:(:))(:(", 3);
+	CU_ASSERT_STRING_EQUAL(str1, "Test ;) :) ! ;);):))(:(");
+	free(str1);
+
+	str1 = semanage_str_replace("", "empty search string", "test", 0);
+	CU_ASSERT_EQUAL(str1, NULL);
+
+	str1 = semanage_str_replace("a", "", "abracadabra", 0);
+	CU_ASSERT_STRING_EQUAL(str1, "brcdbr");
+	free(str1);
+}
+
 void test_semanage_findval(void)
 {
 	char *tok;
-- 
2.11.0

  parent reply	other threads:[~2016-12-19 13:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-19 13:03 [PATCH 0/7] Remove ustr library dependency Nicolas Iooss
2016-12-19 13:03 ` [PATCH 1/7] libsemanage/tests: make "make test" fail when a CUnit test fails Nicolas Iooss
2016-12-19 13:03 ` [PATCH 2/7] libsemanage/tests: make tests standalone Nicolas Iooss
2016-12-19 13:04 ` [PATCH 3/7] libsemanage/tests: test more cases of semanage_split*() Nicolas Iooss
2016-12-19 13:04 ` [PATCH 4/7] libsemanage: simplify string utilities functions Nicolas Iooss
2016-12-19 15:46   ` Stephen Smalley
2016-12-21 15:23     ` Nicolas Iooss
2016-12-19 13:04 ` Nicolas Iooss [this message]
2016-12-19 18:02   ` [PATCH 5/7] libsemanage: add semanage_str_replace() utility function Stephen Smalley
2016-12-19 13:04 ` [PATCH 6/7] libsemanage: genhomedircon: drop ustr dependency Nicolas Iooss
2016-12-19 18:32   ` Stephen Smalley
2016-12-21 15:15     ` Nicolas Iooss
2016-12-21 15:42       ` Stephen Smalley
2016-12-19 18:43   ` Stephen Smalley
2016-12-19 13:04 ` [PATCH 7/7] libsemanage: remove ustr library from Makefiles, README and pkg-config Nicolas Iooss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161219130404.11496-6-nicolas.iooss@m4x.org \
    --to=nicolas.iooss@m4x.org \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.