[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51658] trunk/blender/source/blender: * New string property subtype: PASSWORD

Jiri Hnidek jiri.hnidek at tul.cz
Fri Oct 26 14:58:54 CEST 2012


Revision: 51658
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51658
Author:   jiri
Date:     2012-10-26 12:58:54 +0000 (Fri, 26 Oct 2012)
Log Message:
-----------
* New string property subtype: PASSWORD

When this new subtypes is used, then string of property is hidden using
asterisks, e.g.: mysecretpassword -> ****************

This code was reviewed and modified by Brecht. Thanks very much:
 - https://codereview.appspot.com/6713044/

This new subtype of string property is intended mostly for Add-on developers
writing Add-on which communicates with some server (http, sql, ftp, verse,
etc.). When this server requires user authentication and user has to type
username and password, then current API didn't allow to type 'hidden' password,
e.g. when you want to demonstrate this script, then everybody can see this
security password. Some examples of Add-on which could use this new subtype:
 - On-line database of textures
 - Integration of render farm
 - Integration of Verse

Security Notes:
 - You can copy paste hiddent string of property from text input using (Ctrl-C, Ctrl-V),
but you can do this in other GUI toolkits too (this behavior it is widely used).
 - Text of string property is stored in plain text, but it is widely used in other
GUI toolkits (Qt, Gtk, etc.).

Simple examples:
 - https://dl.dropbox.com/u/369894/draw_op_passwd.py
 - https://dl.dropbox.com/u/369894/blender-password.png

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/BLI_string_utf8.h
    trunk/blender/source/blender/blenlib/intern/string_utf8.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h
    trunk/blender/source/blender/editors/interface/interface_widgets.c
    trunk/blender/source/blender/makesrna/RNA_types.h
    trunk/blender/source/blender/makesrna/intern/makesrna.c
    trunk/blender/source/blender/python/intern/bpy_props.c

Modified: trunk/blender/source/blender/blenlib/BLI_string_utf8.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_string_utf8.h	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/blenlib/BLI_string_utf8.h	2012-10-26 12:58:54 UTC (rev 51658)
@@ -49,7 +49,9 @@
 
 /* wchar_t functions, copied from blenders own font.c originally */
 size_t       BLI_wstrlen_utf8(const wchar_t *src);
+size_t       BLI_strlen_utf8_char(const char *strc);
 size_t       BLI_strlen_utf8(const char *strc);
+size_t       BLI_strlen_range_utf8(const char *start, const char *end);
 size_t       BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
 size_t       BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
 

Modified: trunk/blender/source/blender/blenlib/intern/string_utf8.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/string_utf8.c	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/blenlib/intern/string_utf8.c	2012-10-26 12:58:54 UTC (rev 51658)
@@ -231,29 +231,43 @@
 	return len;
 }
 
-// utf8slen
+/* size of UTF-8 character in bytes */
+size_t BLI_strlen_utf8_char(const char *strc)
+{
+	if ((*strc & 0xe0) == 0xc0) {
+		if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
+			return 2;
+	}
+	else if ((*strc & 0xf0) == 0xe0) {
+		if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
+			return 3;
+	}
+	else if ((*strc & 0xf8) == 0xf0) {
+		if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
+			return 4;
+	}
+
+	return 1;
+}
+
 size_t BLI_strlen_utf8(const char *strc)
 {
-	int len = 0;
+	int len;
 
-	while (*strc) {
-		if ((*strc & 0xe0) == 0xc0) {
-			if ((strc[1] & 0x80) && (strc[1] & 0x40) == 0x00)
-				strc++;
-		}
-		else if ((*strc & 0xf0) == 0xe0) {
-			if ((strc[1] & strc[2] & 0x80) && ((strc[1] | strc[2]) & 0x40) == 0x00)
-				strc += 2;
-		}
-		else if ((*strc & 0xf8) == 0xf0) {
-			if ((strc[1] & strc[2] & strc[3] & 0x80) && ((strc[1] | strc[2] | strc[3]) & 0x40) == 0x00)
-				strc += 3;
-		}
+	for (len = 0; *strc; len++)
+		strc += BLI_strlen_utf8_char(strc);
 
-		strc++;
-		len++;
-	}
+	return len;
+}
 
+size_t BLI_strlen_range_utf8(const char *start, const char *end)
+{
+	const char *strc = start;
+	int len;
+
+	for (len = 0; strc < end; len++)
+		strc += BLI_strlen_utf8_char(strc);
+
 	return len;
 }
 

Modified: trunk/blender/source/blender/editors/interface/interface_handlers.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_handlers.c	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/editors/interface/interface_handlers.c	2012-10-26 12:58:54 UTC (rev 51658)
@@ -1299,6 +1299,71 @@
 	}
 }
 
+/* ************************ password text ******************************
+ *
+ * Functions to convert password strings that should not be displayed
+ * to asterisk representation (e.g. mysecretpasswd -> *************)
+ *
+ * It converts every UTF-8 character to an asterisk, and also remaps
+ * the cursor position and selection start/end.
+ *
+ * Note: remaping is used, because password could contain UTF-8 characters.
+ *
+ */
+
+static int ui_text_position_from_hidden(uiBut *but, int pos)
+{
+	const char *strpos;
+	int i;
+
+	for (i = 0, strpos = but->drawstr; i < pos; i++)
+		strpos = BLI_str_find_next_char_utf8(strpos, NULL);
+	
+	return (strpos - but->drawstr);
+}
+
+static int ui_text_position_to_hidden(uiBut *but, int pos)
+{
+	return BLI_strlen_range_utf8(but->drawstr, but->drawstr + pos);
+}
+
+void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore)
+{
+	if (!(but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_PASSWORD))
+		return;
+
+	if (restore) {
+		/* restore original string */
+		BLI_strncpy(but->drawstr, password_str, UI_MAX_DRAW_STR);
+
+		/* remap cursor positions */
+		if(but->pos >= 0) {
+			but->pos = ui_text_position_from_hidden(but, but->pos);
+			but->selsta = ui_text_position_from_hidden(but, but->selsta);
+			but->selend = ui_text_position_from_hidden(but, but->selend);
+		}
+	}
+	else {
+		/* convert text to hidden test using asterisks (e.g. pass -> ****) */
+		int i, len = BLI_strlen_utf8(but->drawstr);
+
+		/* remap cursor positions */
+		if(but->pos >= 0) {
+			but->pos = ui_text_position_to_hidden(but, but->pos);
+			but->selsta = ui_text_position_to_hidden(but, but->selsta);
+			but->selend = ui_text_position_to_hidden(but, but->selend);
+		}
+
+		/* save original string */
+		BLI_strncpy(password_str, but->drawstr, UI_MAX_DRAW_STR);
+
+		for (i = 0; i < len; i++)
+			but->drawstr[i] = '*';
+		but->drawstr[i] = '\0';
+	}
+}
+
+
 /* ************* in-button text selection/editing ************* */
 
 
@@ -1322,13 +1387,15 @@
 	uiStyle *style = UI_GetStyle();  // XXX pass on as arg
 	uiFontStyle *fstyle = &style->widget;
 	int startx = but->rect.xmin;
-	char *origstr;
+	char *origstr, password_str[UI_MAX_DRAW_STR];
 
 	uiStyleFontSet(fstyle);
 
 	if (fstyle->kerning == 1) /* for BLF_width */
 		BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
 	
+	ui_button_text_password_hide(password_str, but, FALSE);
+
 	origstr = MEM_callocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
 	
 	BLI_strncpy(origstr, but->drawstr, data->maxlen);
@@ -1407,6 +1474,8 @@
 	if (fstyle->kerning == 1)
 		BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
 	
+	ui_button_text_password_hide(password_str, but, TRUE);
+
 	MEM_freeN(origstr);
 }
 

Modified: trunk/blender/source/blender/editors/interface/interface_intern.h
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_intern.h	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/editors/interface/interface_intern.h	2012-10-26 12:58:54 UTC (rev 51658)
@@ -160,7 +160,8 @@
 	int flag, drawflag;
 	eButType         type;
 	eButPointerType  pointype;
-	short bit, bitnr, retval, strwidth, ofs, pos, selsta, selend, alignnr;
+	short bit, bitnr, retval, strwidth, alignnr;
+	short ofs, pos, selsta, selend;
 
 	char *str;
 	char strdata[UI_MAX_NAME_STR];
@@ -484,6 +485,7 @@
 extern void ui_button_active_free(const struct bContext *C, uiBut *but);
 extern int ui_button_is_active(struct ARegion *ar);
 extern int ui_button_open_menu_direction(uiBut *but);
+extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, int restore);
 
 /* interface_widgets.c */
 void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);

Modified: trunk/blender/source/blender/editors/interface/interface_widgets.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_widgets.c	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/editors/interface/interface_widgets.c	2012-10-26 12:58:54 UTC (rev 51658)
@@ -1276,10 +1276,13 @@
 /* draws text and icons for buttons */
 static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
 {
-	if (but == NULL) {
+	char password_str[UI_MAX_DRAW_STR];
+
+	if (but == NULL)
 		return;
-	}
 
+	ui_button_text_password_hide(password_str, but, FALSE);
+
 	/* clip but->drawstr to fit in available space */
 	if (but->editstr && but->pos >= 0) {
 		ui_text_clip_cursor(fstyle, but, rect);
@@ -1337,6 +1340,8 @@
 		widget_draw_text(fstyle, wcol, but, rect);
 
 	}
+
+	ui_button_text_password_hide(password_str, but, TRUE);
 }
 
 

Modified: trunk/blender/source/blender/makesrna/RNA_types.h
===================================================================
--- trunk/blender/source/blender/makesrna/RNA_types.h	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/makesrna/RNA_types.h	2012-10-26 12:58:54 UTC (rev 51658)
@@ -113,6 +113,7 @@
 	PROP_BYTESTRING = 4, /* a string which should be represented as bytes
 	                      * in python, still NULL terminated though. */
 	PROP_TRANSLATE = 5, /* a string which should be translated */
+	PROP_PASSWORD = 6,	/* a string which should not be displayed in UI */
 
 	/* numbers */
 	PROP_UNSIGNED = 13,

Modified: trunk/blender/source/blender/makesrna/intern/makesrna.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/makesrna.c	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/makesrna/intern/makesrna.c	2012-10-26 12:58:54 UTC (rev 51658)
@@ -2345,6 +2345,7 @@
 		case PROP_COORDS: return "PROP_COORDS";
 		case PROP_LAYER: return "PROP_LAYER";
 		case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER";
+		case PROP_PASSWORD: return "PROP_PASSWORD";
 		default: {
 			/* in case we don't have a type preset that includes the subtype */
 			if (RNA_SUBTYPE_UNIT(type)) {

Modified: trunk/blender/source/blender/python/intern/bpy_props.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_props.c	2012-10-26 12:42:59 UTC (rev 51657)
+++ trunk/blender/source/blender/python/intern/bpy_props.c	2012-10-26 12:58:54 UTC (rev 51658)
@@ -78,6 +78,7 @@
 	{PROP_FILENAME, "FILENAME", 0, "Filename", ""},
 	{PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""},
 	{PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
+	{PROP_PASSWORD, "PASSWORD", 0, "Password", 0},
 
 	{PROP_NONE, "NONE", 0, "None", ""},
 	{0, NULL, 0, NULL, NULL}};




More information about the Bf-blender-cvs mailing list