Commit 7cc144a6 authored by mrbean-bremen's avatar mrbean-bremen Committed by mrbean-bremen
Browse files

Added check for direct and indirect cycles in use elements

- ignore elements with recursive references
- fixes stack overflow for test image struct-use-12-f.svg
parent aeffcab8
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
namespace Svg namespace Svg
...@@ -20,6 +16,51 @@ namespace Svg ...@@ -20,6 +16,51 @@ namespace Svg
set { this._referencedElement = value; } set { this._referencedElement = value; }
} }
static private bool ElementReferencesUri(SvgElement element, List<Uri> elementUris)
{
var useElement = element as SvgUse;
if (useElement != null)
{
if (elementUris.Contains(useElement.ReferencedElement))
{
return true;
}
// also detect cycles in referenced elements
elementUris.Add(useElement.ReferencedElement);
return useElement.ReferencedElementReferencesUri(elementUris);
}
var groupElement = element as SvgGroup;
if (groupElement != null)
{
foreach (var child in groupElement.Children)
{
if (ElementReferencesUri(child, elementUris))
{
return true;
}
}
}
return false;
}
private bool ReferencedElementReferencesUri( List<Uri> elementUris )
{
var refElement = this.OwnerDocument.IdManager.GetElementById(ReferencedElement);
return ElementReferencesUri(refElement, elementUris);
}
/// <summary>
/// Checks for any direct or indirect recursions in referenced elements,
/// including recursions via groups.
/// </summary>
/// <returns>True if any recursions are found.</returns>
private bool HasRecursiveReference()
{
var refElement = this.OwnerDocument.IdManager.GetElementById(ReferencedElement);
var uris = new List<Uri>() { ReferencedElement };
return ElementReferencesUri(refElement, uris);
}
[SvgAttribute("x")] [SvgAttribute("x")]
public virtual SvgUnit X public virtual SvgUnit X
{ {
...@@ -59,7 +100,7 @@ namespace Svg ...@@ -59,7 +100,7 @@ namespace Svg
public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer) public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
{ {
SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement); SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement);
return (element != null) ? element.Path(renderer) : null; return (element != null && !this.HasRecursiveReference()) ? element.Path(renderer) : null;
} }
public override System.Drawing.RectangleF Bounds public override System.Drawing.RectangleF Bounds
...@@ -79,7 +120,7 @@ namespace Svg ...@@ -79,7 +120,7 @@ namespace Svg
protected override void Render(ISvgRenderer renderer) protected override void Render(ISvgRenderer renderer)
{ {
if (this.Visible && this.Displayable && this.PushTransforms(renderer)) if (this.Visible && this.Displayable && !this.HasRecursiveReference() && this.PushTransforms(renderer))
{ {
this.SetClip(renderer); this.SetClip(renderer);
......
...@@ -136,7 +136,10 @@ painting-fill-04-t.svg ...@@ -136,7 +136,10 @@ painting-fill-04-t.svg
painting-fill-05-b.svg painting-fill-05-b.svg
painting-stroke-01-t.svg painting-stroke-01-t.svg
struct-defs-01-t.svg struct-defs-01-t.svg
struct-use-01-t.svg
struct-use-03-t.svg
struct-use-05-b.svg struct-use-05-b.svg
struct-use-12-f.svg
struct-use-14-f.svg struct-use-14-f.svg
struct-use-15-f.svg struct-use-15-f.svg
styling-class-01-f.svg styling-class-01-f.svg
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment