msxml3: Validate node content in domelem_put_dataType().
This commit is contained in:
parent
f090ddfe13
commit
643cbafabc
|
@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
|||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
static const xmlChar DT_prefix[] = "dt";
|
||||
static const xmlChar DT_nsURI[] = "urn:schemas-microsoft-com:datatypes";
|
||||
|
||||
typedef struct _domelem
|
||||
|
@ -823,10 +824,94 @@ static HRESULT WINAPI domelem_get_dataType(
|
|||
|
||||
static HRESULT WINAPI domelem_put_dataType(
|
||||
IXMLDOMElement *iface,
|
||||
BSTR p)
|
||||
BSTR dtName)
|
||||
{
|
||||
domelem *This = impl_from_IXMLDOMElement( iface );
|
||||
return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
|
||||
HRESULT hr = E_FAIL;
|
||||
xmlChar *str;
|
||||
XDR_DT dt;
|
||||
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_w(dtName));
|
||||
|
||||
if(dtName == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
dt = bstr_to_dt(dtName, -1);
|
||||
|
||||
/* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
|
||||
This applies to changing types (string->bool) or setting a new one
|
||||
*/
|
||||
str = xmlNodeGetContent(get_element(This));
|
||||
hr = dt_validate(dt, str);
|
||||
xmlFree(str);
|
||||
|
||||
/* Check all supported types. */
|
||||
if (hr == S_OK)
|
||||
{
|
||||
switch (dt)
|
||||
{
|
||||
case DT_BIN_BASE64:
|
||||
case DT_BIN_HEX:
|
||||
case DT_BOOLEAN:
|
||||
case DT_CHAR:
|
||||
case DT_DATE:
|
||||
case DT_DATE_TZ:
|
||||
case DT_DATETIME:
|
||||
case DT_DATETIME_TZ:
|
||||
case DT_FIXED_14_4:
|
||||
case DT_FLOAT:
|
||||
case DT_I1:
|
||||
case DT_I2:
|
||||
case DT_I4:
|
||||
case DT_I8:
|
||||
case DT_INT:
|
||||
case DT_NMTOKEN:
|
||||
case DT_NMTOKENS:
|
||||
case DT_NUMBER:
|
||||
case DT_R4:
|
||||
case DT_R8:
|
||||
case DT_STRING:
|
||||
case DT_TIME:
|
||||
case DT_TIME_TZ:
|
||||
case DT_UI1:
|
||||
case DT_UI2:
|
||||
case DT_UI4:
|
||||
case DT_UI8:
|
||||
case DT_URI:
|
||||
case DT_UUID:
|
||||
{
|
||||
xmlAttrPtr attr = xmlHasNsProp(get_element(This), DT_prefix, DT_nsURI);
|
||||
if (attr)
|
||||
{
|
||||
attr = xmlSetNsProp(get_element(This), attr->ns, DT_prefix, dt_to_str(dt));
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNsPtr ns = xmlNewNs(get_element(This), DT_nsURI, DT_prefix);
|
||||
if (ns)
|
||||
{
|
||||
attr = xmlNewNsProp(get_element(This), ns, DT_prefix, dt_to_str(dt));
|
||||
if (attr)
|
||||
{
|
||||
xmlAddChild(get_element(This), (xmlNodePtr)attr);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
ERR("Failed to create Attribute\n");
|
||||
}
|
||||
else
|
||||
ERR("Failed to create Namespace\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("need to handle dt:%s\n", dt_to_str(dt));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI domelem_get_xml(
|
||||
|
|
|
@ -273,6 +273,7 @@ extern XDR_DT bstr_to_dt(OLECHAR const* bstr, int len /* calculated if -1 */);
|
|||
extern xmlChar const* dt_to_str(XDR_DT dt);
|
||||
extern OLECHAR const* dt_to_bstr(XDR_DT dt);
|
||||
extern XDR_DT element_get_dt(xmlNodePtr node);
|
||||
extern HRESULT dt_validate(XDR_DT dt, xmlChar const* content);
|
||||
|
||||
extern BSTR EnsureCorrectEOL(BSTR);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
|||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
/* TODO: get rid of these and use the enum */
|
||||
static const WCHAR szBinBase64[] = {'b','i','n','.','b','a','s','e','6','4',0};
|
||||
static const WCHAR szString[] = {'s','t','r','i','n','g',0};
|
||||
static const WCHAR szNumber[] = {'n','u','m','b','e','r',0};
|
||||
|
@ -883,78 +884,18 @@ static HRESULT WINAPI xmlnode_put_nodeTypedValue(
|
|||
|
||||
static HRESULT WINAPI xmlnode_put_dataType(
|
||||
IXMLDOMNode *iface,
|
||||
BSTR dataTypeName)
|
||||
BSTR dtName)
|
||||
{
|
||||
xmlnode *This = impl_from_IXMLDOMNode( iface );
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_w(dataTypeName));
|
||||
TRACE("(%p)->(%s)\n", This, debugstr_w(dtName));
|
||||
|
||||
if(dataTypeName == NULL)
|
||||
if(!dtName)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
|
||||
This applies to changing types (string->bool) or setting a new one
|
||||
*/
|
||||
FIXME("Need to Validate the data before allowing a type to be set.\n");
|
||||
FIXME("need to handle node type %i\n", This->node->type);
|
||||
|
||||
/* Check all supported types. */
|
||||
if(lstrcmpiW(dataTypeName,szString) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szNumber) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szUUID) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szInt) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szI4) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szFixed) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szBoolean) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szDateTime) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szDateTimeTZ) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szDate) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szTime) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szTimeTZ) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szI1) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szI2) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szIU1) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szIU2) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szIU4) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szR4) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szR8) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szFloat) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szBinHex) == 0 ||
|
||||
lstrcmpiW(dataTypeName,szBinBase64) == 0)
|
||||
{
|
||||
xmlChar* str = xmlChar_from_wchar(dataTypeName);
|
||||
xmlAttrPtr attr;
|
||||
|
||||
if (!str) return E_OUTOFMEMORY;
|
||||
|
||||
attr = xmlHasNsProp(This->node, (const xmlChar*)"dt",
|
||||
(const xmlChar*)"urn:schemas-microsoft-com:datatypes");
|
||||
if (attr)
|
||||
{
|
||||
attr = xmlSetNsProp(This->node, attr->ns, (const xmlChar*)"dt", str);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlNsPtr ns = xmlNewNs(This->node, (const xmlChar*)"urn:schemas-microsoft-com:datatypes", (const xmlChar*)"dt");
|
||||
if (ns)
|
||||
{
|
||||
attr = xmlNewNsProp(This->node, ns, (const xmlChar*)"dt", str);
|
||||
if (attr)
|
||||
{
|
||||
xmlAddChild(This->node, (xmlNodePtr)attr);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
ERR("Failed to create Attribute\n");
|
||||
}
|
||||
else
|
||||
ERR("Failed to create Namespace\n");
|
||||
}
|
||||
heap_free( str );
|
||||
}
|
||||
|
||||
return hr;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
BSTR EnsureCorrectEOL(BSTR sInput)
|
||||
|
|
|
@ -64,9 +64,11 @@ static const xmlChar XDR_schema[] = "Schema";
|
|||
static const xmlChar XDR_nsURI[] = "urn:schemas-microsoft-com:xml-data";
|
||||
static const xmlChar DT_nsURI[] = "urn:schemas-microsoft-com:datatypes";
|
||||
|
||||
static xmlChar const* datatypes_schema = NULL;
|
||||
static HGLOBAL datatypes_handle = NULL;
|
||||
static HRSRC datatypes_rsrc = NULL;
|
||||
static xmlChar const* datatypes_src = NULL;
|
||||
static int datatypes_len = 0;
|
||||
static HGLOBAL datatypes_handle = NULL;
|
||||
static HRSRC datatypes_rsrc = NULL;
|
||||
static xmlSchemaPtr datatypes_schema = NULL;
|
||||
|
||||
/* Supported Types:
|
||||
* msxml3 - XDR only
|
||||
|
@ -484,6 +486,83 @@ OLECHAR const* dt_to_bstr(XDR_DT dt)
|
|||
return DT_wstring_table[dt];
|
||||
}
|
||||
|
||||
HRESULT dt_validate(XDR_DT dt, xmlChar const* content)
|
||||
{
|
||||
xmlDocPtr tmp_doc;
|
||||
xmlNodePtr node;
|
||||
xmlNsPtr ns;
|
||||
xmlSchemaValidCtxtPtr svctx;
|
||||
BOOL valid;
|
||||
if (!datatypes_schema)
|
||||
{
|
||||
xmlSchemaParserCtxtPtr spctx;
|
||||
assert(datatypes_src != NULL);
|
||||
spctx = xmlSchemaNewMemParserCtxt((char const*)datatypes_src, datatypes_len);
|
||||
datatypes_schema = xmlSchemaParse(spctx);
|
||||
xmlSchemaFreeParserCtxt(spctx);
|
||||
}
|
||||
|
||||
switch (dt)
|
||||
{
|
||||
case DT_INVALID:
|
||||
return E_FAIL;
|
||||
break;
|
||||
case DT_BIN_BASE64:
|
||||
case DT_BIN_HEX:
|
||||
case DT_BOOLEAN:
|
||||
case DT_CHAR:
|
||||
case DT_DATE:
|
||||
case DT_DATE_TZ:
|
||||
case DT_DATETIME:
|
||||
case DT_DATETIME_TZ:
|
||||
case DT_FIXED_14_4:
|
||||
case DT_FLOAT:
|
||||
case DT_I1:
|
||||
case DT_I2:
|
||||
case DT_I4:
|
||||
case DT_I8:
|
||||
case DT_INT:
|
||||
case DT_NMTOKEN:
|
||||
case DT_NMTOKENS:
|
||||
case DT_NUMBER:
|
||||
case DT_R4:
|
||||
case DT_R8:
|
||||
case DT_STRING:
|
||||
case DT_TIME:
|
||||
case DT_TIME_TZ:
|
||||
case DT_UI1:
|
||||
case DT_UI2:
|
||||
case DT_UI4:
|
||||
case DT_UI8:
|
||||
case DT_URI:
|
||||
case DT_UUID:
|
||||
assert(datatypes_schema != NULL);
|
||||
if (content && xmlStrlen(content))
|
||||
{
|
||||
svctx = xmlSchemaNewValidCtxt(datatypes_schema);
|
||||
tmp_doc = xmlNewDoc(NULL);
|
||||
node = xmlNewChild((xmlNodePtr)tmp_doc, NULL, dt_to_str(dt), content);
|
||||
ns = xmlNewNs(node, DT_nsURI, BAD_CAST "dt");
|
||||
xmlSetNs(node, ns);
|
||||
xmlDocSetRootElement(tmp_doc, node);
|
||||
|
||||
valid = !xmlSchemaValidateDoc(svctx, tmp_doc);
|
||||
xmlSchemaFreeValidCtxt(svctx);
|
||||
xmlFreeDoc(tmp_doc);
|
||||
}
|
||||
else
|
||||
{ /* probably the node is being created manually and has no content yet */
|
||||
valid = TRUE;
|
||||
}
|
||||
return valid? S_OK : S_FALSE;
|
||||
break;
|
||||
default:
|
||||
FIXME("need to handle dt:%s\n", dt_to_str(dt));
|
||||
return S_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline xmlChar const* get_node_nsURI(xmlNodePtr node)
|
||||
{
|
||||
return (node->ns != NULL)? node->ns->href : NULL;
|
||||
|
@ -513,13 +592,13 @@ static xmlParserInputPtr external_entity_loader(const char *URL, const char *ID,
|
|||
assert(MSXML_hInstance != NULL);
|
||||
assert(datatypes_rsrc != NULL);
|
||||
assert(datatypes_handle != NULL);
|
||||
assert(datatypes_schema != NULL);
|
||||
assert(datatypes_src != NULL);
|
||||
|
||||
/* TODO: if the desired schema is in the cache, load it from there */
|
||||
if (lstrcmpA(URL, "urn:schemas-microsoft-com:datatypes") == 0)
|
||||
{
|
||||
TRACE("loading built-in schema for %s\n", URL);
|
||||
input = xmlNewStringInputStream(ctxt, datatypes_schema);
|
||||
input = xmlNewStringInputStream(ctxt, datatypes_src);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -551,7 +630,8 @@ void schemasInit(void)
|
|||
* need a null-terminated string */
|
||||
while (buf[len] != '>')
|
||||
buf[len--] = 0;
|
||||
datatypes_schema = BAD_CAST buf;
|
||||
datatypes_src = BAD_CAST buf;
|
||||
datatypes_len = len + 1;
|
||||
|
||||
if ((void*)xmlGetExternalEntityLoader() != (void*)external_entity_loader)
|
||||
{
|
||||
|
@ -564,6 +644,8 @@ void schemasCleanup(void)
|
|||
{
|
||||
if (datatypes_handle)
|
||||
FreeResource(datatypes_handle);
|
||||
if (datatypes_schema)
|
||||
xmlSchemaFree(datatypes_schema);
|
||||
xmlSetExternalEntityLoader(_external_entity_loader);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue