Hello. As I read gw/msg.c I found strange code which looks like:

> Msg *msg_create_real(enum msg_type type, const char *file, long line,
>                      const char *func)
> {
>     Msg *msg;
> 
>     msg = gw_malloc_trace(sizeof(Msg), file, line, func);
> 
>     msg->type = type;
> #define INTEGER(name) p->name = MSG_PARAM_UNDEFINED
> #define OCTSTR(name) p->name = NULL
> #define UUID(name) uuid_generate(p->name)
> #define VOID(name) p->name = NULL
> #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
> #include "msg-decl.h"
> 
>     return msg;
> }

Look attentively to MSG() definition, which means that for any type I requested
msg_create() will run code for all types. There is no switch{} like in
msg_pack/msg_unpack, no if{} like in msg_dump(). Similar "universality" I
observe in msg_destroy() and msg_duplicate() which I think is sorta dangerous
for code like this to be executed in wild. This we call russian roulette.


Bad&dangerous code in my opinion:

> Msg *msg_duplicate(Msg *msg)
> {
>     Msg *new;
> 
>     new = msg_create(msg->type);
> 
> #define INTEGER(name) p->name = q->name
> #define OCTSTR(name) \
>     if (q->name == NULL) p->name = NULL; \
>     else p->name = octstr_duplicate(q->name);
> #define UUID(name) uuid_copy(p->name, q->name)
> #define VOID(name) p->name = q->name
> #define MSG(type, stmt) { \
>     struct type *p = &new->type; \
>     struct type *q = &msg->type; \
>     stmt }
> #include "msg-decl.h"
> 
>     return new;
> }
> 
> void msg_destroy(Msg *msg)
> {
>     if (msg == NULL)
>         return;
> 
> #define INTEGER(name) p->name = 0
> #define OCTSTR(name) octstr_destroy(p->name)
> #define UUID(name) uuid_clear(p->name)
> #define VOID(name)
> #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
> #include "msg-decl.h"
> 
>     gw_free(msg);
> }

Good&sane code in my opinion (to compare):

> excerpt from msg_dump()
> 
> #define MSG(tt, stmt) \
>     if (tt == msg->type) \
>         { char *t = #tt; struct tt *p = &msg->tt; stmt }

> excerpt from msg_pack()
> 
> #define MSG(type, stmt) \
>     case type: { struct type *p = &msg->type; stmt } break;
> 
>     switch (msg->type) {
> #include "msg-decl.h"
>     default:
>         panic(0, "Internal error: unknown message type %d",
>               msg->type);
>     }

Btw, 


Reply via email to