m_alias: Preserve protocol framing characters
This commit is contained in:
parent
3ef1213be4
commit
4e14f9a413
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 *origin; /* the origin of the message (or NULL) */
|
||||||
const char *target; /* the target of the message (either NULL, or custom defined) */
|
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]) */
|
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) */
|
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]) */
|
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);
|
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.
|
* unparse a pure MsgBuf into a buffer.
|
||||||
* if origin is NULL, me.name will be used.
|
* if origin is NULL, me.name will be used.
|
||||||
|
|
|
@ -154,6 +154,7 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
|
||||||
if (*ch == '\0')
|
if (*ch == '\0')
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
msgbuf->endp = &ch[strlen(ch)];
|
||||||
msgbuf->n_para = rb_string_to_array(ch, (char **)msgbuf->para, MAXPARA);
|
msgbuf->n_para = rb_string_to_array(ch, (char **)msgbuf->para, MAXPARA);
|
||||||
if (msgbuf->n_para == 0)
|
if (msgbuf->n_para == 0)
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -162,6 +163,40 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line)
|
||||||
return 0;
|
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
|
* Unparse msgbuf tags into a buffer
|
||||||
* returns the length of the tags written
|
* 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 Client *target_p;
|
||||||
struct alias_entry *aptr = rb_dictionary_retrieve(alias_dict, msgbuf->cmd);
|
struct alias_entry *aptr = rb_dictionary_retrieve(alias_dict, msgbuf->cmd);
|
||||||
char *p, *str;
|
char *p;
|
||||||
|
|
||||||
if(aptr == NULL)
|
if(aptr == NULL)
|
||||||
{
|
{
|
||||||
|
@ -151,8 +151,8 @@ m_alias(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = reconstruct_parv(parc - 1, &parv[1]);
|
msgbuf_reconstruct_tail(msgbuf, 1);
|
||||||
if(EmptyString(str))
|
if(EmptyString(parv[1]))
|
||||||
{
|
{
|
||||||
sendto_one(client_p, form_str(ERR_NOTEXTTOSEND), me.name, target_p->name);
|
sendto_one(client_p, form_str(ERR_NOTEXTTOSEND), me.name, target_p->name);
|
||||||
return;
|
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",
|
sendto_one(target_p, ":%s PRIVMSG %s :%s",
|
||||||
get_id(client_p, target_p),
|
get_id(client_p, target_p),
|
||||||
p != NULL ? aptr->target : get_id(target_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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
memset(&me, 0, sizeof(me));
|
memset(&me, 0, sizeof(me));
|
||||||
|
@ -3411,5 +3454,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
unescape_8bit();
|
unescape_8bit();
|
||||||
|
|
||||||
|
reconstruct_tail();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue