[Top][All Lists]
[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 == "<")
{
value = "<";
}
else if(value == ">")
{
value = ">";
}
else if(value == "&")
{
value = "&";
}
else if(value == """)
{
value = "\"";
}
else if(value == "'")
{
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 += "<";
}
else if(ch == '>')
{
! newStr += ">";
}
else if(ch == '&')
{
! newStr += "&";
}
else if(ch == '"')
{
! newStr += """;
}
else
{
! newStr += "'";
}
start = index;
--- 119,139 ----
if(ch == '<')
{
! newStr.Append("<");
}
else if(ch == '>')
{
! newStr.Append(">");
}
else if(ch == '&')
{
! newStr.Append("&");
}
else if(ch == '"')
{
! newStr.Append(""");
}
else
{
! newStr.Append("'");
}
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();
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Security MiniXml.cs,NONE,1.1 SecurityElement.cs,1.3,1.4,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] CVS: pnetlib/System/Net DnsPermission.cs,1.1,1.2
- Next by Date:
[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Security/Permissions EnvironmentPermission.cs,1.1,1.2 FileIOPermission.cs,1.2,1.3 PrincipalPermission.cs,1.2,1.3 RegistryPermission.cs,1.1,1.2 SiteIdentityPermission.cs,1.1,1.2StrongNameIdentityPermission.cs,1.1,1.2 UrlIdentityPermission.cs,1.1,1.2
- Previous by thread:
[Dotgnu-pnet-commits] CVS: pnetlib/System/Net DnsPermission.cs,1.1,1.2
- Next by thread:
[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Security/Permissions EnvironmentPermission.cs,1.1,1.2 FileIOPermission.cs,1.2,1.3 PrincipalPermission.cs,1.2,1.3 RegistryPermission.cs,1.1,1.2 SiteIdentityPermission.cs,1.1,1.2StrongNameIdentityPermission.cs,1.1,1.2 UrlIdentityPermission.cs,1.1,1.2
- Index(es):