Merge lp:~csurbhi/ubuntu/natty/plymouth/plymouth.bug-fix566818 into lp:ubuntu/natty/plymouth

Proposed by Surbhi Palande
Status: Merged
Merge reported by: Steve Langasek
Merged at revision: not available
Proposed branch: lp:~csurbhi/ubuntu/natty/plymouth/plymouth.bug-fix566818
Merge into: lp:ubuntu/natty/plymouth
Diff against target: 158 lines (+105/-5)
5 files modified
debian/changelog (+12/-0)
debian/patches/details_removeSeparator.patch (+17/-0)
debian/patches/series (+2/-0)
debian/patches/ubuntu_details.patch (+47/-0)
src/plugins/splash/details/plugin.c (+27/-5)
To merge this branch: bzr merge lp:~csurbhi/ubuntu/natty/plymouth/plymouth.bug-fix566818
Reviewer Review Type Date Requested Status
Steve Langasek Needs Fixing
Ubuntu branches Pending
Review via email: mp+58131@code.launchpad.net

Description of the change

At boot the user passsword for a crypted device is captured by plymouth when it is available. By default the "details" plugin is used in text based logins. On every key stroke, the "details" plugin in plymouth clears only the current line before overwriting it with the password prompt. If the prompt is multilined then the last line ends up being overwritten but the previous lines are repeated. Reprinting only the last line of the password prompt string on every key press.

Tested on kvm.

Please consider this change for natty.

To post a comment you must log in.
Revision history for this message
Surbhi Palande (csurbhi) wrote :

Following are some details of the patch:
1) The patch prints the entire prompt the first time (i.e when number of bullets to be printed is zero). It prints only the last line when the user presses a key (i.e bullets > 0)

2) The patch removes the independent printing of ':' as this is included in the prompt. No other plugin prints the ':' separately. So it makes sense to remove it from here and add it to the default prompt or expect it in the user defined prompt (just like in other plugins)

Revision history for this message
Steve Langasek (vorlon) wrote :

Hi Surbhi,

+ * Returns the position of the last newline character.
+ * If the newline character is at the end of the string,
+ * it returns the previous newline character in the string
+ * if any.

Why backing up to the previous newline character? This seems to just result in additional special handling down the line when write_on_views() is called, and is inconsistent anyway with the current handling as it means the prompt will lose the final newline, and the bullets will be drawn on the same line as the prompt instead of on the line after it. (Do you have examples of such a prompt today that ends in a newline?) It wouldn't be good form to end the prompt with a newline, but I don't think the details plugin is the place to correct for this.

+ write_on_views (plugin,
+ prompt,
+ prompt[len-1] == '\n' ? len -1 : len);
+ } else
+ write_on_views (plugin,
+ prompt,
+ strlen (prompt));
+ }

If final newlines don't need special treatment (and I think they shouldn't), then we can reduce the code duplication here as well.

   else
     write_on_views (plugin,
- "Password",
- strlen ("Password"));
-
- write_on_views (plugin, ":", strlen (":"));
+ "Password:",
+ strlen ("Password:"));

This is a fix for the separate issue of a doubled ':' in the prompt, right? It would be best if this were called out separately - perhaps in a dep3 header in debian/patches/ubuntu_details.patch that explains what the patch is for. (No need to split this as a separate commit or go into great detail in the changelog, but it should be documented somewhere so that it's clear this isn't an accidental change.)

review: Needs Fixing
Revision history for this message
Surbhi Palande (csurbhi) wrote :

Hi Steve,

Thanks a lot for reviewing the code. Here is what I thought:

1) If the prompt accidentally ends in a "\n" (which ideally it should not and I dont have an example thankfully to show this :), but if it does anyway), then the repetition of the prompt wont be fixed. Every other plugin can handle the case where there is a "\n" at the end except for the details plugin. So not printing the last character -'\n' in this special (probably a never should happen) is to prevent the case where a prompt does not appear and bullets get repeated. This will be very difficult for someone to debug - very non intuitive:
Eg: prompt: "Enter \n passphrase \n"

What gets printed is:
Enter
passphrase:
* (on next keystroke this is then cleared and \n is printed)
** (on next keystroke this is then cleared and \n is printed)
***
and so on!

Removing the last '\n' would rather print:
Enter
passphrase: ***

Please do let me know what you think!
I will make a separate patch of the ':'. Indeed that will be better to comprehend.

Revision history for this message
Steve Langasek (vorlon) wrote :

On Tue, Apr 19, 2011 at 08:08:28AM -0000, Surbhi Palande wrote:

> Thanks a lot for reviewing the code. Here is what I thought:

> 1) If the prompt accidentally ends in a "\n" (which ideally it should not
> and I dont have an example thankfully to show this :), but if it does
> anyway), then the repetition of the prompt wont be fixed. Every other
> plugin can handle the case where there is a "\n" at the end except for the
> details plugin. So not printing the last character -'\n' in this special
> (probably a never should happen) is to prevent the case where a prompt
> does not appear and bullets get repeated. This will be very difficult for
> someone to debug - very non intuitive: Eg: prompt: "Enter \n passphrase
> \n"

> What gets printed is:
> Enter
> passphrase:
> * (on next keystroke this is then cleared and \n is printed)
> ** (on next keystroke this is then cleared and \n is printed)
> ***
> and so on!

> Removing the last '\n' would rather print:
> Enter
> passphrase: ***

> Please do let me know what you think!

My understanding of the code is that the prompt is only shortened when
bullets > 0. So since we start out with 0 bullets, first you would have
this:

Enter
passphrase
_

Then because we're printing the part of the prompt between the
second-to-last and last newlines, typing a letter would refresh this to:

Enter
passphrase
passphrase *_

If we always cut everything up to and including the last \n, we instead get
an empty prompt when redrawing. And that's ok; given a confusingly
newline-terminated prompt, that's still probably better, as it gives us
this:

Enter
passphrase
***_

So I stand by my recommendation to not special-case a prompt that ends in a
newline.

> I will make a separate patch of the ':'. Indeed that will be better to
> comprehend.

Ok!

--
Steve Langasek Give me a lever long enough and a Free OS
Debian Developer to set it on, and I can move the world.
Ubuntu Developer http://www.debian.org/
<email address hidden> <email address hidden>

Revision history for this message
Surbhi Palande (csurbhi) wrote :

Yes, if we keep the last_nl pointing to the second to last '\n' as it does right now then yes, thats correct: the second line will be repeated over and over again - but then that has a simple fix too - by changing the prompt without the last '\n'.

Ok! I will rewrite the patch and upload here! Thanks!

Revision history for this message
Surbhi Palande (csurbhi) wrote :

So: the shorten_prompt() needs to be kept the way it is right now: by returning the second to the last '\n' in case the '\n' is the last character - to get a non empty prompt. I was assuming that needed to be changed to return the last '\n' (in which case we will get an empty string and a '\n' for every key stroke). Roughly speaking, I will change the part:
write_on_views (plugin,
+ prompt,
+ prompt[len-1] == '\n' ? len -1 : len);

to

write_on_views (plugin,
+ prompt,
+ len);

Revision history for this message
Surbhi Palande (csurbhi) wrote :

Hi Steve,

I have pushed the changes requested. Please do have a look! Thanks!

Regards,
Surbhi.

Revision history for this message
Steve Langasek (vorlon) wrote :

@@ -363,16 +384,16 @@
                     strlen (CLEAR_LINE_SEQUENCE));
   plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;

- if (prompt)
+ if (prompt) {
+ shorten_prompt(&prompt);
     write_on_views (plugin,
                     prompt,
                     strlen (prompt));
+ }
   else

This seems to drop the special handling of the bullets == 0 case. Sorry if my comments were unclear, I do believe that we still need to handle that case specially. Testing with the patch as-is, I never see the first line of the cryptsetup prompt.

review: Needs Fixing
1392. By Surbhi Palande

* details/plugin.c: On every key stroke, the "details" plugin in plymouth
  clears only the current line before overwriting it with the password
  prompt. If the prompt is multilined then the last line ends up being
  overwritten but the previous lines are repeated. Re-printing only the
  last line of the password prompt on every keystroke. (LP:#566818)
* details/plugin.c: Removed the explicit printing of ':'. Expected to be a
  part of the prompt.

Revision history for this message
Surbhi Palande (csurbhi) wrote :

Steve, I have added a tested patch now. Sorry for the re-reviews!

Regards,
Surbhi.

Revision history for this message
Steve Langasek (vorlon) wrote :

Thanks, merged and pushed! Unfortunately due to freeze timing, this is now going to be an SRU rather than included in the natty release pocket; I've still merged it to the 'natty' branch since that's the only available branch for pushing.

BTW, I had to refresh the patches to apply cleanly against the current plymouth source. With dpkg 3.0 (quilt) format, dpkg-source requires the patches to apply with no fuzz.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2011-04-15 13:37:15 +0000
3+++ debian/changelog 2011-04-21 07:09:09 +0000
4@@ -1,3 +1,15 @@
5+plymouth (0.8.2-2ubuntu23) natty; urgency=low
6+
7+ * details/plugin.c: On every key stroke, the "details" plugin in plymouth
8+ clears only the current line before overwriting it with the password
9+ prompt. If the prompt is multilined then the last line ends up being
10+ overwritten but the previous lines are repeated. Re-printing only the
11+ last line of the password prompt on every keystroke. (LP:#566818)
12+ * details/plugin.c: Removed the explicit printing of ':'. Expected to be a
13+ part of the prompt.
14+
15+ -- Surbhi Palande <surbhi.palande@canonical.com> Thu, 21 Apr 2011 09:54:07 +0300
16+
17 plymouth (0.8.2-2ubuntu22) natty; urgency=low
18
19 * Install slave alternative for plymouth-theme-ubuntu-logo, telling GRUB
20
21=== added file 'debian/patches/details_removeSeparator.patch'
22--- debian/patches/details_removeSeparator.patch 1970-01-01 00:00:00 +0000
23+++ debian/patches/details_removeSeparator.patch 2011-04-21 07:09:09 +0000
24@@ -0,0 +1,17 @@
25+Index: b/src/plugins/splash/details/plugin.c
26+===================================================================
27+--- a/src/plugins/splash/details/plugin.c
28++++ b/src/plugins/splash/details/plugin.c
29+@@ -393,10 +393,8 @@
30+ }
31+ else
32+ write_on_views (plugin,
33+- "Password",
34+- strlen ("Password"));
35+-
36+- write_on_views (plugin, ":", strlen (":"));
37++ "Password:",
38++ strlen ("Password:"));
39+
40+ for (i = 0; i < bullets; i++)
41+ write_on_views (plugin, "*", strlen ("*"));
42
43=== modified file 'debian/patches/series'
44--- debian/patches/series 2011-03-24 12:01:21 +0000
45+++ debian/patches/series 2011-04-21 07:09:09 +0000
46@@ -1,3 +1,5 @@
47+ubuntu_details.patch
48+details_removeSeparator.patch
49 misc-changes.patch
50 vga16fb-renderer.patch
51 lbm-nouveau.patch
52
53=== added file 'debian/patches/ubuntu_details.patch'
54--- debian/patches/ubuntu_details.patch 1970-01-01 00:00:00 +0000
55+++ debian/patches/ubuntu_details.patch 2011-04-21 07:09:09 +0000
56@@ -0,0 +1,47 @@
57+Index: b/src/plugins/splash/details/plugin.c
58+===================================================================
59+--- a/src/plugins/splash/details/plugin.c
60++++ b/src/plugins/splash/details/plugin.c
61+@@ -349,6 +349,27 @@
62+ }
63+ }
64+
65++/* @shorten_prompt:
66++ *
67++ * Points prompt to the character immediately after the
68++ * last '\n' in prompt
69++ */
70++static void shorten_prompt(const char ** prompt)
71++{
72++ int last_nl=-1, i=0;
73++ const char * str = *prompt;
74++ for(i=0; str[i] != '\0'; i++) {
75++ if(str[i] == '\n') {
76++ last_nl = i;
77++ }
78++ }
79++ if (last_nl >= 0) {
80++ if((str[last_nl] == '\n') && (last_nl < i)){
81++ *prompt = &str[last_nl + 1];
82++ }
83++ }
84++}
85++
86+ static void
87+ display_password (ply_boot_splash_plugin_t *plugin,
88+ const char *prompt,
89+@@ -363,10 +384,13 @@
90+ strlen (CLEAR_LINE_SEQUENCE));
91+ plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
92+
93+- if (prompt)
94++ if (prompt) {
95++ if (bullets > 0)
96++ shorten_prompt(&prompt);
97+ write_on_views (plugin,
98+ prompt,
99+ strlen (prompt));
100++ }
101+ else
102+ write_on_views (plugin,
103+ "Password",
104
105=== modified file 'src/plugins/splash/details/plugin.c'
106--- src/plugins/splash/details/plugin.c 2010-09-08 09:10:15 +0000
107+++ src/plugins/splash/details/plugin.c 2011-04-21 07:09:09 +0000
108@@ -349,6 +349,27 @@
109 }
110 }
111
112+/* @shorten_prompt:
113+ *
114+ * Points prompt to the character immediately after the
115+ * last '\n' in prompt
116+ */
117+static void shorten_prompt(const char ** prompt)
118+{
119+ int last_nl=-1, i=0;
120+ const char * str = *prompt;
121+ for(i=0; str[i] != '\0'; i++) {
122+ if(str[i] == '\n') {
123+ last_nl = i;
124+ }
125+ }
126+ if (last_nl >= 0) {
127+ if((str[last_nl] == '\n') && (last_nl < i)){
128+ *prompt = &str[last_nl + 1];
129+ }
130+ }
131+}
132+
133 static void
134 display_password (ply_boot_splash_plugin_t *plugin,
135 const char *prompt,
136@@ -363,16 +384,17 @@
137 strlen (CLEAR_LINE_SEQUENCE));
138 plugin->state = PLY_BOOT_SPLASH_DISPLAY_PASSWORD_ENTRY;
139
140- if (prompt)
141+ if (prompt) {
142+ if (bullets > 0)
143+ shorten_prompt(&prompt);
144 write_on_views (plugin,
145 prompt,
146 strlen (prompt));
147+ }
148 else
149 write_on_views (plugin,
150- "Password",
151- strlen ("Password"));
152-
153- write_on_views (plugin, ":", strlen (":"));
154+ "Password:",
155+ strlen ("Password:"));
156
157 for (i = 0; i < bullets; i++)
158 write_on_views (plugin, "*", strlen ("*"));

Subscribers

People subscribed via source and target branches