Delete whole utf8 character on backspace

...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;
This commit is contained in:
Johan Malm 2022-03-20 20:59:17 +00:00 committed by Simon Ser
parent 06d22a8dea
commit 11030b7350
3 changed files with 23 additions and 1 deletions

View File

@ -9,6 +9,14 @@
#define UTF8_INVALID 0x80 #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 * Grabs the next UTF-8 character and advances the string pointer
*/ */

View File

@ -28,7 +28,8 @@ void clear_password_buffer(struct swaylock_password *pw) {
static bool backspace(struct swaylock_password *pw) { static bool backspace(struct swaylock_password *pw) {
if (pw->len != 0) { if (pw->len != 0) {
pw->buffer[--pw->len] = 0; pw->len -= utf8_last_size(pw->buffer);
pw->buffer[pw->len] = 0;
return true; return true;
} }
return false; return false;

View File

@ -1,7 +1,20 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <string.h>
#include "unicode.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) { size_t utf8_chsize(uint32_t ch) {
if (ch < 0x80) { if (ch < 0x80) {
return 1; return 1;