2009-07-23 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Thu, 23 Jul 2009 10:16:54 +0000 (10:16 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Thu, 23 Jul 2009 10:16:54 +0000 (10:16 -0000)
* AspGenerator.cs:
Check for duplicate control IDs at the end of parse. Fixes bug
#524358

2009-07-23  Marek Habersack  <mhabersack@novell.com>

* ControlBuilder.cs: added an internal helper property
IsNamingContainer.

2009-07-23  Marek Habersack  <mhabersack@novell.com>

* HttpException.cs: if an exception is processed which refers to
internal "files", don't show the internal name.

svn path=/trunk/mcs/; revision=138521

mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs
mcs/class/System.Web/System.Web.Compilation/ChangeLog
mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/ControlBuilder.cs
mcs/class/System.Web/System.Web/ChangeLog
mcs/class/System.Web/System.Web/HttpException.cs

index 5fc857a322d98068851191f1c7e09374d394dba4..c00a83eea453e6ed0c65c362ab2b290a29d7add2 100644 (file)
@@ -568,6 +568,60 @@ namespace System.Web.Compilation
                        InitParser (reader, filename);
                }
 #endif
+
+               void CheckForDuplicateIds (ControlBuilder root, Stack scopes)
+               {
+                       if (root == null)
+                               return;
+                       
+                       if (scopes == null)
+                               scopes = new Stack ();
+                       
+#if NET_2_0
+                       Dictionary <string, bool> ids;
+#else
+                       Hashtable ids;
+#endif
+                       
+                       if (scopes.Count == 0 || root.IsNamingContainer) {
+#if NET_2_0
+                               ids = new Dictionary <string, bool> (StringComparer.Ordinal);
+#else
+                               ids = new Hashtable ();
+#endif
+                               scopes.Push (ids);
+                       } else {
+#if NET_2_0
+                               ids = scopes.Peek () as Dictionary <string, bool>;
+#else
+                               ids = scopes.Peek () as Hashtable;
+#endif
+                       }
+                       
+                       if (ids == null)
+                               return;
+
+                       ControlBuilder cb;
+                       string id;
+                       ArrayList children = root.Children;
+                       if (children != null) {
+                               foreach (object o in children) {
+                                       cb = o as ControlBuilder;
+                                       if (cb == null)
+                                               continue;
+
+                                       id = cb.ID;
+                                       if (id == null || id.Length == 0)
+                                               continue;
+                               
+                                       if (ids.ContainsKey (id))
+                                               throw new ParseException (cb.Location, "Id '" + id + "' is already used by another control.");
+
+                                       ids.Add (id, true);
+                                       CheckForDuplicateIds (cb, scopes);
+                               }
+                       }
+               }
                
                public void Parse (string file)
                {
@@ -603,6 +657,7 @@ namespace System.Web.Compilation
                                        throw new ParseException (stack.Builder.Location,
                                                                  "Expecting </" + stack.Builder.TagName + "> " + stack.Builder);
 
+                               CheckForDuplicateIds (RootBuilder, null);
                        } finally {
                                if (reader != null)
                                        reader.Close ();
@@ -705,8 +760,8 @@ namespace System.Web.Compilation
 
                        string i = new string ('\t', indent);
                        Console.Write (i);
-                       Console.WriteLine ("b: {0} id: {1} type: {2} parent: {3}",
-                                          builder, builder.ID, builder.ControlType, builder.ParentBuilder);
+                       Console.WriteLine ("b: {0}; naming container: {1}; id: {2}; type: {3}; parent: {4}",
+                                          builder, builder.IsNamingContainer, builder.ID, builder.ControlType, builder.ParentBuilder);
 
                        if (builder.Children != null)
                        foreach (object o in builder.Children) {
index f94e958ba2e43e3278fa557b3cae935cdedd3149..0c72d430bf24b0032a703e194bd1f7b2bc0b03f5 100644 (file)
@@ -5,6 +5,8 @@
        comment, tag and expression regular expressions to the text 
        and splits it into blocks of different types. Then the blocks are
        processed accordingly.
+       Check for duplicate control IDs at the end of parse. Fixes bug
+       #524358
 
 2009-07-21  Veerapuram Varadhan  <vvaradhan@novell.com>
 
index 77b78b597a3ad4f3717ea63afcc7d55a7a247685..343962f04c17ea4719c2931c03569d047e25f7b4 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-23  Marek Habersack  <mhabersack@novell.com>
+
+       * ControlBuilder.cs: added an internal helper property
+       IsNamingContainer.
+
 2009-07-21  Marek Habersack  <mhabersack@novell.com>
 
        * SimpleWebHandlerParser.cs: make sure to ignore invalid bin/
index ec8797e6cb0a7598a53c83ce91f9b1b952a1ec97..16aac32f6eb1cc8d2c9e7cf205be787c325b9af7 100644 (file)
@@ -225,6 +225,15 @@ namespace System.Web.UI {
                        }
                }
 
+               internal bool IsNamingContainer {
+                       get {
+                               if (type == null)
+                                       return false;
+
+                               return typeof (INamingContainer).IsAssignableFrom (type);
+                       }
+               }
+               
                ControlBuilder MyNamingContainer {
                        get {
                                if (myNamingContainer == null) {
index 62b8a30acde075796900fca6647cddb1ce8b7333..9febc1afec11b4b79216de221654ff9705579f5f 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-23  Marek Habersack  <mhabersack@novell.com>
+
+       * HttpException.cs: if an exception is processed which refers to
+       internal "files", don't show the internal name.
+
 2009-07-18  Marek Habersack  <mhabersack@novell.com>
 
        * HttpContext.cs: GetGlobalResourceObject must look for resources
index 6385ffe7cb325273c38e77e17cc1d297dcaada43..6e22feda80a1017815d27e9ce2d8eafc43094329 100644 (file)
@@ -342,6 +342,17 @@ table.sampleCode {{width: 100%; background-color: #ffffcc; }}
                        return res.Replace ("\r\n", "<br />");
                }
 
+               string FormatSourceFile (string filename)
+               {
+                       if (filename == null || filename.Length == 0)
+                               return String.Empty;
+
+                       if (filename.StartsWith ("@@"))
+                               return "[internal] <!-- " + filename + " -->";
+
+                       return filename;
+               }
+               
                string GetHtmlizedErrorMessage ()
                {
                        StringBuilder builder = new StringBuilder ();
@@ -391,9 +402,9 @@ table.sampleCode {{width: 100%; background-color: #ffffcc; }}
 
                                builder.Append ("<br/><p><strong>Source File: </strong>");
                                if (exc.SourceFile != exc.FileName)
-                                       builder.Append (exc.SourceFile);
+                                       builder.Append (FormatSourceFile (exc.SourceFile));
                                else
-                                       builder.Append (exc.FileName);
+                                       builder.Append (FormatSourceFile (exc.FileName));
 
                                if (isParseException || isCompileException) {
                                        int[] errorLines = exc.ErrorLines;