summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Alzyod <ali198724@gmail.com>2019-03-29 09:52:51 -0400
committerMike Blumenkrantz <zmike@samsung.com>2019-03-29 09:58:53 -0400
commitb8952604ce1921fbd44dad46c88de456abefe430 (patch)
tree5f95390cbec05e612c41bae72a87e27ee3941cb3
parent76e8f9c07ca2e72c4bca489c1e0e48e695fe4394 (diff)
downloadefl-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.c24
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;
}