forked from enlightenment/enlightenment
Fix various invalid memory access problems with _e_editable_text_insert
Patch by Helder Ribeiro: Hi people, I found a couple errors in the function _e_editable_text_insert. - when copying from the old string (n bytes) to the new one (m > n bytes) it was writing garbage into the new one (copying m bytes from old); - when memsetting the old string with 0's (part of extra security measure for password entry) it was writing m 0's into old, therefore writing past old's boundary, into unreserved memory; - a couple checks for NULL were missing. SVN revision: 35911
This commit is contained in:
parent
18966c828b
commit
23d69e088b
|
@ -876,7 +876,8 @@ static int
|
||||||
_e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
|
_e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
|
||||||
{
|
{
|
||||||
E_Editable_Smart_Data *sd;
|
E_Editable_Smart_Data *sd;
|
||||||
int char_length, unicode_length, prev_length;
|
int char_length, unicode_length;
|
||||||
|
int prev_char_length, new_char_length, new_unicode_length;
|
||||||
int index;
|
int index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -901,35 +902,48 @@ _e_editable_text_insert(Evas_Object *editable, int pos, const char *text)
|
||||||
index = 0;
|
index = 0;
|
||||||
for (i = 0; i < pos; i++)
|
for (i = 0; i < pos; i++)
|
||||||
index = evas_string_char_next_get(sd->text, index, NULL);
|
index = evas_string_char_next_get(sd->text, index, NULL);
|
||||||
|
|
||||||
if ((unicode_length <= 0) || (char_length <= 0))
|
if ((unicode_length <= 0) || (char_length <= 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
prev_length = sd->char_length;
|
prev_char_length = sd->char_length;
|
||||||
sd->char_length += char_length;
|
new_char_length = sd->char_length + char_length;
|
||||||
sd->unicode_length += unicode_length;
|
new_unicode_length = sd->unicode_length + unicode_length;
|
||||||
|
|
||||||
if (sd->char_length > sd->allocated_length)
|
if (new_char_length > sd->allocated_length)
|
||||||
{
|
{
|
||||||
|
int new_allocated_length = E_EDITABLE_SIZE_TO_ALLOC(new_char_length);
|
||||||
|
char *old = sd->text;
|
||||||
|
|
||||||
if (sd->password_mode)
|
if (sd->password_mode)
|
||||||
{
|
{
|
||||||
/* security -- copy contents into new buffer, and overwrite old contents */
|
/* security -- copy contents into new buffer, and overwrite old contents */
|
||||||
char *old = sd->text;
|
sd->text = malloc(new_allocated_length + 1);
|
||||||
sd->text = malloc(E_EDITABLE_SIZE_TO_ALLOC(sd->char_length) + 1);
|
if (!sd->text)
|
||||||
memcpy(sd->text, old, sd->char_length + 1);
|
{
|
||||||
memset(old, 0, sd->char_length);
|
sd->text = old;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(sd->text, old, prev_char_length + 1);
|
||||||
|
memset(old, 0, prev_char_length);
|
||||||
free(old);
|
free(old);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sd->text = realloc(sd->text,
|
sd->text = realloc(sd->text, new_allocated_length + 1);
|
||||||
E_EDITABLE_SIZE_TO_ALLOC(sd->char_length) + 1);
|
if (!sd->text)
|
||||||
|
{
|
||||||
|
sd->text = old;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sd->allocated_length = E_EDITABLE_SIZE_TO_ALLOC(sd->char_length);
|
sd->unicode_length = new_unicode_length;
|
||||||
|
sd->char_length = new_char_length;
|
||||||
|
sd->allocated_length = new_allocated_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_length > index)
|
if (prev_char_length > index)
|
||||||
memmove(&sd->text[index + char_length], &sd->text[index], prev_length - index);
|
memmove(&sd->text[index + char_length], &sd->text[index], prev_char_length - index);
|
||||||
strncpy(&sd->text[index], text, char_length);
|
strncpy(&sd->text[index], text, char_length);
|
||||||
sd->text[sd->char_length] = '\0';
|
sd->text[sd->char_length] = '\0';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue