Beispiel #1
0
void *
xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
{
    MEMHDR *p;
    unsigned long number;

    if (!xmlMemInitialized) xmlInitMemory();
    if (ptr == NULL)
        return(NULL);
    TEST_POINT

    p = CLIENT_2_HDR(ptr);
    number = p->mh_number;
    if (p->mh_tag != MEMTAG) {
       Mem_Tag_Err(p);
	 goto error;
    }
    p->mh_tag = ~MEMTAG;
    debugMemSize -= p->mh_size;
#ifdef MEM_LIST
    debugmem_list_delete(p);
#endif

    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
    if (!p) {
	 goto error;
    }
    if (xmlMemTraceBlockAt == ptr) {
	xmlGenericError(xmlGenericErrorContext,
			"%p : Realloced(%d -> %d) Ok\n",
			xmlMemTraceBlockAt, p->mh_size, size);
	xmlMallocBreakpoint();
    }
    p->mh_tag = MEMTAG;
    p->mh_number = number;
    p->mh_type = REALLOC_TYPE;
    p->mh_size = size;
    p->mh_file = file;
    p->mh_line = line;
    debugMemSize += size;
    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
    debugmem_list_add(p);
#endif

    TEST_POINT

    return(HDR_2_CLIENT(p));
    
error:    
    return(NULL);
}
Beispiel #2
0
static void
testRegexpFile(const char *filename) {
    xmlRegexpPtr comp = NULL;
    FILE *input;
    char expression[5000];
    int len;

    input = fopen(filename, "r");
    if (input == NULL) {
        xmlGenericError(xmlGenericErrorContext,
		"Cannot open %s for reading\n", filename);
	return;
    }
    while (fgets(expression, 4500, input) != NULL) {
	len = strlen(expression);
	len--;
	while ((len >= 0) &&
	       ((expression[len] == '\n') || (expression[len] == '\t') ||
		(expression[len] == '\r') || (expression[len] == ' '))) len--;
	expression[len + 1] = 0;
	if (len >= 0) {
	    if (expression[0] == '#')
		continue;
	    if ((expression[0] == '=') && (expression[1] == '>')) {
		char *pattern = &expression[2];

		if (comp != NULL) {
		    xmlRegFreeRegexp(comp);
		    comp = NULL;
		}
		printf("Regexp: %s\n", pattern) ;
		comp = xmlRegexpCompile((const xmlChar *) pattern);
		if (comp == NULL) {
		    printf("   failed to compile\n");
		    break;
		}
	    } else if (comp == NULL) {
		printf("Regexp: %s\n", expression) ;
		comp = xmlRegexpCompile((const xmlChar *) expression);
		if (comp == NULL) {
		    printf("   failed to compile\n");
		    break;
		}
	    } else if (comp != NULL) {
		testRegexp(comp, expression);
	    }
	}
    }
    fclose(input);
    if (comp != NULL)
	xmlRegFreeRegexp(comp);
}
Beispiel #3
0
xmlChar *
xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
  static int deprecated = 0;

  if (!deprecated)
  {
    xmlGenericError(xmlGenericErrorContext,
                    "xmlNamespaceParseNCName() deprecated function reached\n");
    deprecated = 1;
  }
  return (NULL);
}
Beispiel #4
0
/**
 * xmlInitMemory:
 *
 * Initialize the memory layer.
 *
 * Returns 0 on success
 */
int
xmlInitMemory(void)
{
#ifdef HAVE_STDLIB_H
  char *breakpoint;
#endif
#ifdef DEBUG_MEMORY
  xmlGenericError(xmlGenericErrorContext,
                  "xmlInitMemory()\n");
#endif
  /*
   This is really not good code (see Bug 130419).  Suggestions for
   improvement will be welcome!
  */
  if (xmlMemInitialized) return(-1);
  xmlMemInitialized = 1;
  xmlMemMutex = xmlNewMutex();

#ifdef HAVE_STDLIB_H
  breakpoint = getenv("XML_MEM_BREAKPOINT");
  if (breakpoint != NULL)
  {
    sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
  }
#endif
#ifdef HAVE_STDLIB_H
  breakpoint = getenv("XML_MEM_TRACE");
  if (breakpoint != NULL)
  {
    sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
  }
#endif

#ifdef DEBUG_MEMORY
  xmlGenericError(xmlGenericErrorContext,
                  "xmlInitMemory() Ok\n");
#endif
  return(0);
}
Beispiel #5
0
char *
xmlMemStrdupLoc(const char *str, const char *file, int line)
{
    char *s;
    size_t size = strlen(str) + 1;
    MEMHDR *p;

    if (!xmlMemInitialized) xmlInitMemory();
    TEST_POINT

    p = (MEMHDR *) malloc(RESERVE_SIZE+size);
    if (!p) {
      goto error;
    }
    p->mh_tag = MEMTAG;
    p->mh_size = size;
    p->mh_type = STRDUP_TYPE;
    p->mh_file = file;
    p->mh_line = line;
    xmlMutexLock(xmlMemMutex);
    p->mh_number = ++block;
    debugMemSize += size;
    debugMemBlocks++;
    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
    debugmem_list_add(p);
#endif
    xmlMutexUnlock(xmlMemMutex);
    
    s = (char *) HDR_2_CLIENT(p);
    
    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();

    if (s != NULL)
      strcpy(s,str);
    else
      goto error;
    
    TEST_POINT

    if (xmlMemTraceBlockAt == s) {
        xmlGenericError(xmlGenericErrorContext,
                        "%p : Strdup() Ok\n", xmlMemTraceBlockAt);
        xmlMallocBreakpoint();
    }

    return(s);

error:
    return(NULL);
}
int
xmlNanoFTPQuit(void *ctx) {
    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
    char buf[200];
    int len;
    int res;

    sprintf(buf, "QUIT\r\n");
    len = strlen(buf);
#ifdef DEBUG_FTP
    xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
#endif
    res = send(ctxt->controlFd, buf, len, 0);
    return(0);
}
/**
 * htmlDecodeEntities:
 * @ctxt:  the parser context
 * @len:  the len to decode (in bytes !), -1 for no size limit
 * @end:  an end marker xmlChar, 0 if none
 * @end2:  an end marker xmlChar, 0 if none
 * @end3:  an end marker xmlChar, 0 if none
 *
 * Substitute the HTML entities by their value
 *
 * DEPRECATED !!!!
 *
 * Returns A newly allocated string with the substitution done. The caller
 *      must deallocate it !
 */
xmlChar *
htmlDecodeEntities(htmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                   int len ATTRIBUTE_UNUSED, xmlChar end ATTRIBUTE_UNUSED,
                   xmlChar end2 ATTRIBUTE_UNUSED,
                   xmlChar end3 ATTRIBUTE_UNUSED)
{
    static int deprecated = 0;

    if (!deprecated) {
        xmlGenericError(xmlGenericErrorContext,
                        "htmlDecodeEntities() deprecated function reached\n");
        deprecated = 1;
    }
    return (NULL);
}
Beispiel #8
0
/**
 * xmlBufDump:
 * @file:  the file output
 * @buf:  the buffer to dump
 *
 * Dumps an XML buffer to  a FILE *.
 * Returns the number of #xmlChar written
 */
size_t
xmlBufDump(FILE *file, xmlBufPtr buf) {
    size_t ret;

    if ((buf == NULL) || (buf->error != 0)) {
#ifdef DEBUG_BUFFER
        xmlGenericError(xmlGenericErrorContext,
		"xmlBufDump: buf == NULL or in error\n");
#endif
	return(0);
    }
    if (buf->content == NULL) {
#ifdef DEBUG_BUFFER
        xmlGenericError(xmlGenericErrorContext,
		"xmlBufDump: buf->content == NULL\n");
#endif
	return(0);
    }
    CHECK_COMPAT(buf)
    if (file == NULL)
	file = stdout;
    ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
    return(ret);
}
Beispiel #9
0
/**
 * xmlIsMainThread:
 *
 * xmlIsMainThread() check whether the current thread is the main thread.
 *
 * Returns 1 if the current thread is the main thread, 0 otherwise
 */
XMLPUBFUNEXPORT int
xmlIsMainThread(void)
{
#ifdef HAVE_PTHREAD_H
    pthread_once(&once_control, xmlOnceInit);
#endif

#ifdef DEBUG_THREADS
    xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
#endif
#ifdef HAVE_PTHREAD_H
    return(mainthread == pthread_self());
#else
    return(1);
#endif
}
Beispiel #10
0
/**
 * @arg str the XPath expression
 * @arg ctxt the XPath context
 * @arg pctxt pointer to a XPath Parser context pointer
 *
 * Evaluate the XPath expression in the given context.  The XPath Parser
 * context is saved in pctxt, so that it can be accessed from another thread.
 * Especially the error state is interesting, since it can be used to stop a
 * never ending evaluation.
 *
 * Taken from xpath.c in libxml2-2.6.16.
 *
 * @return the xmlXPathObjectPtr resulting from the evaluation or NULL.
 *         The caller has to free the object.
 */
xmlXPathObjectPtr
my_xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt, xmlXPathParserContextPtr *pctxt) {
    xmlXPathObjectPtr res, tmp;
    int stack = 0;

    xmlXPathInit();

    // it is nice that gcc gives no warning anymore,
    // but the bad thing is that *pctxt normally is still NULL at this point
    CHECK_CONTEXT(ctxt,*pctxt)

    g_mutex_lock(find_nodeset_pcontext_mutex);
    //g_printerr("Allocating parser context\n");
    *pctxt = xmlXPathNewParserContext(str, ctxt);
    g_mutex_unlock(find_nodeset_pcontext_mutex);

    xmlXPathEvalExpr(*pctxt);

    if (*(*pctxt)->cur != 0) {
        xmlXPatherror(*pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
        res = NULL;
    } else {
        res = valuePop(*pctxt);
    }
    do {
        tmp = valuePop(*pctxt);
        if (tmp != NULL) {
            xmlXPathFreeObject(tmp);
            stack++;
        }
    } while (tmp != NULL);
    if ((stack != 0) && (res != NULL)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlXPathEvalExpression: %d object left on the stack\n",
                stack);
    }

    g_mutex_lock(find_nodeset_pcontext_mutex);
    xmlXPathFreeParserContext(*pctxt);
    *pctxt = NULL;
    //g_printerr("Freed parser context\n");
    g_mutex_unlock(find_nodeset_pcontext_mutex);

    return(res);
}
Beispiel #11
0
/**
 * Write the xml document out to a file descriptor.
 * @param   xml The xml document
 * @param   fd The xml output descriptor
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Write_Group
 */
int exml_fd_write(EXML *xml, int fd)
{
	xmlTextWriterPtr writer;
	xmlOutputBufferPtr out;

	out = xmlOutputBufferCreateFd(fd, NULL);
	if (out == NULL) {
		xmlGenericError(xmlGenericErrorContext,
										"xmlNewTextWriterFd : out of memory!\n");
		return FALSE;
	}

	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);

	writer = xmlNewTextWriter( out );

	return _exml_write(xml, writer);
}
Beispiel #12
0
/**
 * xmlNanoFTPRead:
 * @ctx:  the FTP context
 * @dest:  a buffer
 * @len:  the buffer length
 *
 * This function tries to read @len bytes from the existing FTP connection
 * and saves them in @dest. This is a blocking call.
 *
 * Returns the number of byte read. 0 is an indication of an end of connection.
 *         -1 indicates a parameter error.
 */
int
xmlNanoFTPRead(void *ctx, void *dest, int len) {
    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;

    if (ctx == NULL) return(-1);
    if (ctxt->dataFd < 0) return(0);
    if (dest == NULL) return(-1);
    if (len <= 0) return(0);

    len = recv(ctxt->dataFd, dest, len, 0);
#ifdef DEBUG_FTP
    xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
#endif
    if (len <= 0) {
	xmlNanoFTPCloseConnection(ctxt);
    }
    return(len);
}
Beispiel #13
0
/**
 * xmlUTF8Strndup:
 * @utf:  the input UTF8 *
 * @len:  the len of @utf (in chars)
 *
 * a strndup for array of UTF8's
 *
 * Returns a new UTF8 * or NULL
 */
xmlChar *
xmlUTF8Strndup(const xmlChar *utf, int len) {
    xmlChar *ret;
    int i;

    if ((utf == NULL) || (len < 0)) return(NULL);
    i = xmlUTF8Strsize(utf, len);
    ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar));
    if (ret == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                "malloc of %ld byte failed\n",
                (len + 1) * (long)sizeof(xmlChar));
        return(NULL);
    }
    memcpy(ret, utf, i * sizeof(xmlChar));
    ret[i] = 0;
    return(ret);
}
Beispiel #14
0
/**
 * xmlListPushBack:
 * @param l a list
 * @param data new data
 *
 * add the new data at the end of the list
 *
 * Returns 1 if successful, 0 otherwise
 */
int
xmlListPushBack(xmlListPtr list, void *data)
{
    xmlLinkPtr lkPlace, lkNew;

    lkPlace = list->sentinel->prev;
    /* Add the new link */
    if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
        xmlGenericError(xmlGenericErrorContext,
                        EMBED_ERRTXT("Cannot initialize memory for new link"));
        return (0);
    }
    lkNew->data = data;
    lkNew->next = lkPlace->next;
    (lkPlace->next)->prev = lkNew;
    lkPlace->next = lkNew;
    lkNew->prev = lkPlace;
    return 1;
}
Beispiel #15
0
/**
 * xmlListAppend:
 * @param l a list
 * @param data the data
 *
 * Insert data in the ordered list at the end for this value
 *
 * Returns 0 in case of success, 1 in case of failure
 */
XMLPUBFUNEXPORT int xmlListAppend(xmlListPtr list, void *data)
{
    xmlLinkPtr lkPlace, lkNew;

    lkPlace = xmlListHigherSearch(list, data);
    /* Add the new link */
    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
    if (lkNew == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        EMBED_ERRTXT("Cannot initialize memory for new link"));
        return (0);
    }
    lkNew->data = data;
    lkNew->next = lkPlace->next;
    (lkPlace->next)->prev = lkNew;
    lkPlace->next = lkNew;
    lkNew->prev = lkPlace;
    return 1;
}
Beispiel #16
0
/**
 * xmlBufFree:
 * @buf:  the buffer to free
 *
 * Frees an XML buffer. It frees both the content and the structure which
 * encapsulate it.
 */
void
xmlBufFree(xmlBufPtr buf) {
    if (buf == NULL) {
#ifdef DEBUG_BUFFER
        xmlGenericError(xmlGenericErrorContext,
		"xmlBufFree: buf == NULL\n");
#endif
	return;
    }

    if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
        (buf->contentIO != NULL)) {
        xmlFree(buf->contentIO);
    } else if ((buf->content != NULL) &&
        (buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)) {
        xmlFree(buf->content);
    }
    xmlFree(buf);
}
Beispiel #17
0
/**
 * xmlListPushFront:
 * @l:  a list
 * @data:  new data
 *
 * add the new data at the beginning of the list
 *
 * Returns 1 if successful, 0 otherwise
 */
int
xmlListPushFront(xmlListPtr l, void *data) 
{
    xmlLinkPtr lkPlace, lkNew;

    lkPlace = l->sentinel;
    /* Add the new link */
    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
    if (lkNew == NULL) {
        xmlGenericError(xmlGenericErrorContext, 
		        "Cannot initialize memory for new link");
        return (0);
    }
    lkNew->data = data;
    lkNew->next = lkPlace->next;
    (lkPlace->next)->prev = lkNew;
    lkPlace->next = lkNew;
    lkNew->prev = lkPlace;
    return 1;
}
Beispiel #18
0
static int
xmlNanoFTPSendPasswd(void *ctx) {
    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
    char buf[200];
    int len;
    int res;

    if (ctxt->passwd == NULL)
	snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
    else
	snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
    buf[sizeof(buf) - 1] = 0;
    len = strlen(buf);
#ifdef DEBUG_FTP
    xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
    res = send(ctxt->controlFd, buf, len, 0);
    if (res < 0) return(res);
    return(0);
}
/**
 * xmlXIncludeIncludeNode:
 * @ctxt: an XInclude context
 * @nr: the node number
 *
 * Inplement the infoset replacement for the given node
 *
 * Returns 0 if substitution succeeded, -1 if some processing failed
 */
static int
xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
    xmlNodePtr cur, end, list;

    if (ctxt == NULL)
        return(-1);
    if ((nr < 0) || (nr >= ctxt->incNr))
        return(-1);
    cur = ctxt->incTab[nr];
    if (cur == NULL)
        return(-1);

    /*
     * Change the current node as an XInclude start one, and add an
     * entity end one
     */
    cur->type = XML_XINCLUDE_START;
    end = xmlNewNode(cur->ns, cur->name);
    if (end == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "XInclude: failed to build node\n");
        return(-1);
    }
    end->type = XML_XINCLUDE_END;
    xmlAddNextSibling(cur, end);

    /*
     * Add the list of nodes
     */
    list = ctxt->repTab[nr];
    ctxt->repTab[nr] = NULL;
    while (list != NULL) {
        cur = list;
        list = list->next;

        xmlAddPrevSibling(end, cur);
    }


    return(0);
}
Beispiel #20
0
/**
 * xmlListAppend:
 * @l:  a list
 * @data:  the data
 *
 * Insert data in the ordered list at the end for this value
 *
 * Returns 0 in case of success, 1 in case of failure
 */
int xmlListAppend(xmlListPtr l, void *data) 
{
    xmlLinkPtr lkPlace, lkNew;

    if (l == NULL)
        return(1);
    lkPlace = xmlListHigherSearch(l, data);
    /* Add the new link */
    lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
    if (lkNew == NULL) {
        xmlGenericError(xmlGenericErrorContext, 
		        "Cannot initialize memory for new link");
        return (1);
    }
    lkNew->data = data;
    lkNew->next = lkPlace->next;
    (lkPlace->next)->prev = lkNew;
    lkPlace->next = lkNew;
    lkNew->prev = lkPlace;
    return 0;
}
Beispiel #21
0
/**
 * xmlBufAdd:
 * @buf:  the buffer to dump
 * @str:  the #xmlChar string
 * @len:  the number of #xmlChar to add
 *
 * Add a string range to an XML buffer. if len == -1, the length of
 * str is recomputed.
 *
 * Returns 0 successful, a positive error code number otherwise
 *         and -1 in case of internal or API error.
 */
int
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
    unsigned int needSize;

    if ((str == NULL) || (buf == NULL) || (buf->error))
	return -1;
    CHECK_COMPAT(buf)

    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
    if (len < -1) {
#ifdef DEBUG_BUFFER
        xmlGenericError(xmlGenericErrorContext,
		"xmlBufAdd: len < 0\n");
#endif
	return -1;
    }
    if (len == 0) return 0;

    if (len < 0)
        len = xmlStrlen(str);

    if (len < 0) return -1;
    if (len == 0) return 0;

    needSize = buf->use + len + 2;
    if (needSize > buf->size){
        if (!xmlBufResize(buf, needSize)){
	    xmlBufMemoryError(buf, "growing buffer");
            return XML_ERR_NO_MEMORY;
        }
    }

    memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
    buf->use += len;
    buf->content[buf->use] = 0;
    UPDATE_COMPAT(buf)
    return 0;
}
Beispiel #22
0
int
xmlNanoFTPCloseConnection(void *ctx) {
    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
    int res;
    fd_set rfd, efd;
    struct timeval tv;

    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
    tv.tv_sec = 15;
    tv.tv_usec = 0;
    FD_ZERO(&rfd);
    FD_SET(ctxt->controlFd, &rfd);
    FD_ZERO(&efd);
    FD_SET(ctxt->controlFd, &efd);
    res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
    if (res < 0) {
#ifdef DEBUG_FTP
	perror("select");
#endif
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	return(-1);
    }
    if (res == 0) {
#ifdef DEBUG_FTP
	xmlGenericError(xmlGenericErrorContext,
		"xmlNanoFTPCloseConnection: timeout\n");
#endif
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
    } else {
	res = xmlNanoFTPGetResponse(ctxt);
	if (res != 2) {
	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	    return(-1);
	}
    }
    return(0);
}
Beispiel #23
0
int main(int argc, char **argv) {
    xmlGenericError(xmlGenericErrorContext,
	    "%s : HTTP support not compiled in\n", argv[0]);
    return(0);
}
Beispiel #24
0
void*
xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
                  char **contentType, char **redir,
		  const char *headers, int ilen ) {
    xmlNanoHTTPCtxtPtr ctxt;
    char *bp, *p;
    int blen;
    SOCKET ret;
    int nbRedirects = 0;
    char *redirURL = NULL;
#ifdef DEBUG_HTTP
    int xmt_bytes;
#endif
    
    if (URL == NULL) return(NULL);
    if (method == NULL) method = "GET";
    xmlNanoHTTPInit();

retry:
    if (redirURL == NULL)
	ctxt = xmlNanoHTTPNewCtxt(URL);
    else {
	ctxt = xmlNanoHTTPNewCtxt(redirURL);
	ctxt->location = xmlMemStrdup(redirURL);
    }

    if ( ctxt == NULL ) {
	return ( NULL );
    }

    if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
	__xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    if (ctxt->hostname == NULL) {
	__xmlIOErr(XML_FROM_HTTP, XML_HTTP_UNKNOWN_HOST,
	           "Failed to identify host in URI");
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    if (proxy) {
	blen = strlen(ctxt->hostname) * 2 + 16;
	ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
    }
    else {
	blen = strlen(ctxt->hostname);
	ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
    }
    if (ret == INVALID_SOCKET) {
        xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
        return(NULL);
    }
    ctxt->fd = ret;

    if (input == NULL)
	ilen = 0;
    else
	blen += 36;

    if (headers != NULL)
	blen += strlen(headers) + 2;
    if (contentType && *contentType)
	/* reserve for string plus 'Content-Type: \r\n" */
	blen += strlen(*contentType) + 16;
    if (ctxt->query != NULL)
	/* 1 for '?' */
	blen += strlen(ctxt->query) + 1;
    blen += strlen(method) + strlen(ctxt->path) + 24;
#ifdef HAVE_ZLIB_H
    /* reserve for possible 'Accept-Encoding: gzip' string */
    blen += 23;
#endif
    if (ctxt->port != 80) {
	/* reserve space for ':xxxxx', incl. potential proxy */
	if (proxy)
	    blen += 12;
	else
	    blen += 6;
    }
    bp = (char*)xmlMallocAtomic(blen);
    if ( bp == NULL ) {
        xmlNanoHTTPFreeCtxt( ctxt );
	xmlHTTPErrMemory("allocating header buffer");
	return ( NULL );
    }

    p = bp;

    if (proxy) {
	if (ctxt->port != 80) {
	    p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", 
			method, ctxt->hostname,
		 	ctxt->port, ctxt->path );
	}
	else 
	    p += snprintf( p, blen - (p - bp), "%s http://%s%s", method,
	    		ctxt->hostname, ctxt->path);
    }
    else
	p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path);

    if (ctxt->query != NULL)
	p += snprintf( p, blen - (p - bp), "?%s", ctxt->query);

    if (ctxt->port == 80) {
        p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n", 
		    ctxt->hostname);
    } else {
        p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s:%d\r\n",
		    ctxt->hostname, ctxt->port);
    }

#ifdef HAVE_ZLIB_H
    p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n");
#endif

    if (contentType != NULL && *contentType) 
	p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType);

    if (headers != NULL)
	p += snprintf( p, blen - (p - bp), "%s", headers );

    if (input != NULL)
	snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen );
    else
	snprintf(p, blen - (p - bp), "\r\n");

#ifdef DEBUG_HTTP
    xmlGenericError(xmlGenericErrorContext,
	    "-> %s%s", proxy? "(Proxy) " : "", bp);
    if ((blen -= strlen(bp)+1) < 0)
	xmlGenericError(xmlGenericErrorContext,
		"ERROR: overflowed buffer by %d bytes\n", -blen);
#endif
    ctxt->outptr = ctxt->out = bp;
    ctxt->state = XML_NANO_HTTP_WRITE;
    blen = strlen( ctxt->out );
#ifdef DEBUG_HTTP
    xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen );
    if ( xmt_bytes != blen )
        xmlGenericError( xmlGenericErrorContext,
			"xmlNanoHTTPMethodRedir:  Only %d of %d %s %s\n",
			xmt_bytes, blen,
			"bytes of HTTP headers sent to host",
			ctxt->hostname );
#else
    xmlNanoHTTPSend(ctxt, ctxt->out, blen );
#endif

    if ( input != NULL ) {
#ifdef DEBUG_HTTP
        xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen );

	if ( xmt_bytes != ilen )
	    xmlGenericError( xmlGenericErrorContext,
	    		"xmlNanoHTTPMethodRedir:  Only %d of %d %s %s\n",
			xmt_bytes, ilen,
			"bytes of HTTP content sent to host",
			ctxt->hostname );
#else
	xmlNanoHTTPSend( ctxt, input, ilen );
#endif
    }

    ctxt->state = XML_NANO_HTTP_READ;

    while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
        if (*p == 0) {
	    ctxt->content = ctxt->inrptr;
	    xmlFree(p);
	    break;
	}
	xmlNanoHTTPScanAnswer(ctxt, p);

#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
#endif
        xmlFree(p);
    }

    if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
        (ctxt->returnValue < 400)) {
#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext,
		"\nRedirect to: %s\n", ctxt->location);
#endif
	while ( xmlNanoHTTPRecv(ctxt) > 0 ) ;
        if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
	    nbRedirects++;
	    if (redirURL != NULL)
		xmlFree(redirURL);
	    redirURL = xmlMemStrdup(ctxt->location);
	    xmlNanoHTTPFreeCtxt(ctxt);
	    goto retry;
	}
	xmlNanoHTTPFreeCtxt(ctxt);
	if (redirURL != NULL) xmlFree(redirURL);
#ifdef DEBUG_HTTP
	xmlGenericError(xmlGenericErrorContext,
		"xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n");
#endif
	return(NULL);
    }

    if (contentType != NULL) {
	if (ctxt->contentType != NULL)
	    *contentType = xmlMemStrdup(ctxt->contentType);
	else
	    *contentType = NULL;
    }

    if ((redir != NULL) && (redirURL != NULL)) {
	*redir = redirURL;
    } else {
	if (redirURL != NULL)
	    xmlFree(redirURL);
	if (redir != NULL)
	    *redir = NULL;
    }

#ifdef DEBUG_HTTP
    if (ctxt->contentType != NULL)
	xmlGenericError(xmlGenericErrorContext,
		"\nCode %d, content-type '%s'\n\n",
	       ctxt->returnValue, ctxt->contentType);
    else
	xmlGenericError(xmlGenericErrorContext,
		"\nCode %d, no content-type\n\n",
	       ctxt->returnValue);
#endif

    return((void *) ctxt);
}
Beispiel #25
0
static SOCKET
xmlNanoHTTPConnectHost(const char *host, int port)
{
    struct hostent *h;
    struct sockaddr *addr = NULL;
    struct in_addr ia;
    struct sockaddr_in sockin;

#ifdef SUPPORT_IP6
    struct in6_addr ia6;
    struct sockaddr_in6 sockin6;
#endif
    int i;
    SOCKET s;

    memset (&sockin, 0, sizeof(sockin));
#ifdef SUPPORT_IP6
    memset (&sockin6, 0, sizeof(sockin6));
#endif

#if !defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && defined(RES_USE_INET6)
    if (have_ipv6 ())
    {
	if (!(_res.options & RES_INIT))
	    res_init();
	_res.options |= RES_USE_INET6;
    }
#endif

#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
    if (have_ipv6 ())
#endif
#if defined(HAVE_GETADDRINFO) && (defined(SUPPORT_IP6) || defined(_WIN32))
    {
	int status;
	struct addrinfo hints, *res, *result;

	result = NULL;
	memset (&hints, 0,sizeof(hints));
	hints.ai_socktype = SOCK_STREAM;

	status = getaddrinfo (host, NULL, &hints, &result);
	if (status) {
	    __xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");
	    return INVALID_SOCKET;
	}

	for (res = result; res; res = res->ai_next) {
	    if (res->ai_family == AF_INET) {
		if (res->ai_addrlen > sizeof(sockin)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    freeaddrinfo (result);
		    return INVALID_SOCKET;
		}
		memcpy (&sockin, res->ai_addr, res->ai_addrlen);
		sockin.sin_port = htons (port);
		addr = (struct sockaddr *)&sockin;
#ifdef SUPPORT_IP6
	    } else if (have_ipv6 () && (res->ai_family == AF_INET6)) {
		if (res->ai_addrlen > sizeof(sockin6)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    freeaddrinfo (result);
		    return INVALID_SOCKET;
		}
		memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
		sockin6.sin6_port = htons (port);
		addr = (struct sockaddr *)&sockin6;
#endif
	    } else
		continue;              /* for */

	    s = xmlNanoHTTPConnectAttempt (addr);
	    if (s != INVALID_SOCKET) {
		freeaddrinfo (result);
		return (s);
	    }
	}

	if (result)
	    freeaddrinfo (result);
    }
#endif
#if defined(HAVE_GETADDRINFO) && defined(SUPPORT_IP6) && !defined(_WIN32)
    else
#endif
#if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
    {
	h = gethostbyname (host);
	if (h == NULL) {

/*
 * Okay, I got fed up by the non-portability of this error message
 * extraction code. it work on Linux, if it work on your platform
 * and one want to enable it, send me the defined(foobar) needed
 */
#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)
	    const char *h_err_txt = "";

	    switch (h_errno) {
		case HOST_NOT_FOUND:
		    h_err_txt = "Authoritive host not found";
		    break;

		case TRY_AGAIN:
		    h_err_txt =
			"Non-authoritive host not found or server failure.";
		    break;

		case NO_RECOVERY:
		    h_err_txt =
			"Non-recoverable errors:  FORMERR, REFUSED, or NOTIMP.";
		    break;

		case NO_ADDRESS:
		    h_err_txt =
			"Valid name, no data record of requested type.";
		    break;

		default:
		    h_err_txt = "No error text defined.";
		    break;
	    }
	    __xmlIOErr(XML_FROM_HTTP, 0, h_err_txt);
#else
	    __xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");
#endif
	    return INVALID_SOCKET;
	}

	for (i = 0; h->h_addr_list[i]; i++) {
	    if (h->h_addrtype == AF_INET) {
		/* A records (IPv4) */
		if ((unsigned int) h->h_length > sizeof(ia)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    return INVALID_SOCKET;
		}
		memcpy (&ia, h->h_addr_list[i], h->h_length);
		sockin.sin_family = h->h_addrtype;
		sockin.sin_addr = ia;
		sockin.sin_port = (u_short)htons ((unsigned short)port);
		addr = (struct sockaddr *) &sockin;
#ifdef SUPPORT_IP6
	    } else if (have_ipv6 () && (h->h_addrtype == AF_INET6)) {
		/* AAAA records (IPv6) */
		if ((unsigned int) h->h_length > sizeof(ia6)) {
		    __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
		    return INVALID_SOCKET;
		}
		memcpy (&ia6, h->h_addr_list[i], h->h_length);
		sockin6.sin6_family = h->h_addrtype;
		sockin6.sin6_addr = ia6;
		sockin6.sin6_port = htons (port);
		addr = (struct sockaddr *) &sockin6;
#endif
	    } else
		break;              /* for */

	    s = xmlNanoHTTPConnectAttempt (addr);
	    if (s != INVALID_SOCKET)
		return (s);
	}
    }
#endif

#ifdef DEBUG_HTTP
    xmlGenericError(xmlGenericErrorContext,
                    "xmlNanoHTTPConnectHost:  unable to connect to '%s'.\n",
                    host);
#endif
    return INVALID_SOCKET;
}
Beispiel #26
0
/**
 * xmlDictGrow:
 * @param dict the dictionnary
 * @param size the new size of the dictionnary
 *
 * resize the dictionnary
 *
 * Returns 0 in case of success, -1 in case of failure
 *
 * OOM: possible --> returns -1, OOM is set
 */
static int
xmlDictGrow(xmlDictPtr dict, int size) {
    unsigned long key;
    int oldsize, i;
    xmlDictEntryPtr iter, next;
    struct _xmlDictEntry *olddict;
#ifdef DEBUG_GROW
    unsigned long nbElem = 0;
#endif

    if (!dict || size < 8 || size > 8 * 2048)
        return(-1);

    oldsize = dict->size;
    olddict = dict->dict;
    if (!olddict)
        return(-1);

    dict->dict = (xmlDictEntryPtr)xmlMalloc(size * sizeof(xmlDictEntry));
    if (!dict->dict) {
        dict->dict = olddict;
        return(-1);
    }
    memset(dict->dict, 0, size * sizeof(xmlDictEntry));
    dict->size = size;

    /*  If the two loops are merged, there would be situations where
    a new entry needs to allocated and data copied into it from
    the main dict. So instead, we run through the array twice, first
    copying all the elements in the main array (where we can't get
    conflicts) and then the rest, so we only free (and don't allocate)
    */
    for (i = 0; i < oldsize; i++)
    {
        if (olddict[i].valid == 0)
            continue;
        key = xmlDictComputeKey(olddict[i].name, olddict[i].len) % dict->size;
        memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
        dict->dict[key].next = NULL;
#ifdef DEBUG_GROW
        nbElem++;
#endif
    }

    for (i = 0; i < oldsize; i++)
    {
        iter = olddict[i].next;
        while (iter) {
            next = iter->next;
            /*
            * put back the entry in the new dict
            */
            key = xmlDictComputeKey(iter->name, iter->len) % dict->size;
            if (dict->dict[key].valid == 0) {
                memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
                dict->dict[key].next = NULL;
                dict->dict[key].valid = 1;
                xmlFree(iter);
            } else {
                iter->next = dict->dict[key].next;
                dict->dict[key].next = iter;
            }
#ifdef DEBUG_GROW
            nbElem++;
#endif
            iter = next;
        } // while (iter)
    } // for (i = 0; i < oldsize; i++)

    xmlFree(olddict);

#ifdef DEBUG_GROW
    xmlGenericError(xmlGenericErrorContext,
        "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
#endif

    return(0);
}
Beispiel #27
0
/**
 * xmlMemFree:
 * @ptr:  the memory block pointer
 *
 * a free() equivalent, with error checking.
 */
void
xmlMemFree(void *ptr)
{
    MEMHDR *p;
    char *target;
#ifdef DEBUG_MEMORY
    size_t size;
#endif

    if (ptr == (void *) -1) {
        xmlGenericError(xmlGenericErrorContext,
            "trying to free pointer from freed area\n");
        goto error;
    }

    if (xmlMemTraceBlockAt == ptr) {
        xmlGenericError(xmlGenericErrorContext,
                        "%p : Freed()\n", xmlMemTraceBlockAt);
        xmlMallocBreakpoint();
    }

    TEST_POINT

    target = (char *) ptr;

    p = CLIENT_2_HDR(ptr);
    if (p->mh_tag != MEMTAG) {
        Mem_Tag_Err(p);
        goto error;
    }
    if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
    p->mh_tag = ~MEMTAG;
    memset(target, -1, p->mh_size);
    xmlMutexLock(xmlMemMutex);
    debugMemSize -= p->mh_size;
    debugMemBlocks--;
#ifdef DEBUG_MEMORY
    size = p->mh_size;
#endif
#ifdef MEM_LIST
    debugmem_list_delete(p);
#endif
    xmlMutexUnlock(xmlMemMutex);

    free(p);

    TEST_POINT

#ifdef DEBUG_MEMORY
    xmlGenericError(xmlGenericErrorContext,
            "Freed(%d) Ok\n", size);
#endif
    
    return;
    
error:    
    xmlGenericError(xmlGenericErrorContext,
            "xmlMemFree(%lX) error\n", (unsigned long) ptr);
    xmlMallocBreakpoint();
    return;
}
Beispiel #28
0
void
xmlMallocBreakpoint(void) {
    xmlGenericError(xmlGenericErrorContext,
            "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
}
Beispiel #29
0
/**
 * xmlDictGrow:
 * @dict: the dictionary
 * @size: the new size of the dictionary
 *
 * resize the dictionary
 *
 * Returns 0 in case of success, -1 in case of failure
 */
static int
xmlDictGrow(xmlDictPtr dict, size_t size) {
    unsigned long key, okey;
    size_t oldsize, i;
    xmlDictEntryPtr iter, next;
    struct _xmlDictEntry *olddict;
#ifdef DEBUG_GROW
    unsigned long nbElem = 0;
#endif
    int ret = 0;
    int keep_keys = 1;

    if (dict == NULL)
	return(-1);
    if (size < 8)
        return(-1);
    if (size > 8 * 2048)
	return(-1);

#ifdef DICT_DEBUG_PATTERNS
    fprintf(stderr, "*");
#endif

    oldsize = dict->size;
    olddict = dict->dict;
    if (olddict == NULL)
        return(-1);
    if (oldsize == MIN_DICT_SIZE)
        keep_keys = 0;

    dict->dict = xmlMalloc(size * sizeof(xmlDictEntry));
    if (dict->dict == NULL) {
	dict->dict = olddict;
	return(-1);
    }
    memset(dict->dict, 0, size * sizeof(xmlDictEntry));
    dict->size = size;

    /*	If the two loops are merged, there would be situations where
	a new entry needs to allocated and data copied into it from
	the main dict. It is nicer to run through the array twice, first
	copying all the elements in the main array (less probability of
	allocate) and then the rest, so we only free in the second loop.
    */
    for (i = 0; i < oldsize; i++) {
	if (olddict[i].valid == 0)
	    continue;

	if (keep_keys)
	    okey = olddict[i].okey;
	else
	    okey = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len);
	key = okey % dict->size;

	if (dict->dict[key].valid == 0) {
	    memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
	    dict->dict[key].next = NULL;
	    dict->dict[key].okey = okey;
	} else {
	    xmlDictEntryPtr entry;

	    entry = xmlMalloc(sizeof(xmlDictEntry));
	    if (entry != NULL) {
		entry->name = olddict[i].name;
		entry->len = olddict[i].len;
		entry->okey = okey;
		entry->next = dict->dict[key].next;
		entry->valid = 1;
		dict->dict[key].next = entry;
	    } else {
	        /*
		 * we don't have much ways to alert from herei
		 * result is loosing an entry and unicity garantee
		 */
	        ret = -1;
	    }
	}
#ifdef DEBUG_GROW
	nbElem++;
#endif
    }

    for (i = 0; i < oldsize; i++) {
	iter = olddict[i].next;
	while (iter) {
	    next = iter->next;

	    /*
	     * put back the entry in the new dict
	     */

	    if (keep_keys)
		okey = iter->okey;
	    else
		okey = xmlDictComputeKey(dict, iter->name, iter->len);
	    key = okey % dict->size;
	    if (dict->dict[key].valid == 0) {
		memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
		dict->dict[key].next = NULL;
		dict->dict[key].valid = 1;
		dict->dict[key].okey = okey;
		xmlFree(iter);
	    } else {
		iter->next = dict->dict[key].next;
		iter->okey = okey;
		dict->dict[key].next = iter;
	    }

#ifdef DEBUG_GROW
	    nbElem++;
#endif

	    iter = next;
	}
    }

    xmlFree(olddict);

#ifdef DEBUG_GROW
    xmlGenericError(xmlGenericErrorContext,
	    "xmlDictGrow : from %lu to %lu, %u elems\n", oldsize, size, nbElem);
#endif

    return(ret);
}
Beispiel #30
0
void *
xmlReallocLoc(void *ptr,unsigned int size, const char * file, int line)
{
    MEMHDR *p;
    unsigned long number;
#ifdef DEBUG_MEMORY
    unsigned int oldsize;
#endif

    if (ptr == NULL)
        return(xmlMallocLoc(size, file, line));

    if (!xmlMemInitialized) xmlInitMemory();
    TEST_POINT

    p = CLIENT_2_HDR(ptr);
    number = p->mh_number;
    if (xmlMemStopAtBlock == number) xmlMallocBreakpoint();
    if (p->mh_tag != MEMTAG) {
       Mem_Tag_Err(p);
	 goto error;
    }
    p->mh_tag = ~MEMTAG;
    xmlMutexLock(xmlMemMutex);
    debugMemSize -= p->mh_size;
    debugMemBlocks--;
#ifdef DEBUG_MEMORY
    oldsize = p->mh_size;
#endif
#ifdef MEM_LIST
    debugmem_list_delete(p);
#endif
    xmlMutexUnlock(xmlMemMutex);

    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
    if (!p) {
	 goto error;
    }
    if (xmlMemTraceBlockAt == ptr) {
	xmlGenericError(xmlGenericErrorContext,
			"%p : Realloced(%ld -> %ld) Ok\n",
			xmlMemTraceBlockAt, p->mh_size, size);
	xmlMallocBreakpoint();
    }
    p->mh_tag = MEMTAG;
    p->mh_number = number;
    p->mh_type = REALLOC_TYPE;
    p->mh_size = size;
    p->mh_file = file;
    p->mh_line = line;
    xmlMutexLock(xmlMemMutex);
    debugMemSize += size;
    debugMemBlocks++;
    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
#ifdef MEM_LIST
    debugmem_list_add(p);
#endif
    xmlMutexUnlock(xmlMemMutex);

    TEST_POINT

#ifdef DEBUG_MEMORY
    xmlGenericError(xmlGenericErrorContext,
	    "Realloced(%d to %d) Ok\n", oldsize, size);
#endif
    return(HDR_2_CLIENT(p));

error:
    return(NULL);
}