OSSP CVS Repository

ossp - Check-in [1856]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1856
Date: 2002-Feb-14 12:03:52 (local)
2002-Feb-14 11:03:52 (UTC)
User:thl
Branch:
Comment: Please review! Attempt to use lib_ex for proper cleanup. I discovered some tweaks and quirks regarding the volatile nature of the hrNew structure temporary allocating resources. Two wrappers, strdupex() and mallocex() are used to throw exceptions. It was a pain, or at least a different kind of programming, to always ensure that hrNew resoures are cleaned up completely when they should and to stop the cleanup code from releasing resources in the non-exceptional case. Although, the declaration of a volatile structure requires casting where i do not want to use it. Maybe i did something wrong, and life becomes easier in this particular case when i put the exeptional cleanup code in the catch construct, because in this try-cleanup-catch block i only want cleanup in the exeptional case. However, this would only remove the "hrNew = NULL" line at the buttom of the for() loop. Would this help, should it work? Unsure ...
Tickets:
Inspections:
Files:
ossp-pkg/lmtp2nntp/fixme.h      1.14 -> 1.15     1 inserted, 0 deleted
ossp-pkg/lmtp2nntp/lmtp2nntp_config.c      1.48 -> 1.49     102 inserted, 72 deleted
ossp-pkg/lmtp2nntp/lmtp2nntp_main.c      1.40 -> 1.41     3 inserted, 3 deleted

ossp-pkg/lmtp2nntp/fixme.h 1.14 -> 1.15

--- fixme.h      2002/02/13 16:25:38     1.14
+++ fixme.h      2002/02/14 11:03:52     1.15
@@ -34,6 +34,7 @@
 typedef struct headerrule_st headerrule_t;
 struct headerrule_st {
     headerrule_t *next;
+    char         *carve; /* pri, regex, header, val carved out here, so free up only this */
     int           pri;
     char         *regex;
     char         *header;


ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.48 -> 1.49

--- lmtp2nntp_config.c   2002/02/13 16:25:38     1.48
+++ lmtp2nntp_config.c   2002/02/14 11:03:52     1.49
@@ -527,82 +527,112 @@
         rethrow;
 
     /* --headerrule MULTI */
-    try {
-        char *cp;
-        int i;
-        char *cpPri;
-        char *cpRegex;
-        char *cpHeader;
-        char *cpVal;
-        headerrule_t *hrNew;
-        headerrule_t *hrI;
-        headerrule_t *hrP;
-
-        if (   (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK)
-            || (ov->ndata <  0)
-            || (ov->ndata >= 1 && ov->data.m == NULL)
-              ) throw(0,0,0);
-        log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
-        for (i = 0; i < ov->ndata; i++)
-            log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]);
-
-        if (ov->ndata >= 1) {
-            for (i = 0; i < ov->ndata; i++) {
-                cp = (ov->data.m)[i];
-                log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
-                cp = strdup(cp); //FIXME
-                /* priority */
-                cpPri = cp;
-                if ((cp = strchr(cp, ':')) == NULL) {
-                    log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]);
-                    throw(0,0,0);
-                }
-                *cp = NUL;
-                cp++;
-                /* regex */
-                cpRegex = cp;
-                if ((cp = strchr(cp, ':')) == NULL) {
-                    log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]);
-                    throw(0,0,0);
-                }
-                *cp = NUL;
-                cp++;
-                /* header */
-                cpHeader = cp;
-                if ((cp = strchr(cp, ':')) == NULL) {
-                    log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]);
-                    throw(0,0,0);
-                }
-                *cp = NUL;
-                cp++;
-                /* value */
-                cpVal = cp;
-
-                if ((hrNew = (headerrule_t *)malloc(sizeof(headerrule_t))) == NULL) throw(0,0,0);
-                hrNew->next   = NULL;
-                hrNew->pri    = atoi(cpPri);
-                hrNew->regex  = cpRegex;
-                hrNew->header = cpHeader;
-                hrNew->val    = cpVal;
-
-                if (ctx->option_firstheaderrule == NULL)
-                    ctx->option_firstheaderrule = hrNew;
-                else {
-                    for (hrP = NULL, hrI = ctx->option_firstheaderrule;
-                         hrI != NULL && hrI->pri <= hrNew->pri;
-                         hrP = hrI, hrI = hrI->next);
-                    if (hrI != NULL)
-                        hrNew->next = hrI; /* insert */
-                    if (hrP != NULL)
-                        hrP->next = hrNew; /* append */
-                    else
-                        ctx->option_firstheaderrule = hrNew; /* newfirst */
+    {
+    volatile headerrule_t *hrNew = NULL; // declare and initialize variables which might have resources allocated that need to be cleaned up when an exception is caught
+        try {
+            char *cp;
+            int i;
+            char *cpPri;
+            char *cpRegex;
+            char *cpHeader;
+            char *cpVal;
+            headerrule_t *hrI;
+            headerrule_t *hrP;
+
+            if (   (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK)
+                || (ov->ndata <  0)
+                || (ov->ndata >= 1 && ov->data.m == NULL)
+                  ) throw(0,0,0);
+            log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
+            for (i = 0; i < ov->ndata; i++)
+                log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]);
+
+            if (ov->ndata >= 1) {
+                for (i = 0; i < ov->ndata; i++) {
+                    cp = (ov->data.m)[i];
+                    log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
+
+                    hrNew = (headerrule_t *)mallocex(sizeof(headerrule_t));
+                    hrNew->next   = NULL;
+                    hrNew->carve  = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught
+                    
+                    cp = hrNew->carve = strdupex(cp);
+                    /* priority */
+                    cpPri = cp;
+                    if ((cp = strchr(cp, ':')) == NULL) {
+                        log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]);
+                        throw(0,0,0);
+                    }
+                    *cp = NUL;
+                    if (strlen(cpPri) == 0)
+                        cpPri = "0";
+                    cp++;
+                    /* regex */
+                    cpRegex = cp;
+                    if ((cp = strchr(cp, ':')) == NULL) {
+                        log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]);
+                        throw(0,0,0);
+                    }
+                    *cp = NUL;
+                    if (strlen(cpRegex) == 0)
+                        cpRegex = NULL;
+                    cp++;
+                    /* header */
+                    cpHeader = cp;
+                    if ((cp = strchr(cp, ':')) == NULL) {
+                        log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]);
+                        throw(0,0,0);
+                    }
+                    *cp = NUL;
+                    if (strlen(cpHeader) == 0) {
+                        log1(ctx, ERROR, "option --headerrule, header (%s) missing", (ov->data.m)[i]);
+                        throw(0,0,0);
+                    }
+                    cp++;
+                    /* value */
+                    cpVal = cp;
+                    if (strlen(cpVal) == 0)
+                        cpVal = NULL;
+
+                    hrNew->pri    = atoi(cpPri);
+                    hrNew->regex  = cpRegex;
+                    hrNew->header = cpHeader;
+                    hrNew->val    = cpVal;
+
+                    if (ctx->option_firstheaderrule == NULL)
+                        ctx->option_firstheaderrule = (headerrule_t *)hrNew; // interesting point since hrNew is declared volatile we have to cast it. This makes me unhappy as it enlarges the code which is far from the spirit of lib_ex
+                    else {
+                        for (hrP = NULL, hrI = ctx->option_firstheaderrule;
+                             hrI != NULL && hrI->pri <= hrNew->pri;
+                             hrP = hrI, hrI = hrI->next);
+                        if (hrI != NULL)
+                            hrNew->next = hrI; /* insert */
+                        if (hrP != NULL)
+                            hrP->next = (headerrule_t *)hrNew; /* append */
+                        else
+                            ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* newfirst */
+                    }
+                    /* after linking the structure into a parental-controlled structure we
+                       expect that the parental cleanup will handle normal and exceptional
+                       resource releasing and therefore we *must* reset this variable initialization
+                       to avoid accidental local cleanup! In fact, this code will fail if the
+                       next statement is omitted.
+                     */
+                    hrNew = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught
+
                 }
             }
         }
+        cleanup { // make sure the conditional variables are *always* proper initialized and cleared volatile
+            if (hrNew != NULL) {
+                if (hrNew->carve != NULL)
+                    freeex(hrNew->carve);
+                freeex((headerrule_t *)hrNew);
+            }
+        }
+        catch (ex)
+            rethrow;
     }
-    catch (ex)
-        rethrow;
 
     /* --mailfrom SINGLE */
     try {


ossp-pkg/lmtp2nntp/lmtp2nntp_main.c 1.40 -> 1.41

--- lmtp2nntp_main.c     2002/02/13 16:25:38     1.40
+++ lmtp2nntp_main.c     2002/02/14 11:03:52     1.41
@@ -405,9 +405,9 @@
 fprintf(stderr, "DEBUG: los geht's\n");
 for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) {
     fprintf(stderr, "DEBUG: cpPri    = %d\n", hrI->pri);
-    fprintf(stderr, "DEBUG: cpRegex  = \"%s\"\n", hrI->regex);
-    fprintf(stderr, "DEBUG: cpHeader = \"%s\"\n", hrI->header);
-    fprintf(stderr, "DEBUG: cpValue  = \"%s\"\n", hrI->val);
+    fprintf(stderr, "DEBUG: cpRegex  = \"%s\"\n", hrI->regex  == NULL ? "(NULL)" : hrI->regex);
+    fprintf(stderr, "DEBUG: cpHeader = \"%s\"\n", hrI->header == NULL ? "(NULL)" : hrI->header);
+    fprintf(stderr, "DEBUG: cpValue  = \"%s\"\n", hrI->val    == NULL ? "(NULL)" : hrI->val);
 }
 fprintf(stderr, "DEBUG: das war's\n");
 }

CVSTrac 2.0.1