dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Security MiniXml.cs,N


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Security MiniXml.cs,NONE,1.1 SecurityElement.cs,1.3,1.4
Date: Tue, 01 Apr 2003 01:42:11 -0500

Update of /cvsroot/dotgnu-pnet/pnetlib/runtime/System/Security
In directory subversions:/tmp/cvs-serv30814/runtime/System/Security

Modified Files:
        SecurityElement.cs 
Added Files:
        MiniXml.cs 
Log Message:


Implement the mini XML parser for "SecurityElement"; make sure
that permission values are properly escaped when adding them
to "SecurityElement" objects.


--- NEW FILE ---
/*
 * MiniXml.cs - Implementation of the "System.Security.MiniXml" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Security
{

using System;

// This class is used by "SecurityElement" to implement a very
// simple XML parser, suitable for processing code access security tags.
// It isn't for general-purpose XML parsing (use System.Xml instead).
// We cannot use System.Xml directly due to library circularities.

internal sealed class MiniXml
{

        // Token types.
        private enum Token
        {
                EOF,
                StartTag,
                EndTag,
                SingletonTag,
                Text

        }; // enum Token

        // Internal state.
        private String input;
        private int posn;
        private Token token;
        private String value;
        private String args;

        // Constructor.
        public MiniXml(String input)
                        {
                                this.input = (input == null ? String.Empty : 
input);
                                this.posn = 0;
                        }

        // Read the next token from the input.
        private void NextToken()
                        {
                                char ch;
                                int start;
                                int level;
                                args = String.Empty;
                                for(;;)
                                {
                                        // Skip white space prior to the next 
token.
                                        while(posn < input.Length && 
Char.IsWhiteSpace(input[posn]))
                                        {
                                                ++posn;
                                        }
                                        if(posn >= input.Length)
                                        {
                                                token = Token.EOF;
                                                return;
                                        }

                                        // What kind of token is this?
                                        ch = input[posn];
                                        if(ch == '<')
                                        {
                                                // Some form of tag.
                                                if((posn + 3) < input.Length &&
                                                   input[posn + 1] == '!' &&
                                                   input[posn + 2] == '-' &&
                                                   input[posn + 3] == '-')
                                                {
                                                        // Comment tag.
                                                        start = 
input.IndexOf("-->", posn + 4);
                                                        if(start != -1)
                                                        {
                                                                posn = start + 
3;
                                                        }
                                                        else
                                                        {
                                                                posn = 
input.Length;
                                                        }
                                                }
                                                else if((posn + 1) < 
input.Length &&
                                                                input[posn + 1] 
== '/')
                                                {
                                                        // End tag.
                                                        posn += 2;
                                                        start = posn;
                                                        while(posn < 
input.Length &&
                                                                  ((ch = 
input[posn]) != '>' &&
                                                                   
!Char.IsWhiteSpace(ch)))
                                                        {
                                                                ++posn;
                                                        }
                                                        value = 
input.Substring(start, posn - start);
                                                        while(posn < 
input.Length && input[posn] != '>')
                                                        {
                                                                ++posn;
                                                        }
                                                        if(posn < input.Length)
                                                        {
                                                                ++posn;
                                                        }
                                                        token = Token.EndTag;
                                                        return;
                                                }
                                                else if((posn + 8) < 
input.Length &&
                                                                input[posn + 1] 
== '!' &&
                                                                input[posn + 2] 
== '[' &&
                                                                input[posn + 3] 
== 'C' &&
                                                                input[posn + 4] 
== 'D' &&
                                                                input[posn + 5] 
== 'A' &&
                                                                input[posn + 6] 
== 'T' &&
                                                                input[posn + 7] 
== 'A' &&
                                                                input[posn + 8] 
== '[')
                                                {
                                                        // CDATA text block.
                                                        start = 
input.IndexOf("]]>", posn + 9);
                                                        if(start != -1)
                                                        {
                                                                value = 
input.Substring
                                                                        (posn + 
9, start - (posn + 9));
                                                                posn = start + 
3;
                                                        }
                                                        else
                                                        {
                                                                value = 
input.Substring(posn + 9);
                                                                posn = 
input.Length;
                                                        }
                                                        token = Token.Text;
                                                        return;
                                                }
                                                else if((posn + 1) < 
input.Length &&
                                                                (input[posn + 
1] == '!' ||
                                                                 input[posn + 
1] == '?'))
                                                {
                                                        // DTD or XML 
declaration.
                                                        level = 1;
                                                        ++posn;
                                                        while(posn < 
input.Length)
                                                        {
                                                                ch = 
input[posn++];
                                                                if(ch == '>')
                                                                {
                                                                        
if(--level == 0)
                                                                        {
                                                                                
break;
                                                                        }
                                                                }
                                                                else if(ch == 
'<')
                                                                {
                                                                        ++level;
                                                                }
                                                        }
                                                }
                                                else
                                                {
                                                        // Start or singleton 
tag.
                                                        ++posn;
                                                        start = posn;
                                                        while(posn < 
input.Length &&
                                                                  ((ch = 
input[posn]) != '>' && ch != '/' &&
                                                                   
!Char.IsWhiteSpace(ch)))
                                                        {
                                                                ++posn;
                                                        }
                                                        value = 
input.Substring(start, posn - start);
                                                        start = posn;
                                                        while(posn < 
input.Length && input[posn] != '>')
                                                        {
                                                                ++posn;
                                                        }
                                                        if(input[posn - 1] == 
'/')
                                                        {
                                                                args = 
input.Substring(start, posn - start - 1);
                                                                token = 
Token.SingletonTag;
                                                        }
                                                        else
                                                        {
                                                                args = 
input.Substring(start, posn - start);
                                                                token = 
Token.StartTag;
                                                        }
                                                        if(posn < input.Length)
                                                        {
                                                                ++posn;
                                                        }
                                                        return;
                                                }
                                        }
                                        else if(ch == '&')
                                        {
                                                // Ampersand-escaped character.
                                                start = posn;
                                                ++posn;
                                                while(posn < input.Length && 
input[posn] != ';')
                                                {
                                                        ++posn;
                                                }
                                                if(posn < input.Length)
                                                {
                                                        ++posn;
                                                }
                                                value = input.Substring(start, 
posn - start);
                                                if(value == "&lt;")
                                                {
                                                        value = "<";
                                                }
                                                else if(value == "&gt;")
                                                {
                                                        value = ">";
                                                }
                                                else if(value == "&amp;")
                                                {
                                                        value = "&";
                                                }
                                                else if(value == "&quot;")
                                                {
                                                        value = "\"";
                                                }
                                                else if(value == "&apos;")
                                                {
                                                        value = "'";
                                                }
                                                else
                                                {
                                                        value = " ";
                                                }
                                                token = Token.Text;
                                                return;
                                        }
                                        else
                                        {
                                                // Start of an ordinary text 
run.
                                                start = posn;
                                                ++posn;
                                                while(posn < input.Length &&
                                                          ((ch = input[posn]) 
!= '<' && ch != '&'))
                                                {
                                                        ++posn;
                                                }
                                                while(posn > start &&
                                                          
Char.IsWhiteSpace(input[posn - 1]))
                                                {
                                                        --posn;
                                                }
                                                value = input.Substring(start, 
posn - start);
                                                token = Token.Text;
                                                return;
                                        }
                                }
                        }

        // Parse an element tag.
        private SecurityElement ParseElement()
                        {
                                // Create the new element.
                                SecurityElement element;
                                element = new SecurityElement(value);

                                // Parse and add the attribute arguments.
                                int temp = 0;
                                int start;
                                String name;
                                String value;
                                for(;;)
                                {
                                        while(temp < args.Length && 
Char.IsWhiteSpace(args[temp]))
                                        {
                                                ++temp;
                                        }
                                        if(temp >= args.Length)
                                        {
                                                break;
                                        }
                                        start = temp;
                                        while(temp < args.Length && args[temp] 
!= '=')
                                        {
                                                ++temp;
                                        }
                                        name = args.Substring(start, temp - 
start);
                                        if(temp < args.Length)
                                        {
                                                ++temp;
                                        }
                                        if(temp < args.Length && args[temp] == 
'"')
                                        {
                                                ++temp;
                                                start = temp;
                                                while(temp < args.Length && 
args[temp] != '"')
                                                {
                                                        ++temp;
                                                }
                                                value = args.Substring(start, 
temp - start);
                                                if(temp < args.Length)
                                                {
                                                        ++temp;
                                                }
                                        }
                                        else if(temp < args.Length && 
args[temp] == '\'')
                                        {
                                                ++temp;
                                                start = temp;
                                                while(temp < args.Length && 
args[temp] != '\'')
                                                {
                                                        ++temp;
                                                }
                                                value = args.Substring(start, 
temp - start);
                                                if(temp < args.Length)
                                                {
                                                        ++temp;
                                                }
                                        }
                                        else
                                        {
                                                value = String.Empty;
                                        }
                                        element.AddAttribute(name, value);
                                }

                                // Parse the children of this element.
                                if(token == Token.SingletonTag)
                                {
                                        NextToken();
                                }
                                else
                                {
                                        NextToken();
                                        while(token != Token.EOF && token != 
Token.EndTag)
                                        {
                                                if(token == Token.StartTag ||
                                                   token == Token.SingletonTag)
                                                {
                                                        SecurityElement child;
                                                        child = ParseElement();
                                                        element.AddChild(child);
                                                }
                                                else if(token == Token.Text)
                                                {
                                                        String prevText = 
element.Text;
                                                        if(prevText != null)
                                                        {
                                                                element.Text = 
prevText + value;
                                                        }
                                                        else
                                                        {
                                                                element.Text = 
value;
                                                        }
                                                }
                                                NextToken();
                                        }
                                }

                                // Return the final element to the caller.
                                return element;
                        }

        // Parse the input data.
        public SecurityElement Parse()
                        {
                                // Skip until we find a start or singleton 
token.
                                do
                                {
                                        NextToken();
                                }
                                while(token != Token.EOF &&
                                          token != Token.StartTag &&
                                          token != Token.SingletonTag);
                                if(token == Token.EOF)
                                {
                                        return null;
                                }

                                // Parse the element.
                                return ParseElement();
                        }

}; // class MiniXml

}; // namespace System.Security

Index: SecurityElement.cs
===================================================================
RCS file: 
/cvsroot/dotgnu-pnet/pnetlib/runtime/System/Security/SecurityElement.cs,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** SecurityElement.cs  30 Mar 2003 11:58:44 -0000      1.3
--- SecurityElement.cs  1 Apr 2003 06:42:09 -0000       1.4
***************
*** 3,7 ****
   *            "System.Security.SecurityElement" class.
   *
!  * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
   *
   * This program is free software; you can redistribute it and/or modify
--- 3,7 ----
   *            "System.Security.SecurityElement" class.
   *
!  * Copyright (C) 2001, 2003  Southern Storm Software, Pty Ltd.
   *
   * This program is free software; you can redistribute it and/or modify
***************
*** 24,27 ****
--- 24,28 ----
  
  using System;
+ using System.Text;
  using System.Collections;
  
***************
*** 93,97 ****
        public static String Escape(String str)
                        {
!                               String newStr;
                                int start;
                                int index;
--- 94,98 ----
        public static String Escape(String str)
                        {
!                               StringBuilder newStr;
                                int start;
                                int index;
***************
*** 112,116 ****
  
                                // Replace the invalid characters and build a 
new string.
!                               newStr = str.Substring(0, index);
                                for(;;)
                                {
--- 113,117 ----
  
                                // Replace the invalid characters and build a 
new string.
!                               newStr = new StringBuilder(str.Substring(0, 
index));
                                for(;;)
                                {
***************
*** 118,138 ****
                                        if(ch == '<')
                                        {
!                                               newStr += "&lt;";
                                        }
                                        else if(ch == '>')
                                        {
!                                               newStr += "&gt;";
                                        }
                                        else if(ch == '&')
                                        {
!                                               newStr += "&amp;";
                                        }
                                        else if(ch == '"')
                                        {
!                                               newStr += "&quot;";
                                        }
                                        else
                                        {
!                                               newStr += "&apos;";
                                        }
                                        start = index;
--- 119,139 ----
                                        if(ch == '<')
                                        {
!                                               newStr.Append("&lt;");
                                        }
                                        else if(ch == '>')
                                        {
!                                               newStr.Append("&gt;");
                                        }
                                        else if(ch == '&')
                                        {
!                                               newStr.Append("&amp;");
                                        }
                                        else if(ch == '"')
                                        {
!                                               newStr.Append("&quot;");
                                        }
                                        else
                                        {
!                                               newStr.Append("&apos;");
                                        }
                                        start = index;
***************
*** 145,159 ****
                                        if(index == -1)
                                        {
!                                               newStr += str.Substring(start);
                                                break;
                                        }
                                        else if(index > start)
                                        {
!                                               newStr += str.Substring(start, 
index - start);
                                        }
                                }
  
                                // Return the escaped string to the caller.
!                               return newStr;
                        }
  
--- 146,218 ----
                                        if(index == -1)
                                        {
!                                               
newStr.Append(str.Substring(start));
                                                break;
                                        }
                                        else if(index > start)
                                        {
!                                               
newStr.Append(str.Substring(start, index - start));
                                        }
                                }
  
                                // Return the escaped string to the caller.
!                               return newStr.ToString();
!                       }
! 
!       // Unescape invalid XML characters in a string.
!       private static String Unescape(String str)
!                       {
!                               // Bail out early if there are no escapes in 
the string.
!                               if(str == null || str.IndexOf('&') == -1)
!                               {
!                                       return str;
!                               }
! 
!                               // Construct a new string with the escapes 
removed.
!                               StringBuilder newStr = new StringBuilder();
!                               int posn = 0;
!                               char ch;
!                               String name;
!                               while(posn < str.Length)
!                               {
!                                       ch = str[posn++];
!                                       if(ch == '&')
!                                       {
!                                               name = String.Empty;
!                                               while(posn < str.Length && 
str[posn] != ';')
!                                               {
!                                                       name += str[posn];
!                                                       ++posn;
!                                               }
!                                               if(posn < str.Length)
!                                               {
!                                                       ++posn;
!                                               }
!                                               if(name == "lt")
!                                               {
!                                                       newStr.Append('<');
!                                               }
!                                               else if(name == "gt")
!                                               {
!                                                       newStr.Append('>');
!                                               }
!                                               else if(name == "amp")
!                                               {
!                                                       newStr.Append('&');
!                                               }
!                                               else if(name == "quot")
!                                               {
!                                                       newStr.Append('"');
!                                               }
!                                               else if(name == "apos")
!                                               {
!                                                       newStr.Append('\'');
!                                               }
!                                       }
!                                       else
!                                       {
!                                               newStr.Append(ch);
!                                       }
!                               }
!                               return newStr.ToString();
                        }
  
***************
*** 406,410 ****
                                        if(name == nv.name)
                                        {
!                                               return nv.value;
                                        }
                                }
--- 465,469 ----
                                        if(name == nv.name)
                                        {
!                                               return Unescape(nv.value);
                                        }
                                }
***************
*** 555,559 ****
                                        if(text != null)
                                        {
!                                               result += text;
                                        }
                                        if(children != null)
--- 614,618 ----
                                        if(text != null)
                                        {
!                                               result += Escape(text);
                                        }
                                        if(children != null)
***************
*** 571,579 ****
  
        // Parse an XML string into a tree of "SecurityElement" values.
-       [TODO]
        internal static SecurityElement Parse(String xmlString)
                        {
!                               // TODO
!                               return null;
                        }
  
--- 630,637 ----
  
        // Parse an XML string into a tree of "SecurityElement" values.
        internal static SecurityElement Parse(String xmlString)
                        {
!                               MiniXml xml = new MiniXml(xmlString);
!                               return xml.Parse();
                        }
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]