aboutsummaryrefslogtreecommitdiffstats
path: root/evaluator.c
diff options
context:
space:
mode:
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2006-01-21 09:40:20 +0000
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>2006-01-21 09:40:20 +0000
commitab1f95d24f2b5132f99812ee68a181cd7fa0dc01 (patch)
tree215e65c06ab7efdfde2e7d395f0cc5aabc173234 /evaluator.c
parent1c7b2ac5fdda6a1c1b63647e9d360bdd6715d423 (diff)
downloadlcd4linux-ab1f95d24f2b5132f99812ee68a181cd7fa0dc01.tar.gz
[lcd4linux @ 2006-01-21 09:40:20 by reinelt]
Big Memory Leak in Evaluator fixed (thanks to Oliver Gehrke) git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@617 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
Diffstat (limited to 'evaluator.c')
-rw-r--r--evaluator.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/evaluator.c b/evaluator.c
index abb3278..e4493b3 100644
--- a/evaluator.c
+++ b/evaluator.c
@@ -1,4 +1,4 @@
-/* $Id: evaluator.c,v 1.25 2005/05/08 04:32:44 reinelt Exp $
+/* $Id: evaluator.c,v 1.26 2006/01/21 09:40:20 reinelt Exp $
*
* expression evaluation
*
@@ -23,6 +23,9 @@
*
*
* $Log: evaluator.c,v $
+ * Revision 1.26 2006/01/21 09:40:20 reinelt
+ * Big Memory Leak in Evaluator fixed (thanks to Oliver Gehrke)
+ *
* Revision 1.25 2005/05/08 04:32:44 reinelt
* CodingStyle added and applied
*
@@ -340,29 +343,6 @@ static RESULT *NewResult(void)
}
-static RESULT *DupResult(RESULT * result)
-{
- RESULT *result2;
-
- if ((result2 = NewResult()) == NULL)
- return NULL;
-
- result2->type = result->type;
- result2->number = result->number;
-
- if (result->length >= 0) {
- result2->length = result->length;
- result2->string = malloc(result2->length);
- strcpy(result2->string, result->string);
- } else {
- result2->length = -1;
- result2->string = NULL;
- }
-
- return result2;
-}
-
-
RESULT *SetResult(RESULT ** result, const int type, const void *value)
{
if (*result == NULL) {
@@ -392,7 +372,7 @@ RESULT *SetResult(RESULT ** result, const int type, const void *value)
(*result)->length = CHUNK_SIZE * (len / CHUNK_SIZE + 1) - 1;
(*result)->string = malloc((*result)->length + 1);
}
- strcpy((*result)->string, value);
+ strncpy((*result)->string, value, (*result)->length + 1);
} else {
error("Evaluator: internal error: invalid result type %d", type);
return NULL;
@@ -402,6 +382,36 @@ RESULT *SetResult(RESULT ** result, const int type, const void *value)
}
+static RESULT *CopyResult(RESULT ** result, RESULT * value)
+{
+ if (*result == NULL) {
+ if ((*result = NewResult()) == NULL)
+ return NULL;
+ }
+
+ (*result)->type = value->type;
+ (*result)->number = value->number;
+
+ if (value->string == NULL) {
+ if ((*result)->string)
+ free((*result)->string);
+ (*result)->string = NULL;
+ (*result)->length = -1;
+ } else {
+ /* is buffer large enough? */
+ if ((*result)->string == NULL || value->length > (*result)->length) {
+ if ((*result)->string)
+ free((*result)->string);
+ (*result)->length = value->length;
+ (*result)->string = malloc((*result)->length + 1);
+ /* length does not count the trailing \0 */
+ }
+ strncpy((*result)->string, value->string, (*result)->length + 1);
+ }
+ return *result;
+}
+
+
double R2N(RESULT * result)
{
if (result == NULL) {
@@ -440,8 +450,8 @@ char *R2S(RESULT * result)
if (result->string)
free(result->string);
result->length = CHUNK_SIZE - 1;
- result->string = malloc(CHUNK_SIZE);
- snprintf(result->string, CHUNK_SIZE, "%g", result->number);
+ result->string = malloc(result->length+1);
+ snprintf(result->string, result->length, "%g", result->number);
return result->string;
}
@@ -483,15 +493,15 @@ int SetVariable(const char *name, RESULT * value)
V = FindVariable(name);
if (V != NULL) {
- FreeResult(V->value);
- V->value = DupResult(value);
+ CopyResult (&V->value, value);
return 1;
}
nVariable++;
Variable = realloc(Variable, nVariable * sizeof(VARIABLE));
Variable[nVariable - 1].name = strdup(name);
- Variable[nVariable - 1].value = DupResult(value);
+ Variable[nVariable - 1].value = NULL;
+ CopyResult (&Variable[nVariable - 1].value, value);
qsort(Variable, nVariable, sizeof(VARIABLE), SortVariable);
@@ -1064,8 +1074,7 @@ static int EvalTree(NODE * Root)
return 0;
case T_VARIABLE:
- DelResult(Root->Result);
- Root->Result = DupResult(Root->Variable->value);
+ CopyResult (&Root->Result, Root->Variable->value);
return 0;
case T_FUNCTION:
@@ -1097,8 +1106,7 @@ static int EvalTree(NODE * Root)
break;
case O_SET: /* variable assignment */
- DelResult(Root->Variable->value);
- Root->Variable->value = DupResult(Root->Child[0]->Result);
+ CopyResult(&Root->Variable->value, Root->Child[0]->Result);
type = Root->Child[0]->Result->type;
number = Root->Child[0]->Result->number;
string = Root->Child[0]->Result->string;
@@ -1297,9 +1305,9 @@ int Eval(void *tree, RESULT * result)
result->number = Tree->Result->number;
result->length = Tree->Result->length;
if (result->length >= 0) {
- result->string = malloc(result->length);
+ result->string = malloc(result->length+1);
if (Tree->Result->string != NULL)
- strcpy(result->string, Tree->Result->string);
+ strncpy(result->string, Tree->Result->string, result->length);
else
result->string[0] = '\0';
} else {