Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

Commit

Permalink
Merge pull request #345 from edk0/alias
Browse files Browse the repository at this point in the history
m_alias: Preserve protocol framing characters
  • Loading branch information
aaronmdjones authored Jul 7, 2020
2 parents e241d79 + 4e14f9a commit 860d238
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 4 deletions.
7 changes: 7 additions & 0 deletions include/msgbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct MsgBuf {
const char *origin; /* the origin of the message (or NULL) */
const char *target; /* the target of the message (either NULL, or custom defined) */
const char *cmd; /* the cmd/verb of the message (either NULL, or para[0]) */
char *endp; /* one past the end of the original array */

size_t n_para; /* the number of parameters (always at least 1 if a full message) */
const char *para[MAXPARA]; /* parameters vector (starting with cmd as para[0]) */
Expand Down Expand Up @@ -76,6 +77,12 @@ struct MsgBuf_cache {
*/
int msgbuf_parse(struct MsgBuf *msgbuf, char *line);

/*
* Unparse the tail of a msgbuf perfectly, preserving framing details
* msgbuf->para[n] will reach to the end of the line
*/
void msgbuf_reconstruct_tail(struct MsgBuf *msgbuf, size_t n);

/*
* unparse a pure MsgBuf into a buffer.
* if origin is NULL, me.name will be used.
Expand Down
35 changes: 35 additions & 0 deletions ircd/msgbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
if (*ch == '\0')
return 2;

msgbuf->endp = &ch[strlen(ch)];
msgbuf->n_para = rb_string_to_array(ch, (char **)msgbuf->para, MAXPARA);
if (msgbuf->n_para == 0)
return 3;
Expand All @@ -162,6 +163,40 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
return 0;
}

/*
* Unparse the tail of a msgbuf perfectly, preserving framing details
* msgbuf->para[n] will reach to the end of the line
*/

void
msgbuf_reconstruct_tail(struct MsgBuf *msgbuf, size_t n)
{
if (msgbuf->endp == NULL || n > msgbuf->n_para)
return;

char *c;
const char *c_;

if (n == 0)
c_ = msgbuf->para[n];
else
c_ = msgbuf->para[n-1] + strlen(msgbuf->para[n-1]) + 1;

if (n == msgbuf->n_para && c_ == msgbuf->endp)
return;

msgbuf->para[n] = c_;
/* promote to non-const. msgbuf->endp witnesses that this is allowed */
c = msgbuf->endp - (msgbuf->endp - c_);

for ( ; c < msgbuf->endp; c++)
{
if (*c == '\0')
*c = ' ';
}
}


/*
* Unparse msgbuf tags into a buffer
* returns the length of the tags written
Expand Down
8 changes: 4 additions & 4 deletions modules/m_alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ m_alias(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p,
{
struct Client *target_p;
struct alias_entry *aptr = rb_dictionary_retrieve(alias_dict, msgbuf->cmd);
char *p, *str;
char *p;

if(aptr == NULL)
{
Expand Down Expand Up @@ -151,8 +151,8 @@ m_alias(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p,
return;
}

str = reconstruct_parv(parc - 1, &parv[1]);
if(EmptyString(str))
msgbuf_reconstruct_tail(msgbuf, 1);
if(EmptyString(parv[1]))
{
sendto_one(client_p, form_str(ERR_NOTEXTTOSEND), me.name, target_p->name);
return;
Expand All @@ -161,5 +161,5 @@ m_alias(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p,
sendto_one(target_p, ":%s PRIVMSG %s :%s",
get_id(client_p, target_p),
p != NULL ? aptr->target : get_id(target_p, target_p),
str);
parv[1]);
}
45 changes: 45 additions & 0 deletions tests/msgbuf_parse1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3297,6 +3297,49 @@ static void unescape_8bit(void)
}
}

static struct MsgBuf *reconstruct_tail_prep(char *line, size_t n)
{
static struct MsgBuf msgbuf;
msgbuf_init(&msgbuf);
msgbuf_parse(&msgbuf, line);
msgbuf_reconstruct_tail(&msgbuf, n);
return &msgbuf;
}

static void reconstruct_tail(void)
{
struct MsgBuf *mb;
mb = reconstruct_tail_prep((char[]){"CMD P1"}, 2);
is_string("CMD", mb->para[0], MSG);
is_string("P1", mb->para[1], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 P2"}, 2);
is_string("CMD", mb->para[0], MSG);
is_string("P1", mb->para[1], MSG);
is_string("P2", mb->para[2], MSG);

mb = reconstruct_tail_prep((char[]){" CMD P1 P2 :P3"}, 0);
is_string("CMD P1 P2 :P3", mb->para[0], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 P2 :P3"}, 1);
is_string(" P1 P2 :P3", mb->para[1], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 P2"}, 1);
is_string("P1 P2", mb->para[1], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 P2 "}, 2);
is_string(" P2 ", mb->para[2], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 "}, 2);
is_string(" ", mb->para[2], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 :"}, 2);
is_string(":", mb->para[2], MSG);

mb = reconstruct_tail_prep((char[]){"CMD P1 :"}, 2);
is_string(" :", mb->para[2], MSG);
}

int main(int argc, char *argv[])
{
memset(&me, 0, sizeof(me));
Expand Down Expand Up @@ -3411,5 +3454,7 @@ int main(int argc, char *argv[])

unescape_8bit();

reconstruct_tail();

return 0;
}

0 comments on commit 860d238

Please sign in to comment.