aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2022-03-18 12:47:10 +0000
committerWerner Koch <[email protected]>2022-03-18 13:14:39 +0000
commit449d2fbcde630974628285d3405feb6ab2a812f9 (patch)
treee2eef0f8d1ff5e68d3bacb5a8193829cb31333b1
parentgpg: Allow decryption of symencr even for non-compliant cipher. (diff)
downloadgnupg-449d2fbcde630974628285d3405feb6ab2a812f9.tar.gz
gnupg-449d2fbcde630974628285d3405feb6ab2a812f9.zip
common: New function map_static_strings
* common/mapstrings.c (struct intmapping_s): New. (map_static_strings): New. * common/stringhelp.c (do_strconcat): Rename to ... (vstrconcat): this and make global. * common/t-mapstrings.c (test_map_static_strings): New test.
-rw-r--r--common/mapstrings.c49
-rw-r--r--common/stringhelp.c11
-rw-r--r--common/stringhelp.h5
-rw-r--r--common/t-mapstrings.c26
4 files changed, 86 insertions, 5 deletions
diff --git a/common/mapstrings.c b/common/mapstrings.c
index 318ca5bd1..172e198ea 100644
--- a/common/mapstrings.c
+++ b/common/mapstrings.c
@@ -69,6 +69,18 @@ struct mapping_s
static struct mapping_s *mappings;
+/* Similar to above but using two integers and a domain as key. */
+struct intmapping_s
+{
+ struct intmapping_s *next;
+ int key1;
+ int key2;
+ const char *string;
+ char domain[1];
+};
+static struct intmapping_s *intmappings;
+
+
/* If STRING has already been mapped, return the mapped string. If
not return NULL. */
static const char *
@@ -166,3 +178,40 @@ map_static_macro_string (const char *string)
return store_mapping (string, p);
}
+
+
+/* If a list of strings has already been mapped to a the tuple
+ * (DOMAIN,KEY1,KEY2) return that string. If not, create a mapping
+ * made up of the concatenation of the given strings. */
+const char *
+map_static_strings (const char *domain, int key1, int key2,
+ const char *string1, ...)
+{
+ va_list arg_ptr;
+ struct intmapping_s *m;
+
+ if (!string1 || !domain)
+ return "";
+
+ for (m = intmappings; m; m = m->next)
+ if (m->key1 == key1 && m->key2 == key2 && !strcmp (domain, m->domain))
+ return m->string;
+
+ m = xmalloc (sizeof *m + strlen (domain));
+ strcpy (m->domain, domain);
+ m->key1 = key1;
+ m->key2 = key2;
+
+ va_start (arg_ptr, string1);
+ m->string = vstrconcat (string1, arg_ptr);
+ va_end (arg_ptr);
+ if (!m->string)
+ log_fatal ("map_static_strings failed: %s\n", strerror (errno));
+
+ gpgrt_annotate_leaked_object (m->string);
+ gpgrt_annotate_leaked_object (m);
+
+ m->next = intmappings;
+ intmappings = m;
+ return m->string;
+}
diff --git a/common/stringhelp.c b/common/stringhelp.c
index c9e10800d..3e56d664d 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -1169,9 +1169,10 @@ try_percent_escape (const char *str, const char *extra)
}
-
-static char *
-do_strconcat (const char *s1, va_list arg_ptr)
+/* Same as strconcat but takes a va_list. Returns EINVAL if the list
+ * is too long, all other errors are due to an ENOMEM condition. */
+char *
+vstrconcat (const char *s1, va_list arg_ptr)
{
const char *argv[48];
size_t argc;
@@ -1216,7 +1217,7 @@ strconcat (const char *s1, ...)
else
{
va_start (arg_ptr, s1);
- result = do_strconcat (s1, arg_ptr);
+ result = vstrconcat (s1, arg_ptr);
va_end (arg_ptr);
}
return result;
@@ -1235,7 +1236,7 @@ xstrconcat (const char *s1, ...)
else
{
va_start (arg_ptr, s1);
- result = do_strconcat (s1, arg_ptr);
+ result = vstrconcat (s1, arg_ptr);
va_end (arg_ptr);
}
if (!result)
diff --git a/common/stringhelp.h b/common/stringhelp.h
index cd874af2e..915b3aa72 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -141,9 +141,12 @@ char *try_percent_escape (const char *str, const char *extra);
NULL. Returns a malloced buffer with the new string or NULL on a
malloc error or if too many arguments are given. */
char *strconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
+/* Same but taking a va_list. */
+char *vstrconcat (const char *s1, va_list arg_ptr);
/* Ditto, but die on error. */
char *xstrconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0);
+
char **strsplit (char *string, char delim, char replacement, int *count);
/* Tokenize STRING using the set of delimiters in DELIM. */
@@ -172,5 +175,7 @@ char *substitute_envvars (const char *string);
/*-- mapstrings.c --*/
const char *map_static_macro_string (const char *string);
+const char *map_static_strings (const char *domain, int key1, int key2,
+ const char *string1, ...);
#endif /*GNUPG_COMMON_STRINGHELP_H*/
diff --git a/common/t-mapstrings.c b/common/t-mapstrings.c
index 0856c3cc4..7dc622177 100644
--- a/common/t-mapstrings.c
+++ b/common/t-mapstrings.c
@@ -88,6 +88,31 @@ test_map_static_macro_string (void)
}
+static void
+test_map_static_strings (void)
+{
+ const char *s, *s1;
+
+ s1 = map_static_strings ("mydomain", 0, 42,
+ "This", " ", "is", " ", "my"," ","string", NULL);
+ if (strcmp (s1, "This is my string"))
+ fail (1);
+ s = map_static_strings ("mydomain", 0, 42,
+ "This", " ", "is", " ", "my"," ","string", NULL);
+ if (strcmp (s1, s))
+ fail (2);
+ s = map_static_strings ("mydomain", 0, 42, "foo", NULL);
+ if (strcmp (s1, s))
+ fail (3);
+ s = map_static_strings ("mydomain", 1, 42, "foo 1.42", NULL);
+ if (!strcmp (s1, s))
+ fail (4);
+ s = map_static_strings ("xdomain", 1, 42, "foo 1.42 other domain", NULL);
+ if (!strcmp (s1, s))
+ fail (5);
+}
+
+
int
main (int argc, char **argv)
{
@@ -95,6 +120,7 @@ main (int argc, char **argv)
(void)argv;
test_map_static_macro_string ();
+ test_map_static_strings ();
return 0;
}