joes        2003/04/22 23:48:57

  Modified:    env      mod_apreq.c
               src      apreq.h apreq_tables.c
               t        tables.c
  Log:
  Eliminate a few segfaults in tree insertion/deletion algorithms. Added test 
handler and filter injection logic to mod_apreq.c
  
  Revision  Changes    Path
  1.8       +60 -12    httpd-apreq-2/env/mod_apreq.c
  
  Index: mod_apreq.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/env/mod_apreq.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- mod_apreq.c       22 Apr 2003 21:21:18 -0000      1.7
  +++ mod_apreq.c       23 Apr 2003 06:48:57 -0000      1.8
  @@ -79,6 +79,7 @@
   
   static const char env_name[] = "APACHE2";
   static const char filter_name[] = "APREQ";
  +
   module AP_MODULE_DECLARE_DATA apreq_module;
   
   static apr_pool_t *env_pool(void *ctx)
  @@ -116,7 +117,7 @@
           ctx->req = NULL;
           ctx->jar = NULL;
           ctx->bb_in = ctx->bb_parse = NULL;
  -        apr_table_add(r->notes, filter_name, (char *)ctx);
  +        apr_table_addn(r->notes, filter_name, (char *)ctx);
       }
       return ctx;
   }
  @@ -143,7 +144,12 @@
           apreq_request_t *oldreq = c->req;
   
           if (oldreq == NULL) {
  +            dAPREQ_LOG;
  +            ap_filter_rec_t *f = ap_get_input_filter_handle(filter_name);
  +            apreq_log(APREQ_DEBUG 0, r, "Adding APREQ filter to input 
chain");
               /* XXX: SOMEHOW INJECT APREQ INPUT FILTER */
  +            ap_add_input_filter_handle(f, NULL, r, r->connection);
  +
           }
   
           c->req = (apreq_request_t *)req;
  @@ -162,8 +168,7 @@
   static int dump_table(void *ctx, const char *key, const char *value)
   {
       request_rec *r = ctx;
  -    dAPREQ_LOG;
  -    apreq_log(APREQ_DEBUG 0, r, "%s => %s", key, value);
  +    ap_rprintf(r, "\t%s => %s\n", key, value);
       return 1;
   }
   
  @@ -200,7 +205,7 @@
               ctx->bb_parse = apr_brigade_create(r->pool, f->c->bucket_alloc);
           if (ctx->req == NULL) {
               apreq_parser_t *parser;
  -            ctx->req = apreq_request(r,r->args);
  +            ctx->req = apreq_request(r, NULL);
               parser = apreq_make_parser(r->pool, APREQ_URL_ENCTYPE,
                                          apreq_parse_urlencoded, NULL, 
ctx->req);
               apreq_register_parser(ctx->req, parser);
  @@ -208,18 +213,17 @@
                                          apreq_parse_multipart, NULL, 
ctx->req);
               apreq_register_parser(ctx->req, parser);
           }
  +        apreq_log(APREQ_DEBUG 0, r, "filter initialized");
       }
       else
           ctx = (struct env_ctx *)f->ctx;
   
       /* XXX configure filter & parser here */
   
  +
       rv = ap_get_brigade(f->next, ctx->bb_in, AP_MODE_READBYTES,
                           block, readbytes);
   
  -    apreq_log(APREQ_DEBUG rv, r, "dump args:");
  -    apreq_table_do(dump_table, r, ctx->req->args, NULL);
  -
   
       if (ctx->req->v.status == APR_INCOMPLETE) {
           int saw_eos = 0;
  @@ -239,6 +243,7 @@
               }
           }
   
  +        apreq_log(APREQ_DEBUG 0, r, "filter parsing");
           rv = apreq_parse(ctx->req, ctx->bb_parse);
   
           if (rv == APR_INCOMPLETE && saw_eos == 1)
  @@ -248,21 +253,64 @@
       else {
           APR_BRIGADE_CONCAT(bb, ctx->bb_in);
       }
  -
  -    if (ctx->req->body) {
  -        apreq_log(APREQ_DEBUG rv, r, "dump body:");
  -        apreq_table_do(dump_table, r, ctx->req->body, NULL);
  -    }
  +    apreq_log(APREQ_DEBUG 0, r, "filter returned(%d)", rv);
   
       return rv;
   }
   
   
   
  +static int test_handler(request_rec *r)
  +{
  +    apr_bucket_brigade *bb;
  +    apreq_request_t *req;
  +    apr_status_t s;
  +    int saw_eos = 1;
  +    dAPREQ_LOG;
  +
  +    if (strcmp(r->handler, "httpd-apreq") != 0)
  +        return DECLINED;
  +
  +    apreq_log(APREQ_DEBUG 0, r, "initializing request");
  +    req = apreq_request(r, NULL);
  +
  +
  +    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
  +    
  +    do {
  +        apr_bucket *e;
  +        apreq_log(APREQ_DEBUG 0, r, "pulling content thru input filters");
  +        s = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
  +                           APR_BLOCK_READ, HUGE_STRING_LEN);
  +
  +        APR_BRIGADE_FOREACH(e,bb) {
  +            if (APR_BUCKET_IS_EOS(e)) {
  +                saw_eos = 1;
  +                break;
  +            }
  +        }
  +
  +        apr_brigade_cleanup(bb);
  +
  +    } while (!saw_eos);
  +
  +    ap_set_content_type(r, "text/plain");
  +    ap_rputs("GOT APREQ?\n\n",r);
  +
  +    ap_rputs("ARGS:\n");
  +    apreq_table_do(dump_table, r, req->args, NULL);
  +    if (req->body) {
  +        ap_rputs("\nBODY:\n");
  +        apreq_table_do(dump_table, r, req->body, NULL);
  +    }
  +    return OK;
  +}
  +
   static void register_hooks (apr_pool_t *p)
   {
       ap_register_input_filter(filter_name, apreq_filter, NULL, 
                                AP_FTYPE_CONTENT_SET);
  +    ap_hook_handler(test_handler, NULL, NULL, APR_HOOK_MIDDLE);
   }
   
   
  
  
  
  1.15      +2 -2      httpd-apreq-2/src/apreq.h
  
  Index: apreq.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- apreq.h   21 Apr 2003 16:09:09 -0000      1.14
  +++ apreq.h   23 Apr 2003 06:48:57 -0000      1.15
  @@ -9,8 +9,8 @@
   #endif 
   
   
  -#define APREQ_DECLARE(d)                d
  -#define APREQ_DECLARE_NONSTD(d)         d
  +#define APREQ_DECLARE(d)                APR_DECLARE(d)
  +#define APREQ_DECLARE_NONSTD(d)         APR_DECLARE_NONSTD(d)
   #define APREQ_URL_ENCTYPE               "application/x-www-form-urlencoded"
   #define APREQ_MFD_ENCTYPE               "multipart/form-data"
   #define APREQ_XML_ENCTYPE               "application/xml"
  
  
  
  1.20      +48 -106   httpd-apreq-2/src/apreq_tables.c
  
  Index: apreq_tables.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- apreq_tables.c    22 Apr 2003 03:50:25 -0000      1.19
  +++ apreq_tables.c    23 Apr 2003 06:48:57 -0000      1.20
  @@ -207,12 +207,6 @@
       return 0;
   }
   
  -/* XXX Are these macros really needed? */
  -#define TREE_PUSH      1
  -#define TREE_REPLACE   2
  -
  -#define TREE_POP       1
  -#define TREE_DROP      2
   
   static int insert(apreq_table_entry_t *o, int *root, int x,
                     apreq_table_entry_t *elt,
  @@ -222,76 +216,49 @@
       int s = search(o, &x, elt->key);
   
       if (s == 0) { /* found */
  -        if (x < 0) { /* empty tree */
  +        int parent = x;
  +        if (parent < 0) { /* empty tree */
               *root = idx;
               elt->tree[LEFT]   = -1;
               elt->tree[RIGHT]  = -1;
               elt->tree[PARENT] = -1;
  +            elt->color = BLACK;
               return -1;
           }
   
  -        switch (flags) {
  -            int parent;
  -
  -        case TREE_PUSH:
  -            parent = x;
  -
  -            while (parent[o].tree[NEXT] >= 0)
  -                parent = parent[o].tree[NEXT];
  -
  -            parent[o].tree[NEXT]  = idx;
  -            elt->tree[PARENT]      = -1;
  -            elt->tree[RIGHT]       = -1;
  -            elt->tree[LEFT]        = -1;
  -            return x;
  -
  -        case TREE_REPLACE:
  -            parent = x[o].tree[PARENT];
  -
  -            if (x[o].tree[LEFT] >= 0)
  -                x[o].tree[LEFT][o].tree[PARENT] = idx;
  -
  -            if (x[o].tree[RIGHT] >= 0)
  -                x[o].tree[RIGHT][o].tree[PARENT] = idx;
  -
  -            if (parent >= 0)
  -                parent[o].tree[LR(x)] = idx;
  -            else
  -                *root = idx;
  +        elt->color = parent[o].color;
   
  -            elt->tree[PARENT] = parent;
  -            elt->tree[RIGHT]  = x[o].tree[RIGHT];
  -            elt->tree[LEFT]   = x[o].tree[LEFT];
  -            elt->color        = x[o].color;
  +        while (parent[o].tree[NEXT] >= 0)
  +            parent = parent[o].tree[NEXT];
   
  -            return x;
  -
  -        default:
  -            return -1;
  -        }
  +        parent[o].tree[NEXT]   = idx;
  +        elt->tree[PARENT]      = -1;
  +        elt->tree[RIGHT]       = -1;
  +        elt->tree[LEFT]        = -1;
  +        return x;
       }
   
   
       /* The element wasn't in the tree, so add it */
       x[o].tree[s < 0 ? LEFT : RIGHT] = idx;
  +
       elt->tree[PARENT] =  x;
       elt->tree[RIGHT]  = -1;
       elt->tree[LEFT]   = -1;
   
       elt->color = RED;
   
  -
       if (flags & TF_BALANCE) {
           while (idx[o].tree[PARENT] >= 0 && idx[o].tree[PARENT][o].color == 
RED)
           {
  -        /* parent , grandparent, & parent_sibling nodes all exist */
  +        /* parent & grandparent exist, parent_sibling may not */
   
               int parent = idx[o].tree[PARENT];
               int grandparent = parent[o].tree[PARENT];
               register const int parent_direction = LR(parent);
               int parent_sibling = grandparent[o].tree[!parent_direction];
   
  -            if (parent_sibling[o].color == RED) {
  +            if (parent_sibling >= 0 && parent_sibling[o].color == RED) {
                   parent[o].color            = BLACK;
                   parent_sibling[o].color    = BLACK;
                   grandparent[o].color       = RED;
  @@ -300,13 +267,14 @@
               }
               else {  /* parent_sibling->color == BLACK */
   
  -                if ( LR(idx) != parent_direction ) { /* opposite direction */
  -                    rotate(o, root, parent, parent_direction); /* demotes 
idx */
  +                if ( LR(idx) != parent_direction ) {
  +                    /* demote parent & swap idx with parent */
  +                    rotate(o, root, parent, parent_direction);
                       idx           = parent;
  -                    parent        = idx[o].tree[PARENT]; /* idx's old 
sibling */
  -                    /* grandparent is unchanged */
  +                    parent        = idx[o].tree[PARENT];
                   }
   
  +                /* promote parent */
                   parent[o].color      = BLACK;
                   grandparent[o].color = RED;
                   rotate(o, root, grandparent, !parent_direction);
  @@ -323,61 +291,43 @@
   {
       int x,y;
   
  -    if ((flags & TREE_POP) && idx[o].tree[NEXT] >= 0) {
  -        /* pop elt off the stack */
  -        x = idx[o].tree[PARENT];
  -        y = idx[o].tree[NEXT];
  -        idx[o].tree[NEXT] = 0;
  -
  -        y[o].tree[PARENT] = x;
  -        y[o].tree[LEFT]   = idx[o].tree[LEFT];
  -        y[o].tree[RIGHT]  = idx[o].tree[RIGHT];
  -        y[o].color        = idx[o].color;
  +    if (idx[o].tree[LEFT] < 0 || idx[o].tree[RIGHT] < 0) {
  +        x = y = 1 + idx[o].tree[RIGHT] + idx[o].tree[LEFT];
   
  -        if (x >= 0)
  -            x[o].tree[LR(idx)] = y;
  -        else
  -            *root = y;
   
  -        idx[o].tree[PARENT] = -1;
  -        idx[o].tree[LEFT]   = -1;
  -        idx[o].tree[RIGHT]  = -1;
  +        if (idx[o].tree[PARENT] >= 0)
  +            idx[o].tree[PARENT][o].tree[LR(idx)] = x;
  +        else
  +            *root = x;
   
  -        return;
  +        if (x >= 0)
  +            x[o].tree[PARENT] = idx[o].tree[PARENT];
  +        else
  +            return;
       }
  -
  -    if (idx[o].tree[LEFT] < 0 || idx[o].tree[RIGHT] < 0)
  -        y = idx;
       else {
           y = idx[o].tree[RIGHT];
           while (y[o].tree[LEFT] >= 0)
               y = y[o].tree[LEFT];
  -    }
   
  -    /* x is y's only child */
  -    x = (y[o].tree[LEFT] >= 0) ? y[o].tree[LEFT] : y[o].tree[RIGHT];
  +        x = y[o].tree[RIGHT];
   
  -    /* remove y from the parent chain */
  -    x[o].tree[PARENT] = y[o].tree[PARENT];
  +        if (y[o].tree[PARENT] != idx) {
  +            y[o].tree[RIGHT] = idx[o].tree[RIGHT];
   
  -    if (y[o].tree[PARENT] >= 0)
  -        y[o].tree[PARENT][o].tree[LR(y)] = x;
  -    else
  -        *root = x;
  +            if (x >= 0) {
  +                x[o].tree[PARENT] = y[o].tree[PARENT];
  +                y[o].tree[PARENT][o].tree[LR(y)] = x;
  +            }
  +        }
   
  -    if (y != idx) {     /* swap y[o] with idx[o] */
           y[o].tree[LEFT] = idx[o].tree[LEFT];
  -        y[o].tree[RIGHT] = idx[o].tree[RIGHT];
           y[o].tree[PARENT] = idx[o].tree[PARENT];
           
  -        if (y[o].tree[PARENT] >= 0)
  -            y[o].tree[PARENT][o].tree[LR(y)] = y;
  +        if (idx[o].tree[PARENT] >= 0)
  +            idx[o].tree[PARENT][o].tree[LR(idx)] = y;
           else
               *root = y;
  -
  -        idx[o].tree[LEFT] = -1;
  -        idx[o].tree[RIGHT] = -1;
  -        idx[o].tree[PARENT] = -1;
       }
   
       if (y[o].color == RED) {
  @@ -385,9 +335,10 @@
           return;
       }
   
  +
       /* rebalance tree (standard double-black promotion) */
   
  -    x[o].color = idx[o].color; /* should this be y[o].color ??? */
  +    x[o].color = idx[o].color;
   
       if (flags & TF_BALANCE) {
           while (x != *root && x[o].color == BLACK) 
  @@ -455,7 +406,7 @@
               a[o].tree[PARENT] = -1;
           }
   
  -        if (insert(o,&a,a,b+o, TREE_PUSH) < 0)
  +        if (insert(o,&a,a,b+o,0) < 0)
               rv = b;
   
           if (b[o].tree[PARENT] >= 0)
  @@ -666,8 +617,7 @@
   
           memset(t->root,-1,TABLE_HASH_SIZE * sizeof(int));
           for (idx = 0; idx < t->a.nelts; ++idx)
  -            insert(o, &t->root[TABLE_HASH(idx[o].key)], -1, &idx[o], 
  -                   TF_BALANCE | TREE_PUSH);
  +            insert(o, &t->root[TABLE_HASH(idx[o].key)], -1, &idx[o], 
TF_BALANCE);
   
           t->flags |= TF_BALANCE;
       }
  @@ -874,12 +824,6 @@
       int idx = t->root[TABLE_HASH(key)];
       apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
   
  -#ifdef POOL_DEBUG
  -    {
  -        /* XXX */
  -    }
  -#endif
  -
       if (idx >= 0 && search(o,&idx,key) == 0) {
           int n;
           idx[o].val = val;
  @@ -895,7 +839,7 @@
           e->val = val;
           e->tree[NEXT] = -1;
           insert((apreq_table_entry_t *)t->a.elts,
  -               &t->root[TABLE_HASH(key)],idx,e,TREE_PUSH);
  +               &t->root[TABLE_HASH(key)],idx,e,t->flags);
       }
   }
   
  @@ -909,7 +853,7 @@
   
           LOCK_TABLE(t);
   
  -        delete(o,&t->root[TABLE_HASH(key)],idx,TREE_DROP);
  +        delete(o,&t->root[TABLE_HASH(key)],idx, t->flags);
   
           for ( n=idx; n>=0; n=n[o].tree[NEXT] )
               KILL(t,n);
  @@ -962,7 +906,7 @@
           e->val = val;
           e->tree[NEXT] = -1;
           insert((apreq_table_entry_t *)t->a.elts,
  -               &t->root[TABLE_HASH(key)],idx,e,TREE_PUSH);
  +               &t->root[TABLE_HASH(key)],idx,e,t->flags);
       }
       return val->status;
   }
  @@ -986,7 +930,7 @@
           elt->key = val->name;
           elt->val = val;
           elt->tree[NEXT] = -1;
  -        insert(o, root, *root, elt, TREE_PUSH);
  +        insert(o, root, *root, elt, t->flags);
           return APR_SUCCESS;
       }
   
  @@ -1022,7 +966,6 @@
               if (DEAD(idx))
                   continue;
   
  -
               if (idx[o].tree[NEXT] >= 0)
                   idx[o].tree[NEXT] += n;
               
  @@ -1039,8 +982,7 @@
               else if ( idx[o].tree[PARENT] >= 0 || 
                         s->root[hash] == idx-n ) 
               {
  -                insert(o, &t->root[hash], t->root[hash], idx+o, 
  -                       TREE_PUSH | TF_BALANCE);
  +                insert(o, &t->root[hash], t->root[hash], idx+o, TF_BALANCE);
               }
           }
       }
  
  
  
  1.7       +44 -33    httpd-apreq-2/t/tables.c
  
  Index: tables.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/t/tables.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- tables.c  21 Apr 2003 18:45:57 -0000      1.6
  +++ tables.c  23 Apr 2003 06:48:57 -0000      1.7
  @@ -75,14 +75,18 @@
   {
       t1 = apreq_make_table(p, 5);
       CuAssertPtrNotNull(tc, t1);
  +    apreq_table_balance(t1,1);
   }
   
   static void table_get(CuTest *tc)
   {
       const char *val;
  +    apreq_table_set(t1, V(APREQ_URL_ENCTYPE,"foo"));
  +    apreq_table_set(t1, V(APREQ_MFD_ENCTYPE,"bar"));
   
  -    apreq_table_set(t1, V("foo","bar"));
  -    val = apreq_table_get(t1,"foo");
  +    val = apreq_table_get(t1,APREQ_URL_ENCTYPE);
  +    CuAssertStrEquals(tc,"foo",val);
  +    val = apreq_table_get(t1,APREQ_MFD_ENCTYPE);
       CuAssertStrEquals(tc,"bar",val);
   
   }
  @@ -114,23 +118,46 @@
       apreq_table_add(t1, V("add", "foo"));
       val = apreq_table_get(t1, "add");
       CuAssertStrEquals(tc, "bar", val);
  -    apreq_table_add(t1, V("fl", "left"));
  -    apreq_table_add(t1, V("fr", "right"));
  -    apreq_table_add(t1, V("fll", "left-left"));
  -    apreq_table_add(t1, V("frr", "right-right"));
  -    apreq_table_add(t1, V("frl", "right-left"));
  -    apreq_table_add(t1, V("flr", "left-right"));
  -    apreq_table_add(t1, V("b", "bah"));
  +
  +
  +    apreq_table_add(t1, V("f", "top"));
  +    apreq_table_add(t1, V("fo", "child"));
  +    apreq_table_add(t1, V("fro", "child-right"));
  +
  +    /*
  +     *     f(5)  black                fo(6) black   
  +     *      fo(6)  red       =>  f(5)red   fro(7)red
  +     *       fro(7) red
  +     *
  +     */
  +
  +
  +    apreq_table_add(t1, V("flo", "child-left"));
  +    apreq_table_add(t1, V("flr", "child-left-right"));
  +    apreq_table_add(t1, V("frr", "child-right-right"));
  +    apreq_table_add(t1, V("frl", "child-right-left"));
  +    apreq_table_add(t1, V("flr", "child-left-right"));
  +    apreq_table_add(t1, V("fll", "child-left-left"));
  +    apreq_table_add(t1, V("foo", "bar"));
  +    apreq_table_add(t1, V("b", "bah humbug"));
       val = apreq_table_get(t1, "foo");
       CuAssertStrEquals(tc, "bar", val);
  -    val = apreq_table_get(t1, "fl");
  -    CuAssertStrEquals(tc, "left", val);
  -    val = apreq_table_get(t1, "fr");
  -    CuAssertStrEquals(tc, "right", val);
  +    val = apreq_table_get(t1, "flr");
  +    CuAssertStrEquals(tc, "child-left-right", val);
  +}
  +
  +static void table_unset(CuTest *tc) {
  +    const char *val;
  +    apreq_table_unset(t1, "flo");
  +    val = apreq_table_get(t1, "flo");
  +    CuAssertPtrEquals(tc, NULL, val);
  +
  +    val = apreq_table_get(t1, "fro");
  +    CuAssertStrEquals(tc, "child-right", val);
       val = apreq_table_get(t1, "fll");
  -    CuAssertStrEquals(tc, "left-left", val);
  +    CuAssertStrEquals(tc, "child-left-left", val);
       val = apreq_table_get(t1, "frl");
  -    CuAssertStrEquals(tc, "right-left", val);
  +    CuAssertStrEquals(tc, "child-right-left", val);
   
   }
   
  @@ -159,22 +186,6 @@
       CuAssertIntEquals(tc, 0, apreq_table_nelts(t1));
   }
   
  -static void table_unset(CuTest *tc)
  -{
  -    const char *val;
  -    apreq_table_t *t;
  -
  -    t = apreq_table_make(p, 1);
  -    apreq_table_set(t, V("a", "1"));
  -    apreq_table_set(t, V("b", "2"));
  -    apreq_table_unset(t, "b");
  -    CuAssertIntEquals(tc, 1, apreq_table_nelts(t));
  -    val = apreq_table_get(t, "a");
  -    CuAssertStrEquals(tc, val, "1");
  -    val = apreq_table_get(t, "b");
  -    CuAssertPtrEquals(tc, NULL, val);
  -}
  -
   static void table_overlap(CuTest *tc)
   {
       const char *val;
  @@ -301,13 +312,13 @@
       CuSuite *suite = CuSuiteNew("Table");
   
       SUITE_ADD_TEST(suite, table_make);
  -    SUITE_ADD_TEST(suite, table_get);
  +    SUITE_ADD_TEST(suite, table_get); 
       SUITE_ADD_TEST(suite, table_set);
       SUITE_ADD_TEST(suite, table_getnotthere);
       SUITE_ADD_TEST(suite, table_add);
  +    SUITE_ADD_TEST(suite, table_unset);
       SUITE_ADD_TEST(suite, table_nelts);
       SUITE_ADD_TEST(suite, table_clear);
  -    SUITE_ADD_TEST(suite, table_unset);
       SUITE_ADD_TEST(suite, table_overlap);
       SUITE_ADD_TEST(suite, table_elts);
       SUITE_ADD_TEST(suite, table_overlay);
  
  
  

Reply via email to