cant store article: bogus Xref: header in INN 2.5 ?
Julien ÉLIE
julien at trigofacile.com
Thu Sep 1 18:23:43 UTC 2011
Hi Russ,
>> It would be better to find out why two spaces are inserted, instead of
>> modifying CrackXref to handle that weirdness.
>
> It would be nice to fix both, but in general we shouldn't be this picky
> about whitespace. It's pretty easy to skip over leading whitespace in
> that header, and in general RFC 5322 headers are not supposed to care
> about whitespace. The RFC 5536 grammar also explicitly allows leading
> whitespace:
>
> The Xref header field indicates where an article was filed by the last
> news server to process it. User agents often use the information in
> the Xref header field to avoid multiple processing of crossposted
> articles.
>
> xref = "Xref:" SP *WSP server-name
> 1*( FWS location ) *WSP CRLF
Yes, you're totally right. We should fix how the Xref: header is parsed
by tradspool.
A slave INN server could be fed by another news server so we cannot assume any
restrictive syntax for the Xref: header field.
Besides, even when the upstream server is INN, there is an issue with the Xref:
parsing because of folding whitespace that is not taken into account (innd
properly folds the Xref: header it generates in ARTassignnumbers).
Suggested fix for INN 2.5.3:
--- storage/tradspool/tradspool.c (r?vision 9364)
+++ storage/tradspool/tradspool.c (copie de travail)
@@ -578,18 +578,21 @@
xrefsize = 5;
xrefs = xmalloc(xrefsize * sizeof(char *));
- /* no path element should exist, nor heading white spaces exist */
p = xref;
+
+ /* Skip leading whitespaces. As no path element should exist,
+ * p will point to the beginning of the server name. */
+ for ( ; ISWHITE(*p) ; p++);
+
while (true) {
/* check for EOL */
- /* shouldn't ever hit null w/o hitting a \r\n first, but best to be paranoid */
- if (*p == '\n' || *p == '\r' || *p == 0) {
+ if (*p == '\n' || *p == '\r' || *p == '\0') {
/* hit EOL, return. */
*lenp = len;
return xrefs;
}
/* skip to next space or EOL */
- for (q=p; *q && *q != ' ' && *q != '\n' && *q != '\r' ; ++q) ;
+ for (q=p; *q && (! ISWHITE(*q)) && *q != '\n' && *q != '\r' ; ++q) ;
xrefs[len] = xstrndup(p, q - p);
@@ -599,9 +602,8 @@
xrefs = xrealloc(xrefs, xrefsize * sizeof(char *));
}
- p = q;
- /* skip spaces */
- for ( ; *p == ' ' ; p++) ;
+ /* Skip whitespaces, possibly folded. */
+ p = (char *) skip_fws(q);
}
}
That is to say, the whole function would be:
/*
** Crack an Xref: line apart into separate strings, each of the form "ng:artnum".
** Return in "num" the number of newsgroups found.
*/
static char **
CrackXref(char *xref, unsigned int *lenp) {
char *p;
char **xrefs;
char *q;
unsigned int len, xrefsize;
len = 0;
xrefsize = 5;
xrefs = xmalloc(xrefsize * sizeof(char *));
p = xref;
/* Skip leading whitespaces. As no path element should exist,
* p will point to the beginning of the server name. */
for ( ; ISWHITE(*p) ; p++);
while (true) {
/* check for EOL */
if (*p == '\n' || *p == '\r' || *p == '\0') {
/* hit EOL, return. */
*lenp = len;
return xrefs;
}
/* skip to next space or EOL */
for (q=p; *q && (! ISWHITE(*q)) && *q != '\n' && *q != '\r' ; ++q) ;
xrefs[len] = xstrndup(p, q - p);
if (++len == xrefsize) {
/* grow xrefs if needed. */
xrefsize *= 2;
xrefs = xrealloc(xrefs, xrefsize * sizeof(char *));
}
/* Skip whitespaces, possibly folded. */
p = (char *) skip_fws(q);
}
}
It seems to work fine. (I successfully stored articles posted to 1, 2
and 3 newsgroups in tradspool.)
--
Julien ÉLIE
« Un voyage de mille lieues commence toujours par un premier pas. »
(Lao Zi)
More information about the inn-workers
mailing list