Skip to content

Commit

Permalink
Delete whole utf8 character on backspace
Browse files Browse the repository at this point in the history
...rather than just the last byte of the password buffer.

Demostrate the need for this by taking the following steps:
- Apply the patch below (before this commit).
- Set keyboard layout to one where utf8 characters longer than one byte
  can be obtained, for example åäö using Swedish layout
  (XKB_DEFAULT_LAYOUT=se).
- Type "åäö" then press backspace and observe that it takes two
  backspaces to delete each character fully, and therefore six
  backspaces to fully clear the password buffer.

diff --git a/password.c b/password.c
index e1a1d9a..b640cd3 100644
--- a/password.c
+++ b/password.c
@@ -29,6 +29,7 @@ void clear_password_buffer(struct swaylock_password *pw) {
 static bool backspace(struct swaylock_password *pw) {
 	if (pw->len != 0) {
 		pw->buffer[--pw->len] = 0;
+		fprintf(stderr, "%s\n", pw->buffer);
 		return true;
 	}
 	return false;
  • Loading branch information
johanmalm authored and emersion committed Mar 22, 2022
1 parent 06d22a8 commit 11030b7
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
8 changes: 8 additions & 0 deletions include/unicode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

#define UTF8_INVALID 0x80

/**
* Gets the size in bytes of the last utf8 character in a NULL terminated string
* This function does not validate that the buffer contains correct utf8 data;
* it merely looks for the first byte that correctly denotes the beginning of a
* utf8 character.
*/
int utf8_last_size(const char *str);

/**
* Grabs the next UTF-8 character and advances the string pointer
*/
Expand Down
3 changes: 2 additions & 1 deletion password.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ void clear_password_buffer(struct swaylock_password *pw) {

static bool backspace(struct swaylock_password *pw) {
if (pw->len != 0) {
pw->buffer[--pw->len] = 0;
pw->len -= utf8_last_size(pw->buffer);
pw->buffer[pw->len] = 0;
return true;
}
return false;
Expand Down
13 changes: 13 additions & 0 deletions unicode.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "unicode.h"

int utf8_last_size(const char *str) {
int len = 0;
char *pos = strchr(str, '\0');
while (pos > str) {
--pos; ++len;
if ((*pos & 0xc0) != 0x80) {
return len;
}
}
return 0;
}

size_t utf8_chsize(uint32_t ch) {
if (ch < 0x80) {
return 1;
Expand Down

0 comments on commit 11030b7

Please sign in to comment.