Re: [xml] No stat, no catalog.



In message <000501c14a0d$608ce040$4c09a8c0 home loc>
          Igor Zlatkovic <igor stud fh-frankfurt de> wrote:

Hello everyone.

Again we have an issue regarding HAVE_STAT. Somewhere in catalog.c, in the
function xmlLoadCatalog, we can find the following lines:


    #ifdef HAVE_STAT
        if (stat(filename, &info) < 0)
        return(-1);
    #endif


Later in the same function we can see the following:


    content = xmlMalloc(info.st_size + 10);


If HAVE_STAT is not defined, the local variable 'info' remains
uninitialised. This leads to a problem, because the actual value of what we
pass into xmlMalloc is unpredictable in this case. Unfortunately, the proper
operation of the code that follows depends on successful execution of the
stat function.

If there is no alternative portable way to discover the size of the file
'filename', I would suggest to either make the catalog feature dependent on
the availability of the function stat, or let the xmlLoadCatalog function
fail if the function stat is not available. The way things are, the
successful execution of the xmlLoadCatalog function depends on nothing but
luck, if HAVE_STAT is undefined.

For the RISC OS version of this routine, we have a rather large collection
of somewhat unrelated conditionals. Primarily, RISC OS does not have a stat
routine in its standard library, so I don't use one - I prefer to use the
core C library alone. Similarly, there are no open/close/read/write
routines.

Thus, we assume that if no stat function exists, we must resort to the
standard filing system calls. Thus, the xmlLoadCatalog routine becomes to
following section. Apologies for the size of this section, but very little
is gained by making this into a diff.

Obviously this is not directly related to Igor's comments, but I feel that
the ability to fall back on functions that are known to exist has got to
be worthwhile :-)

--8<--------
int
xmlLoadCatalog(const char *filename) {
#ifdef HAVE_STAT
    int fd;
#else
    FILE *fd;
#endif
    int len, ret, i;
    long size;
#ifdef HAVE_STAT
    struct stat info;
#endif
    xmlChar *content;

    if (filename == NULL)
        return(-1);

    if (xmlDefaultCatalog == NULL)
        xmlDefaultCatalog = xmlHashCreate(20);
    if (xmlDefaultCatalog == NULL)
        return(-1);

    /*
     * Need to be done after ...
     */
    if (!xmlCatalogInitialized)
        xmlInitializeCatalog();

#ifdef HAVE_STAT
    if (stat(filename, &info) < 0)
        return(-1);
#endif

    /*
     * Prevent loops
     */
    for (i = 0;i < catalNr;i++) {
        if (xmlStrEqual((const xmlChar *)catalTab[i],
                        (const xmlChar *)filename)) {
            xmlGenericError(xmlGenericErrorContext,
                "xmlLoadCatalog: %s seems to induce a loop\n",
                            filename);
            return(-1);
        }
    }
    if (catalNr >= catalMax) {
        xmlGenericError(xmlGenericErrorContext,
            "xmlLoadCatalog: %s catalog list too deep\n",
                        filename);
            return(-1);
    }
    catalTab[catalNr++] = filename;

#ifdef HAVE_STAT
    if ((fd = open(filename, O_RDONLY)) < 0) {
#else
    if ((fd = fopen(riscosfilename(filename), "rb")) == NULL) {
#endif
        catalNr--;
        return(-1);
    }

#ifdef HAVE_STAT
    size=info.st_size;
#else
    if (fseek(fd, 0, SEEK_END) ||
        (size=ftell(fd))==EOF ||
        fseek(fd, 0, SEEK_SET))
    { /* File operations denied? ok, just close and return failure */
      fclose(fd);
      return(-1);
    }
#endif
    content = xmlMalloc(size + 10);
    if (content == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                "realloc of %d byte failed\n", size + 10);
        catalNr--;
        return(-1);
    }
#ifdef HAVE_STAT
    len = read(fd, content, size);
#else
    len = fread(content, 1, size, fd);
#endif
    if (len < 0) {
        xmlFree(content);
        catalNr--;
        return(-1);
    }
    content[len] = 0;
#ifdef HAVE_STAT
    close(fd);
#else
    fclose(fd);
#endif

    if ((content[0] == ' ') || (content[0] == '-') ||
        ((content[0] >= 'A') && (content[0] <= 'Z')) ||
        ((content[0] >= 'a') && (content[0] <= 'z')))
        ret = xmlParseSGMLCatalog(content, filename);
    else {
        xmlCatalogEntryPtr catal, tmp;
        /* TODO: allow to switch the default preference */
        catal = xmlParseXMLCatalog(content, XML_CATA_PREFER_PUBLIC, filename);
        if (catal != NULL) {
            if (xmlDefaultXMLCatalogList == NULL)
                xmlDefaultXMLCatalogList = catal;
            else {
                tmp = xmlDefaultXMLCatalogList;
                while (tmp->next != NULL)
                    tmp = tmp->next;
                tmp->next = catal;
            }
            ret = 0;
        } else
            ret = -1;
    }
    xmlFree(content);
    catalNr--;
    return(ret);
}
--8<--------

-- 
Gerph {djf0-.3w6e2w2.226,6q6w2q2,2.3,2m4}
URL: http://www.movspclr.co.uk/
... Eyes to the heavens, screaming at the sky;
    Trying to send you messages, but choking on goodbye.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]