Example #1
0
        /// <summary>
        /// Validates the document against the specified XML schema.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="schemaString">The XML schema string.</param>
        /// <param name="flags">Unsupported.</param>
        /// <returns><B>True</B> or <B>false</B>.</returns>
        public virtual bool schemaValidateSource(Context ctx, string schemaString, int flags = 0)
        {
            if ((flags & PhpLibXml.LIBXML_SCHEMA_CREATE) == PhpLibXml.LIBXML_SCHEMA_CREATE)
            {
                PhpException.Throw(PhpError.Warning, Resources.SchemaCreateUnsupported);
            }

            XmlSchema schema;

            try
            {
                schema = XmlSchema.Read(new System.IO.StringReader(schemaString), null);
            }
            catch (XmlException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, null);
                return(false);
            }

            XmlDocument.Schemas.Add(schema);
            try
            {
                XmlDocument.Validate(null);
            }
            catch (XmlException)
            {
                return(false);
            }
            finally
            {
                XmlDocument.Schemas.Remove(schema);
            }
            return(true);
        }
Example #2
0
        /// <summary>
        /// Validates the document against the specified XML schema.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="schemaFile">URL for the file containing the XML schema to load.</param>
        /// <param name="flags">Unsupported.</param>
        /// <returns><B>True</B> or <B>false</B>.</returns>
        public virtual bool schemaValidate(Context ctx, string schemaFile, int flags = 0)
        {
            XmlSchema schema;

            using (PhpStream stream = PhpStream.Open(ctx, schemaFile, "rt"))
            {
                if (stream == null)
                {
                    return(false);
                }

                try
                {
                    schema = XmlSchema.Read(stream.RawStream, null);
                }
                catch (XmlException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, schemaFile);
                    return(false);
                }
                catch (IOException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, schemaFile);
                    return(false);
                }
            }

            return(ValidateSchemaInternal(schema, flags));
        }
Example #3
0
        private static bool TryLoadSchema(Context ctx, string url, out XmlSchema schema, out string fullPath)
        {
            schema   = default;
            fullPath = default;

            using var stream = PhpStream.Open(ctx, url, "rt");

            if (stream == null)
            {
                return(false);
            }

            try
            {
                schema   = XmlSchema.Read(stream.RawStream, null);
                fullPath = stream.OpenedPath;
                return(true);
            }
            catch (XmlException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, url);
                return(false);
            }
            catch (IOException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, url);
                return(false);
            }
        }
Example #4
0
        /// <summary>
        /// Loads provided XML string into this <see cref="DOMDocument"/>.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="source">String representing XML document.</param>
        /// <param name="options">PHP options.</param>
        /// <param name="isHtml">Whether the <paramref name="source"/> represents XML generated from HTML document (then it may contain some invalid XML characters).</param>
        /// <returns></returns>
        private bool loadXMLInternal(Context ctx, PhpString source, int options, bool isHtml)
        {
            this._isHtmlDocument = isHtml;

            try
            {
                var settings = new XmlReaderSettings()
                {
                    DtdProcessing = DtdProcessing.Parse
                };

                // TODO: options

                // validating XML reader
                if (this._validateOnParse)
                {
#pragma warning disable 618
                    settings.ValidationType = ValidationType.Auto;
#pragma warning restore 618
                }

                // do not check invalid characters in HTML (XML)
                if (isHtml)
                {
                    settings.CheckCharacters = false;
                }

                var reader = source.ContainsBinaryData
                    ? XmlReader.Create(new MemoryStream(source.ToBytes(ctx)), settings)
                    : XmlReader.Create(new StringReader(source.ToString() /*faster*/), settings);

                // load the document
                this.XmlDocument.Load(reader);

                // done
                return(true);
            }
            catch (XmlException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, e.LineNumber, e.LinePosition, e.Message, null);
                return(false);
            }
            catch (IOException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, null);
                return(false);
            }
        }
Example #5
0
        /// <summary>
        /// Validates the document against the specified XML schema.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="schemaString">The XML schema string.</param>
        /// <param name="flags">Unsupported.</param>
        /// <returns><B>True</B> or <B>false</B>.</returns>
        public virtual bool schemaValidateSource(Context ctx, string schemaString, int flags = 0)
        {
            XmlSchema schema;

            try
            {
                schema = XmlSchema.Read(new System.IO.StringReader(schemaString), null);
            }
            catch (XmlException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, null);
                return(false);
            }

            return(ValidateSchemaInternal(schema, flags));
        }
Example #6
0
        /// <summary>
        /// Validates the document against the specified XML schema.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="schemaFile">URL for the file containing the XML schema to load.</param>
        /// <param name="flags">Unsupported.</param>
        /// <returns><B>True</B> or <B>false</B>.</returns>
        public virtual bool schemaValidate(Context ctx, string schemaFile, int flags = 0)
        {
            if ((flags & PhpLibXml.LIBXML_SCHEMA_CREATE) == PhpLibXml.LIBXML_SCHEMA_CREATE)
            {
                PhpException.Throw(PhpError.Warning, Resources.SchemaCreateUnsupported);
            }

            XmlSchema schema;

            using (PhpStream stream = PhpStream.Open(ctx, schemaFile, "rt"))
            {
                if (stream == null)
                {
                    return(false);
                }

                try
                {
                    schema = XmlSchema.Read(stream.RawStream, null);
                }
                catch (XmlException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, schemaFile);
                    return(false);
                }
                catch (IOException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, schemaFile);
                    return(false);
                }
            }

            XmlDocument.Schemas.Add(schema);
            try
            {
                XmlDocument.Validate(null);
            }
            catch (XmlException)
            {
                return(false);
            }
            finally
            {
                XmlDocument.Schemas.Remove(schema);
            }
            return(true);
        }
Example #7
0
        /// <summary>
        /// Loads the XML document from the specified URL.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="filename">URL for the file containing the XML document to load.</param>
        /// <param name="options">Undocumented.</param>
        /// <returns><b>True</b> on success or <b>false</b> on failure.</returns>
        public virtual bool load(Context ctx, string filename, int options = 0)
        {
            // TODO: this method can be called both statically and via an instance

            _isHtmlDocument = false;

            using (PhpStream stream = PhpStream.Open(ctx, filename, "rt"))
            {
                if (stream == null)
                {
                    return(false);
                }

                try
                {
                    var settings = new XmlReaderSettings()
                    {
                        DtdProcessing = DtdProcessing.Parse
                    };

                    // TODO: options

                    // validating XML reader
                    if (this._validateOnParse)
                    {
#pragma warning disable 618
                        settings.ValidationType = ValidationType.Auto;
#pragma warning restore 618
                    }
                    XmlDocument.Load(XmlReader.Create(stream.RawStream, settings, XIncludeHelper.UriResolver(filename, ctx.WorkingDirectory)));
                }
                catch (XmlException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, filename);
                    return(false);
                }
                catch (IOException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, filename);
                    return(false);
                }
            }

            return(true);
        }
Example #8
0
        /// <summary>
        /// Loads provided XML string into this <see cref="DOMDocument"/>.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="xmlString">String representing XML document.</param>
        /// <param name="options">PHP options.</param>
        /// <param name="isHtml">Whether the <paramref name="xmlString"/> represents XML generated from HTML document (then it may contain some invalid XML characters).</param>
        /// <returns></returns>
        private bool loadXMLInternal(Context ctx, string xmlString, int options, bool isHtml)
        {
            this._isHtmlDocument = isHtml;

            var stream = new StringReader(xmlString);

            try
            {
                XmlReaderSettings settings = new XmlReaderSettings()
                {
                    DtdProcessing = DtdProcessing.Ignore
                };

                // validating XML reader
                if (this._validateOnParse)
                {
                    // TODO: Enable when DtdProcessing.Parse is enabled in System.Xml.ReaderWriter package
                    //#pragma warning disable 618
                    //settings.DtdProcessing = DtdProcessing.Parse;
                    //#pragma warning restore 618
                }

                // do not check invalid characters in HTML (XML)
                if (isHtml)
                {
                    settings.CheckCharacters = false;
                }

                // load the document
                this.XmlDocument.Load(XmlReader.Create(stream, settings));

                // done
                return(true);
            }
            catch (XmlException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, e.LineNumber, e.LinePosition, e.Message, null);
                return(false);
            }
            catch (IOException e)
            {
                PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, null);
                return(false);
            }
        }
Example #9
0
        /// <summary>
        /// Processes HTML errors, if any.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="htmlDoc"><see cref="HtmlAgilityPack.HtmlDocument"/> instance to process errors from.</param>
        /// <param name="filename">HTML file name or <c>null</c> if HTML has been loaded from a string.</param>
        private void CheckHtmlErrors(Context ctx, HtmlAgilityPack.HtmlDocument htmlDoc, string filename)
        {
            Debug.Assert(htmlDoc != null);

            foreach (var error in htmlDoc.ParseErrors)
            {
                switch (error.Code)
                {
                case HtmlAgilityPack.HtmlParseErrorCode.EndTagNotRequired:
                case HtmlAgilityPack.HtmlParseErrorCode.TagNotOpened:
                    break;

                default:
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, error.Line, error.LinePosition, "(" + error.Code.ToString() + ")" + error.Reason, filename);
                    break;
                }
            }
        }
Example #10
0
        /// <summary>
        /// Saves the XML document to the specified stream.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="fileName">The location of the file where the document should be saved.</param>
        /// <param name="options">Unsupported.</param>
        /// <returns>The number of bytes written or <B>false</B> on error.</returns>
        public virtual PhpValue save(Context ctx, string fileName, int options = 0)
        {
            using (PhpStream stream = PhpStream.Open(ctx, fileName, "wt"))
            {
                if (stream == null)
                {
                    return(PhpValue.Create(false));
                }

                try
                {
                    // direct stream write indents
                    if (_formatOutput)
                    {
                        XmlDocument.Save(stream.RawStream);
                    }
                    else
                    {
                        var settings = new XmlWriterSettings()
                        {
                            Encoding = Utils.GetNodeEncoding(ctx, XmlNode)
                        };

                        using (var writer = System.Xml.XmlWriter.Create(stream.RawStream, settings))
                        {
                            XmlDocument.Save(writer);
                        }
                    }
                }
                catch (XmlException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName);
                    return(PhpValue.False);
                }
                catch (IOException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName);
                    return(PhpValue.False);
                }

                // TODO:
                return(PhpValue.Create(stream.RawStream.CanSeek ? stream.RawStream.Position : 1));
            }
        }
Example #11
0
        /// <summary>
        /// Loads the XML document from the specified URL.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="fileName">URL for the file containing the XML document to load.</param>
        /// <param name="options">Undocumented.</param>
        /// <returns><b>True</b> on success or <b>false</b> on failure.</returns>
        public virtual bool load(Context ctx, string fileName, int options = 0)
        {
            // TODO: this method can be called both statically and via an instance

            _isHtmlDocument = false;

            using (PhpStream stream = PhpStream.Open(ctx, fileName, "rt"))
            {
                if (stream == null)
                {
                    return(false);
                }

                try
                {
                    if (_validateOnParse)
                    {
                        // create a validating XML reader
                        XmlReaderSettings settings = new XmlReaderSettings();
                        //#pragma warning disable 618
                        //                        settings.ValidationType = ValidationType.Auto;
                        //#pragma warning restore 618

                        XmlDocument.Load(XmlReader.Create(stream.RawStream, settings));
                    }
                    else
                    {
                        XmlDocument.Load(stream.RawStream);
                    }
                }
                catch (XmlException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName);
                    return(false);
                }
                catch (IOException e)
                {
                    PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName);
                    return(false);
                }
            }

            return(true);
        }
Example #12
0
        /// <summary>
        /// Treats all include tags, if there are bad reference on document, catches exception and tries to find fallback, which is treated as document.
        /// </summary>
        /// <param name="includeNodes">Nodes, which will be replace</param>
        /// <param name="document">Document, which contains includeNodes</param>
        /// <param name="absoluteUri">Uri of document</param>
        /// <param name="nsPrefix">Prefix of include namespace</param>
        /// <param name="nsm">Namespace Manager of document</param>
        /// <returns></returns>
        bool TreatIncludes(XmlElement[] includeNodes, XmlDocument document, string absoluteUri, string nsPrefix, XmlNamespaceManager nsm)
        {
            foreach (var includeElement in includeNodes)
            {
                var valueOfXPoiner = includeElement.GetAttribute(atXPointer);
                var valueOfHref    = includeElement.GetAttribute(atHref);

                if (string.IsNullOrEmpty(valueOfHref)) // There must be xpointer Attribute, if not, fatal error..
                {
                    if (string.IsNullOrEmpty(valueOfXPoiner))
                    {
                        PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a local recursion with no xpointer in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri);
                        return(true);
                    }
                    _documents.Push(document);
                    var includeUri = includeElement.BaseURI + valueOfXPoiner;
                    if (_references.ContainsKey(includeUri)) // fatal error, cycle recursion
                    {
                        PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a recursion in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri);
                        return(true);
                    }
                    _references[absoluteUri] = includeUri;

                    IncludeXml(includeElement.BaseURI, includeElement, null, valueOfXPoiner);
                    return(false);
                }

                // Resolving absolute and relative uri...
                string uri = UriResolver(valueOfHref, Path.GetDirectoryName(absoluteUri));

                // Resolving type of parsing.
                string typeOfParse = includeElement.GetAttribute(atParse);
                try
                {
                    if (string.Equals(typeOfParse, "text", StringComparison.OrdinalIgnoreCase))
                    {
                        _documents.Push(document);
                        IncludeText(uri, includeElement);
                    }
                    else
                    {
                        if (_references.ContainsKey(uri + valueOfXPoiner)) // fatal error, cycle recursion
                        {
                            PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a recursion in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri);
                            //return true;
                        }
                        else
                        {
                            _documents.Push(document);
                            _references[absoluteUri] = uri + valueOfXPoiner;
                            IncludeXml(uri, includeElement, null, string.IsNullOrEmpty(valueOfXPoiner) ? null : valueOfXPoiner);
                        }
                    }
                }
                catch (System.IO.FileNotFoundException)
                {
                    PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): I/O warning : failed to load external entity &quot;{absoluteUri}&quot; in {_ctx.MainScriptFile.Path}", absoluteUri);
                    _documents.Pop();
                    XmlElement[] fallbacks = includeElement.GetElementsByTagName(nsPrefix + ":" + etFallback).OfType <XmlElement>().ToArray <XmlElement>();

                    if (fallbacks.Length > 1) // fatal error
                    {
                        PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): include has multiple fallback children in {_ctx.MainScriptFile.Path}", _ctx.MainScriptFile.Path);
                        return(true);
                    }

                    if (fallbacks.Length == 1)
                    {
                        XmlElement[] includes = fallbacks[0].SelectNodes($".//{nsPrefix}:{etInclude}[ not( descendant::{nsPrefix}:{etFallback} ) ]", nsm).OfType <XmlElement>().ToArray();

                        while (fallbacks[0].ChildNodes.Count != 0)
                        {
                            includeElement.ParentNode.InsertAfter(fallbacks[0].LastChild, includeElement);
                        }

                        TreatIncludes(includes, document, absoluteUri, nsPrefix, nsm);

                        includeElement.ParentNode.RemoveChild(includeElement);
                    }
                    else // error missing fallback
                    {
                        PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): could not load {absoluteUri}, and no fallback was found in {_ctx.MainScriptFile.Path}", absoluteUri);
                        return(true);
                    }
                }
                _references = new Dictionary <string, string>();
            }
            return(false);
        }