* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define COBJMACROS
-#include "precomp.h"
+#include "config.h"
+#include <stdarg.h>
#ifdef HAVE_LIBXML2
+# include <libxml/parser.h>
+# include <libxml/xmlerror.h>
+# include <libxml/SAX2.h>
# include <libxml/parserInternals.h>
#endif
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "ole2.h"
+#include "msxml6.h"
+#include "wininet.h"
+#include "urlmon.h"
+#include "winreg.h"
+#include "shlwapi.h"
+
+#include "wine/debug.h"
+
+#include "msxml_private.h"
+
#ifdef HAVE_LIBXML2
+WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+
typedef enum
{
FeatureUnknown = 0,
'/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0
};
+static const WCHAR ExhaustiveErrorsW[] = {
+ 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0
+};
+
+static const WCHAR SchemaValidationW[] = {
+ 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0
+};
+
struct saxreader_feature_pair
{
saxreader_feature feature;
};
static const struct saxreader_feature_pair saxreader_feature_map[] = {
+ { ExhaustiveErrors, ExhaustiveErrorsW },
{ ExternalGeneralEntities, FeatureExternalGeneralEntitiesW },
{ ExternalParameterEntities, FeatureExternalParameterEntitiesW },
{ LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW },
{ NamespacePrefixes, FeatureNamespacePrefixesW },
{ Namespaces, FeatureNamespacesW },
- { ProhibitDTD, FeatureProhibitDTDW }
+ { ProhibitDTD, FeatureProhibitDTDW },
+ { SchemaValidation, SchemaValidationW },
};
static saxreader_feature get_saxreader_feature(const WCHAR *name)
int min, max, n, c;
min = 0;
- max = sizeof(saxreader_feature_map)/sizeof(struct saxreader_feature_pair) - 1;
+ max = ARRAY_SIZE(saxreader_feature_map) - 1;
while (min <= max)
{
return FeatureUnknown;
}
+static const WCHAR empty_str;
+
struct bstrpool
{
BSTR *pool;
struct list elements;
BSTR namespaceUri;
- int attributesSize;
- int nb_attributes;
+ int attr_alloc_count;
+ int attr_count;
struct _attributes
{
BSTR szLocalname;
{
if (!pool->pool)
{
- pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
+ pool->pool = heap_alloc(16 * sizeof(*pool->pool));
if (!pool->pool)
return FALSE;
}
else if (pool->index == pool->len)
{
- BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
+ BSTR *realloc = heap_realloc(pool->pool, pool->len * 2 * sizeof(*realloc));
if (!realloc)
return FALSE;
for (i = 0; i < pool->index; i++)
SysFreeString(pool->pool[i]);
- HeapFree(GetProcessHeap(), 0, pool->pool);
+ heap_free(pool->pool);
pool->pool = NULL;
pool->index = pool->len = 0;
{
WCHAR msg[1024];
if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, hr, 0, msg, sizeof(msg), NULL))
+ NULL, hr, 0, msg, ARRAY_SIZE(msg), NULL))
{
FIXME("MSXML errors not yet supported.\n");
msg[0] = '\0';
static void update_position(saxlocator *This, BOOL fix_column)
{
const xmlChar *p = This->pParserCtxt->input->cur-1;
+ const xmlChar *baseP = This->pParserCtxt->input->base;
This->line = xmlSAX2GetLineNumber(This->pParserCtxt);
if(fix_column)
{
This->column = 1;
- for(; *p!='\n' && *p!='\r' && p>=This->pParserCtxt->input->base; p--)
+ for(;p>=baseP && *p!='\n' && *p!='\r'; p--)
This->column++;
}
else
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- *length = This->nb_attributes;
+ *length = This->attr_count;
TRACE("Length set to %d\n", *length);
return S_OK;
}
+static inline BOOL is_valid_attr_index(const saxlocator *locator, int index)
+{
+ return index < locator->attr_count && index >= 0;
+}
+
static HRESULT WINAPI isaxattributes_getURI(
ISAXAttributes* iface,
int index,
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!url || !size) return E_POINTER;
*size = SysStringLen(This->attributes[index].szURI);
static HRESULT WINAPI isaxattributes_getLocalName(
ISAXAttributes* iface,
- int nIndex,
+ int index,
const WCHAR **pLocalName,
int *pLocalNameLength)
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- TRACE("(%p)->(%d)\n", This, nIndex);
+ TRACE("(%p)->(%d)\n", This, index);
- if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!pLocalName || !pLocalNameLength) return E_POINTER;
- *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
- *pLocalName = This->attributes[nIndex].szLocalname;
+ *pLocalNameLength = SysStringLen(This->attributes[index].szLocalname);
+ *pLocalName = This->attributes[index].szLocalname;
return S_OK;
}
static HRESULT WINAPI isaxattributes_getQName(
ISAXAttributes* iface,
- int nIndex,
+ int index,
const WCHAR **pQName,
int *pQNameLength)
{
saxlocator *This = impl_from_ISAXAttributes( iface );
- TRACE("(%p)->(%d)\n", This, nIndex);
+ TRACE("(%p)->(%d)\n", This, index);
- if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!pQName || !pQNameLength) return E_POINTER;
- *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
- *pQName = This->attributes[nIndex].szQName;
+ *pQNameLength = SysStringLen(This->attributes[index].szQName);
+ *pQName = This->attributes[index].szQName;
return S_OK;
}
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!uri || !pUriLength || !localName || !pLocalNameSize
|| !QName || !pQNameLength) return E_POINTER;
if(!pUri || !pLocalName || !index) return E_POINTER;
- for(i=0; i<This->nb_attributes; i++)
+ for(i=0; i<This->attr_count; i++)
{
if(cUriLength!=SysStringLen(This->attributes[i].szURI)
|| cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
if(!pQName || !index) return E_POINTER;
if(!nQNameLength) return E_INVALIDARG;
- for(i=0; i<This->nb_attributes; i++)
+ for(i=0; i<This->attr_count; i++)
{
if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
saxlocator *This = impl_from_ISAXAttributes( iface );
TRACE("(%p)->(%d)\n", This, index);
- if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
+ if(!is_valid_attr_index(This, index)) return E_INVALIDARG;
if(!value || !nValue) return E_POINTER;
*nValue = SysStringLen(This->attributes[index].szValue);
WCHAR *src;
/* leave first '&' from a reference as a value */
- src = dest + (sizeof(ampescW)/sizeof(WCHAR) - 1);
+ src = dest + ARRAY_SIZE(ampescW) - 1;
dest++;
/* move together with null terminator */
{
int i;
- for (i = 0; i < locator->nb_attributes; i++)
+ for (i = 0; i < locator->attr_count; i++)
{
SysFreeString(locator->attributes[i].szLocalname);
locator->attributes[i].szLocalname = NULL;
if ((locator->saxreader->features & NamespacePrefixes) == 0)
nb_namespaces = 0;
- locator->nb_attributes = nb_namespaces + nb_attributes;
- if(locator->nb_attributes > locator->attributesSize)
+ locator->attr_count = nb_namespaces + nb_attributes;
+ if(locator->attr_count > locator->attr_alloc_count)
{
- int new_size = locator->attributesSize * 2;
+ int new_size = locator->attr_count * 2;
attrs = heap_realloc_zero(locator->attributes, new_size * sizeof(struct _attributes));
if(!attrs)
{
free_attribute_values(locator);
- locator->nb_attributes = 0;
+ locator->attr_count = 0;
return E_OUTOFMEMORY;
}
locator->attributes = attrs;
- locator->attributesSize = new_size;
+ locator->attr_alloc_count = new_size;
}
else
{
&uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
else
hr = ISAXContentHandler_startElement(handler->handler,
- uri, SysStringLen(uri),
- local, SysStringLen(local),
+ uri ? uri : &empty_str, SysStringLen(uri),
+ local ? local : &empty_str, SysStringLen(local),
element->qname, SysStringLen(element->qname),
&This->ISAXAttributes_iface);
if (!saxreader_has_handler(This, SAXContentHandler))
{
free_attribute_values(This);
- This->nb_attributes = 0;
+ This->attr_count = 0;
free_element_entry(element);
return;
}
else
hr = ISAXContentHandler_endElement(
handler->handler,
- uri, SysStringLen(uri),
- local, SysStringLen(local),
+ uri ? uri : &empty_str, SysStringLen(uri),
+ local ? local : &empty_str, SysStringLen(local),
element->qname, SysStringLen(element->qname));
free_attribute_values(This);
- This->nb_attributes = 0;
+ This->attr_count = 0;
if (sax_callback_failed(This, hr))
{
BSTR bstr = bstr_from_xmlCharN(str, len), ret;
WCHAR *ptr;
+ len = SysStringLen(bstr);
ptr = bstr + len - 1;
while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr)
ptr--;
while (i < len)
{
if (value[i] != '\r' && value[i] != '\n') break;
- i++;
+ i++;
}
end = &value[i];
SysFreeString(This->systemId);
SysFreeString(This->namespaceUri);
- for(index=0; index<This->attributesSize; index++)
+ for(index = 0; index < This->attr_alloc_count; index++)
{
SysFreeString(This->attributes[index].szLocalname);
SysFreeString(This->attributes[index].szValue);
return E_OUTOFMEMORY;
}
- locator->attributesSize = 8;
- locator->nb_attributes = 0;
- locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attributesSize);
+ locator->attr_alloc_count = 8;
+ locator->attr_count = 0;
+ locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count);
if(!locator->attributes)
{
ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
if (encoding == XML_CHAR_ENCODING_NONE)
{
const WCHAR *ptr = (WCHAR*)buffer;
- /* xml declaration with possibly specfied encoding will be still handled by parser */
+ /* an xml declaration with optional encoding will still be handled by the parser */
if ((size >= 2) && *ptr == '<' && ptr[1] != '?')
{
enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE);
}
case VT_UNKNOWN:
case VT_DISPATCH: {
- IPersistStream *persistStream;
ISequentialStream *stream = NULL;
IXMLDOMDocument *xmlDoc;
+ if (!V_UNKNOWN(&varInput))
+ return E_INVALIDARG;
+
if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
&IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
{
break;
}
- if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
- &IID_IPersistStream, (void**)&persistStream) == S_OK)
- {
- IStream *stream_copy;
-
- hr = CreateStreamOnHGlobal(NULL, TRUE, &stream_copy);
- if(hr != S_OK)
- {
- IPersistStream_Release(persistStream);
- return hr;
- }
-
- hr = IPersistStream_Save(persistStream, stream_copy, TRUE);
- IPersistStream_Release(persistStream);
- if(hr == S_OK)
- IStream_QueryInterface(stream_copy, &IID_ISequentialStream, (void**)&stream);
-
- IStream_Release(stream_copy);
- }
-
/* try base interface first */
- if(!stream)
- {
- IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
- if (!stream)
- /* this should never happen if IStream is implemented properly, but just in case */
- IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
- }
+ IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream);
+ if (!stream)
+ /* this should never happen if IStream is implemented properly, but just in case */
+ IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream);
if(stream)
{
TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value);
feature = get_saxreader_feature(feature_name);
- if (feature == Namespaces || feature == NamespacePrefixes)
+
+ if (This->version < MSXML4 && (feature == ExhaustiveErrors || feature == SchemaValidation))
+ return E_INVALIDARG;
+
+ if (feature == Namespaces ||
+ feature == NamespacePrefixes ||
+ feature == ExhaustiveErrors ||
+ feature == SchemaValidation)
return get_feature_value(This, feature, value);
FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value);
feature = get_saxreader_feature(feature_name);
/* accepted cases */
- if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) ||
- (feature == ExternalParameterEntities && value == VARIANT_FALSE) ||
+ if ((feature == ExhaustiveErrors && value == VARIANT_FALSE) ||
+ (feature == SchemaValidation && value == VARIANT_FALSE) ||
feature == Namespaces ||
feature == NamespacePrefixes)
{
return set_feature_value(This, feature, value);
}
- if (feature == LexicalHandlerParEntities || feature == ProhibitDTD)
+ if (feature == LexicalHandlerParEntities ||
+ feature == ProhibitDTD ||
+ feature == ExternalGeneralEntities ||
+ feature == ExternalParameterEntities)
{
FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value);
return set_feature_value(This, feature, value);