Merge pull request #345 from edk0/alias
m_alias: Preserve protocol framing characters
This commit is contained in:
commit
860d2381cf
4 changed files with 91 additions and 4 deletions
|
@ -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]) */
|
||||
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
@ -3411,5 +3454,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
unescape_8bit();
|
||||
|
||||
reconstruct_tail();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue