diff options
author | Ali Alzyod <ali198724@gmail.com> | 2019-03-29 09:52:51 -0400 |
---|---|---|
committer | Mike Blumenkrantz <zmike@samsung.com> | 2019-03-29 09:58:53 -0400 |
commit | b8952604ce1921fbd44dad46c88de456abefe430 (patch) | |
tree | 5f95390cbec05e612c41bae72a87e27ee3941cb3 | |
parent | 76e8f9c07ca2e72c4bca489c1e0e48e695fe4394 (diff) | |
download | efl-b8952604ce1921fbd44dad46c88de456abefe430.tar.gz |
elm_entry: Speedup finding new line, prevent readind invalid memory
Summary:
1- Speed up detecting new lines.
```
if (!strncmp(text, "<br", 3) || !strncmp(text, "<ps", 3))
```
This will cause 6 comparisons (if one of conditions did not meet), or at least 3 comparisons.
this is changed to
```
if (!strncmp(text, "<", 1))
```
2- Speedup detecting lines
If this condition is true, we should increment the string for next iteration 3 times, not just one
```
if (!strncmp(text, "<br", 3) || !strncmp(text, "<ps", 3))
```
if '<' founded then 'pr' or 'br', we will skip 3 characters for next iteration.
```
if (!strncmp(text, "<", 1))
{
text++;
len--;
if (!strncmp(text, "br", 2) || !strncmp(text, "ps", 2))
{
text += 2;
len -= 2;
```
3- Prevent reading invalid memory out of the string
```
if (text[3] == '>' || ((text[3] == '/') && (text[4] == '>')))
```
string could reach last char in string (original string ends with "<br")
but now we will check if remaining string length allow comparison :
```
if (text[0] == '>' || (len > 1 && ((text[0] == '/') && (text[1] == '>'))))
```
Test Plan:
```
static int
oldFunc(const char *text)
{
if (!text)
return 0;
while (*text)
{
if (!strncmp(text, "<br", 3) || !strncmp(text, "<ps", 3))
{
if (text[3] == '>' || ((text[3] == '/') && (text[4] == '>')))
{
return 1;
}
}
text++;
}
return 0;
}
static int
newFunc(const char *text)
{
if (!text)
return 0;
char *pTemp = (char *)text;
while (pTemp = strchr(pTemp, '<'))
{
pTemp++;
if (!strncmp(pTemp, "br", 2) || !strncmp(pTemp, "ps", 2))
{
pTemp += 2;
if (pTemp[0] != '\0' && (pTemp[0] == '>' || (pTemp[0] == '/' && pTemp[1] == '>')))
{
return 1;
}
}
}
return 0;
}
int main()
{
int counter = 1000;
srand(time(NULL));
char pStr[50001] = {0};
char AllChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<>";
int AllCharsLen = strlen(AllChars);
for (int i = 0; i < 50000; i++)
pStr[i] = AllChars[rand() % AllCharsLen];
clock_t start, end;
double total_Time1 = 0;
int i;
for (int j = 0; j < 3; j++)
{
if (j == 0)
{
printf("random String\n");
}
else if (j == 1)
{
printf("With Random <br/>\n");
int location = rand()%(5000 - 5);
pStr[location++] = '<';
pStr[location++] = 'b';
pStr[location++] = 'r';
pStr[location++] = '/';
pStr[location++] = '>';
}
else if (j == 2)
{
printf("With Random <ps>\n");
int location = rand()%(5000 - 4);
pStr[location++] = '<';
pStr[location++] = 'p';
pStr[location++] = 's';
pStr[location++] = '>';
}
start = clock();
for (i = 0; i < counter; i++)
oldFunc(pStr);
end = clock();
total_Time1 = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("original = %f has new Line = %i\n", total_Time1, oldFunc(pStr));
start = clock();
for (i = 0; i < counter; i++)
newFunc(pStr);
end = clock();
total_Time1 = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("modified = %f has new line = %i\n\n", total_Time1, newFunc(pStr));
}
}
```
output:
random String
original = 2.523000 has new Line = 0
modified = 0.090000 has new line = 0
With Random <br/>
original = 0.081000 has new Line = 1
modified = 0.003000 has new line = 1
With Random <ps>
original = 0.016000 has new Line = 1
modified = 0.001000 has new line = 1
Reviewers: zmike, woohyun, bowonryu
Reviewed By: zmike
Subscribers: bu5hm4n, segfaultxavi, zmike, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D8497
-rw-r--r-- | src/lib/elementary/elm_entry.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/lib/elementary/elm_entry.c b/src/lib/elementary/elm_entry.c index e48a8c8ecb..5543504a3d 100644 --- a/src/lib/elementary/elm_entry.c +++ b/src/lib/elementary/elm_entry.c @@ -2868,18 +2868,20 @@ _entry_has_new_line(const char *text) { if (!text) return EINA_FALSE; - while (*text) - { - if (!strncmp(text, "<br", 3) || !strncmp(text, "<ps", 3)) - { - if (text[3] == '>' || ((text[3] == '/') && (text[4] == '>'))) - { - return EINA_TRUE; - } - } - text++; - } + const char * pTemp = text; + while ((pTemp = strchr(pTemp, '<'))) + { + pTemp++; + if (!strncmp(pTemp, "br", 2) || !strncmp(pTemp, "ps", 2)) + { + pTemp += 2; + if (pTemp[0] != '\0' && (pTemp[0] == '>' || (pTemp[0] == '/' && pTemp[1] == '>'))) + { + return EINA_TRUE; + } + } + } return EINA_FALSE; } |