[Pkg-gnupg-commit] [gnupg2] 168/241: gpg: Reflow long texts.
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed Dec 9 20:32:12 UTC 2015
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit 19362a8dd7ee986c082a5afc5a446f939991ec0f
Author: Neal H. Walfield <neal at g10code.com>
Date: Mon Nov 23 22:20:28 2015 +0100
gpg: Reflow long texts.
* common/stringhelp.c (format_text): New function.
* common/t-stringhelp.c (stresc): New function.
(test_format_text): New function. Test format_text.
* g10/tofu.c (get_trust): Use format_text to reflow long texts.
(show_statistics): Likewise.
--
Signed-off-by: Neal H. Walfield <neal at g10code.com>
---
common/stringhelp.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
common/stringhelp.h | 5 ++
common/t-stringhelp.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++
g10/tofu.c | 16 ++++--
4 files changed, 283 insertions(+), 4 deletions(-)
diff --git a/common/stringhelp.c b/common/stringhelp.c
index d0b5561..6748d1e 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -1327,3 +1327,132 @@ strtokenize (const char *string, const char *delim)
return result;
}
+
+char *
+format_text (char *text, int in_place, int target_cols, int max_cols)
+{
+ const int do_debug = 0;
+
+ /* The character under consideration. */
+ char *p;
+ /* The start of the current line. */
+ char *line;
+ /* The last space that we saw. */
+ char *last_space = NULL;
+ int last_space_cols = 0;
+ int copied_last_space = 0;
+
+ if (! in_place)
+ text = xstrdup (text);
+
+ p = line = text;
+ while (1)
+ {
+ /* The number of columns including any trailing space. */
+ int cols;
+
+ p = p + strcspn (p, "\n ");
+ if (! p)
+ /* P now points to the NUL character. */
+ p = &text[strlen (text)];
+
+ if (*p == '\n')
+ /* Pass through any newlines. */
+ {
+ p ++;
+ line = p;
+ last_space = NULL;
+ last_space_cols = 0;
+ copied_last_space = 1;
+ continue;
+ }
+
+ /* Have a space or a NUL. Note: we don't count the trailing
+ space. */
+ cols = utf8_charcount (line, (uintptr_t) p - (uintptr_t) line);
+ if (cols < target_cols)
+ {
+ if (! *p)
+ /* Nothing left to break. */
+ break;
+
+ last_space = p;
+ last_space_cols = cols;
+ p ++;
+ /* Skip any immediately following spaces. If we break:
+ "... foo bar ..." between "foo" and "bar" then we want:
+ "... foo\nbar ...", which means that the left space has
+ to be the first space after foo, not the last space
+ before bar. */
+ while (*p == ' ')
+ p ++;
+ }
+ else
+ {
+ int cols_with_left_space;
+ int cols_with_right_space;
+ int left_penalty;
+ int right_penalty;
+
+ cols_with_left_space = last_space_cols;
+ cols_with_right_space = cols;
+
+ if (do_debug)
+ log_debug ("Breaking: '%.*s'\n",
+ (int) ((uintptr_t) p - (uintptr_t) line), line);
+
+ /* The number of columns away from TARGET_COLS. We prefer
+ to underflow than to overflow. */
+ left_penalty = target_cols - cols_with_left_space;
+ right_penalty = 2 * (cols_with_right_space - target_cols);
+
+ if (cols_with_right_space > max_cols)
+ /* Add a large penalty for each column that exceeds
+ max_cols. */
+ right_penalty += 4 * (cols_with_right_space - max_cols);
+
+ if (do_debug)
+ log_debug ("Left space => %d cols (penalty: %d); right space => %d cols (penalty: %d)\n",
+ cols_with_left_space, left_penalty,
+ cols_with_right_space, right_penalty);
+ if (last_space_cols && left_penalty <= right_penalty)
+ /* Prefer the left space. */
+ {
+ if (do_debug)
+ log_debug ("Breaking at left space.\n");
+ p = last_space;
+ }
+ else
+ {
+ if (do_debug)
+ log_debug ("Breaking at right space.\n");
+ }
+
+ if (! *p)
+ break;
+
+ *p = '\n';
+ p ++;
+ if (*p == ' ')
+ {
+ int spaces;
+ for (spaces = 1; p[spaces] == ' '; spaces ++)
+ ;
+ memmove (p, &p[spaces], strlen (&p[spaces]) + 1);
+ }
+ line = p;
+ last_space = NULL;
+ last_space_cols = 0;
+ copied_last_space = 0;
+ }
+ }
+
+ /* Chop off any trailing space. */
+ while (text[strlen (text) - 1] == ' ')
+ text[strlen (text) - 1] = '\0';
+ /* If we inserted the trailing newline, then remove it. */
+ if (! copied_last_space && text[strlen (text) - 1] == '\n')
+ text[strlen (text) - 1] = '\0';
+
+ return text;
+}
diff --git a/common/stringhelp.h b/common/stringhelp.h
index b34d28b..9ff062b 100644
--- a/common/stringhelp.h
+++ b/common/stringhelp.h
@@ -148,6 +148,11 @@ char **strsplit (char *string, char delim, char replacement, int *count);
/* Tokenize STRING using the set of delimiters in DELIM. */
char **strtokenize (const char *string, const char *delim);
+/* Format a string so that it fits within about TARGET_COLS columns.
+ If IN_PLACE is 0, then TEXT is copied to a new buffer, which is
+ returned. Otherwise, TEXT is modified in place and returned.
+ Normally, target_cols will be 72 and max_cols is 80. */
+char *format_text (char *text, int in_place, int target_cols, int max_cols);
/*-- mapstrings.c --*/
const char *map_static_macro_string (const char *string);
diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c
index 13f3afa..9e5410b 100644
--- a/common/t-stringhelp.c
+++ b/common/t-stringhelp.c
@@ -677,6 +677,142 @@ test_strtokenize (void)
}
}
+static char *
+stresc (char *s)
+{
+ char *p;
+ int l = strlen (s) + 1;
+
+ for (p = s; *p; p ++)
+ if (*p == '\n')
+ l ++;
+
+ p = xmalloc (l);
+ for (l = 0; *s; s ++, l ++)
+ {
+ if (*s == ' ')
+ p[l] = '_';
+ else if (*p == '\n')
+ {
+ p[l ++] = '\\';
+ p[l ++] = 'n';
+ p[l] = '\n';
+ }
+ else
+ p[l] = *s;
+ }
+ p[l] = *s;
+
+ return p;
+}
+
+static void
+test_format_text (void)
+{
+ struct test
+ {
+ int target_cols, max_cols;
+ char *input;
+ char *expected;
+ };
+
+ struct test tests[] = {
+ {
+ 10, 12,
+ "",
+ "",
+ },
+ {
+ 10, 12,
+ " ",
+ "",
+ },
+ {
+ 10, 12,
+ " ",
+ "",
+ },
+ {
+ 10, 12,
+ " \n ",
+ " \n",
+ },
+ {
+ 10, 12,
+ " \n \n ",
+ " \n \n",
+ },
+ {
+ 10, 12,
+ "0123456789 0123456789 0",
+ "0123456789\n0123456789\n0",
+ },
+ {
+ 10, 12,
+ " 0123456789 0123456789 0 ",
+ " 0123456789\n0123456789\n0",
+ },
+ {
+ 10, 12,
+ "01 34 67 90 23 56 89 12 45 67 89 1",
+ "01 34 67\n90 23 56\n89 12 45\n67 89 1"
+ },
+ {
+ 10, 12,
+ "01 34 67 90 23 56 89 12 45 67 89 1",
+ "01 34 67\n90 23 56\n89 12 45\n67 89 1"
+ },
+ {
+ 72, 80,
+ "Warning: if you think you've seen more than 10 messages "
+ "signed by this key, then this key might be a forgery! "
+ "Carefully examine the email address for small variations "
+ "(e.g., additional white space). If the key is suspect, "
+ "then use 'gpg --tofu-policy bad \"FINGERPRINT\"' to mark it as being bad.\n",
+ "Warning: if you think you've seen more than 10 messages signed by this\n"
+ "key, then this key might be a forgery! Carefully examine the email\n"
+ "address for small variations (e.g., additional white space). If the key\n"
+ "is suspect, then use 'gpg --tofu-policy bad \"FINGERPRINT\"' to mark it as\n"
+ "being bad.\n"
+
+ },
+ {
+ 72, 80,
+ "Normally, there is only a single key associated with an email "
+ "address. However, people sometimes generate a new key if "
+ "their key is too old or they think it might be compromised. "
+ "Alternatively, a new key may indicate a man-in-the-middle "
+ "attack! Before accepting this key, you should talk to or "
+ "call the person to make sure this new key is legitimate.",
+ "Normally, there is only a single key associated with an email "
+ "address.\nHowever, people sometimes generate a new key if "
+ "their key is too old or\nthey think it might be compromised. "
+ "Alternatively, a new key may indicate\na man-in-the-middle "
+ "attack! Before accepting this key, you should talk\nto or "
+ "call the person to make sure this new key is legitimate.",
+ }
+ };
+
+ int i;
+ int failed = 0;
+
+ for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i ++)
+ {
+ struct test *test = &tests[i];
+ char *result =
+ format_text (test->input, 0, test->target_cols, test->max_cols);
+ if (strcmp (result, test->expected) != 0)
+ {
+ printf ("%s: Test #%d failed.\nExpected: '%s'\nResult: '%s'\n",
+ __func__, i + 1, stresc (test->expected), stresc (result));
+ failed ++;
+ }
+ xfree (result);
+ }
+
+ if (failed)
+ fail(0);
+}
int
main (int argc, char **argv)
@@ -692,6 +828,7 @@ main (int argc, char **argv)
test_make_absfilename_try ();
test_strsplit ();
test_strtokenize ();
+ test_format_text ();
xfree (home_buffer);
return 0;
diff --git a/g10/tofu.c b/g10/tofu.c
index 5e38d21..d340bfe 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -2038,7 +2038,9 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
"Alternatively, a new key may indicate a man-in-the-middle "
"attack! Before accepting this key, you should talk to or "
"call the person to make sure this new key is legitimate.";
+ text = format_text (text, 0, 72, 80);
es_fprintf (fp, "\n%s\n", text);
+ xfree (text);
}
es_fputc ('\n', fp);
@@ -2440,7 +2442,8 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
if (policy == TOFU_POLICY_AUTO && messages < 10)
{
char *set_policy_command;
- const char *text;
+ char *text;
+ char *tmp;
if (messages == 0)
log_info (_("Warning: we've have yet to see"
@@ -2462,9 +2465,14 @@ show_statistics (struct dbs *dbs, const char *fingerprint,
"Carefully examine the email address for small variations "
"(e.g., additional white space). If the key is suspect, "
"then use '%s' to mark it as being bad.\n";
- log_info (text,
- messages, messages == 1 ? _("message") : _("message"),
- set_policy_command);
+ tmp = xasprintf
+ (text,
+ messages, messages == 1 ? _("message") : _("message"),
+ set_policy_command);
+ text = format_text (tmp, 0, 72, 80);
+ xfree (tmp);
+ log_info ("%s", text);
+ xfree (text);
free (set_policy_command);
}
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list