// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if CONFIGURATION_DEP
+#if CONFIGURATION_DEP && !TARGET_JVM
extern alias PrebuiltSystem;
using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
#endif
using System.Collections.Specialized;
using System.IO;
using System.Runtime.CompilerServices;
+using System.Security.Permissions;
#if (XML_DEP)
using System.Xml;
using System.Xml.XPath;
#endif
+#if TARGET_JVM
+using vmw.common;
+using vmw.@internal.io;
+#endif
namespace System.Configuration
{
public sealed class ConfigurationSettings
{
- static IConfigurationSystem config = DefaultConfig.GetInstance ();
+#if !TARGET_JVM
+ static IConfigurationSystem config = DefaultConfig.GetInstance ();
+#else
+ static IConfigurationSystem config {
+ get {
+ IConfigurationSystem conf = (IConfigurationSystem) AppDomain.CurrentDomain.GetData ("ConfigurationSettings.Config");
+ if (conf == null) {
+ conf = DefaultConfig.GetInstance ();
+ AppDomain.CurrentDomain.SetData ("ConfigurationSettings.Config", conf);
+ }
+ return conf;
+ }
+ set {
+ AppDomain.CurrentDomain.SetData ("ConfigurationSettings.Config", value);
+ }
+ }
+#endif
static object lockobj = new object ();
private ConfigurationSettings ()
{
}
+#if NET_2_0
+ [Obsolete ("This method is obsolete, it has been replaced by System.Configuration!System.Configuration.ConfigurationManager.GetSection")]
+#endif
public static object GetConfig (string sectionName)
{
+#if NET_2_0 && CONFIGURATION_DEP
+ return ConfigurationManager.GetSection (sectionName);
+#else
return config.GetConfig (sectionName);
+#endif
}
#if NET_2_0
//
class DefaultConfig : IConfigurationSystem
{
- static readonly DefaultConfig instance = new DefaultConfig ();
+#if !TARGET_JVM
+ static readonly DefaultConfig instance = new DefaultConfig ();
+#else
+ static DefaultConfig instance {
+ get {
+ DefaultConfig conf = (DefaultConfig) AppDomain.CurrentDomain.GetData ("DefaultConfig.instance");
+ if (conf == null) {
+ conf = new DefaultConfig ();
+ AppDomain.CurrentDomain.SetData ("DefaultConfig.instance", conf);
+ }
+ return conf;
+ }
+ set {
+ AppDomain.CurrentDomain.SetData ("DefaultConfig.instance", value);
+ }
+ }
+#endif
ConfigurationData config;
private DefaultConfig ()
return;
ConfigurationData data = new ConfigurationData ();
- if (!data.Load (GetMachineConfigPath ()))
- throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ());
+ if (data.LoadString (GetBundledMachineConfig ())) {
+ // do nothing
+ } else {
+ if (!data.Load (GetMachineConfigPath ()))
+ throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ());
+ }
string appfile = GetAppConfigPath ();
if (appfile == null) {
config = data;
config = data;
}
}
-
+#if TARGET_JVM
+ internal static string GetBundledMachineConfig ()
+ {
+ return null;
+ }
+ internal static string GetMachineConfigPath ()
+ {
+ return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
+ }
+#else
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern private static string get_bundled_machine_config ();
+ internal static string GetBundledMachineConfig ()
+ {
+ return get_bundled_machine_config ();
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern private static string get_machine_config_path ();
-
internal static string GetMachineConfigPath ()
{
return get_machine_config_path ();
}
-
+#endif
private static string GetAppConfigPath ()
{
AppDomainSetup currentInfo = AppDomain.CurrentDomain.SetupInformation;
MachineOnly,
MachineToApplication
}
-
+
class SectionData
{
public readonly string SectionName;
public readonly bool AllowLocation;
public readonly AllowDefinition AllowDefinition;
public string FileName;
+ public readonly bool RequirePermission;
public SectionData (string sectionName, string typeName,
- bool allowLocation, AllowDefinition allowDefinition)
+ bool allowLocation, AllowDefinition allowDefinition, bool requirePermission)
{
SectionName = sectionName;
TypeName = typeName;
AllowLocation = allowLocation;
AllowDefinition = allowDefinition;
+ RequirePermission = requirePermission;
}
}
-
+
class ConfigurationData
{
ConfigurationData parent;
Hashtable factories;
+ static object removedMark = new object ();
+ static object emptyMark = new object ();
+#if (XML_DEP)
Hashtable pending;
string fileName;
- static object removedMark = new object ();
static object groupMark = new object ();
- static object emptyMark = new object ();
+#endif
Hashtable cache;
- Hashtable FileCache {
- get {
+ Hashtable FileCache {
+ get {
if (cache != null)
return cache;
cache = new Hashtable ();
- return cache;
- }
- }
+ return cache;
+ }
+ }
public ConfigurationData () : this (null)
{
factories = new Hashtable ();
}
+ // SECURITY-FIXME: limit this with an imperative assert for reading the specific file
+ [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
public bool Load (string fileName)
{
+#if (XML_DEP)
this.fileName = fileName;
- if (fileName == null || !File.Exists (fileName))
+ if (fileName == null
+#if !TARGET_JVM
+ || !File.Exists (fileName)
+#endif
+)
return false;
-#if (XML_DEP)
+
XmlTextReader reader = null;
try {
+#if !TARGET_JVM
FileStream fs = new FileStream (fileName, FileMode.Open, FileAccess.Read);
+#else
+ Stream fs = (Stream) vmw.common.IOUtils.getStream (fileName);
+
+ //patch for machine.config
+ if (fs == null && fileName.EndsWith ("machine.config")) {
+ fs = (Stream) IOUtils.getStreamForGHConfigs (fileName);
+ }
+
+ if (fs == null) {
+ return false;
+ }
+#endif
reader = new XmlTextReader (fs);
- InitRead (reader);
- ReadConfigFile (reader);
+ if (InitRead (reader))
+ ReadConfigFile (reader);
} catch (ConfigurationException) {
throw;
} catch (Exception e) {
#endif
return true;
}
+
+ public bool LoadString (string data)
+ {
+ if (data == null)
+ return false;
+#if (XML_DEP)
+ XmlTextReader reader = null;
+ try {
+ TextReader tr = new StringReader (data);
+ reader = new XmlTextReader (tr);
+ if (InitRead (reader))
+ ReadConfigFile (reader);
+ } catch (ConfigurationException) {
+ throw;
+ } catch (Exception e) {
+ throw new ConfigurationException ("Error reading " + fileName, e);
+ } finally {
+ if (reader != null)
+ reader.Close();
+ }
+#endif
+ return true;
+ }
+
object GetHandler (string sectionName)
{
lock (factories) {
return GetInnerDoc (doc, 0, sectionPath);
}
-
+
object GetConfigInternal (string sectionName)
{
object handler = GetHandler (sectionName);
config = this.FileCache [sectionName];
}
- if (config == emptyMark)
- return null;
+ if (config == emptyMark)
+ return null;
- if (config != null)
- return config;
+ if (config != null)
+ return config;
lock (this) {
config = GetConfigInternal (sectionName);
}
return config;
- }
+ }
private object LookForFactory (string key)
{
return null;
}
#if (XML_DEP)
- private void InitRead (XmlTextReader reader)
+ private bool InitRead (XmlTextReader reader)
{
reader.MoveToContent ();
if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
if (reader.HasAttributes)
ThrowException ("Unrecognized attribute in root element", reader);
-
- MoveToNextElement (reader);
+ if (reader.IsEmptyElement) {
+ reader.Skip ();
+ return false;
+ }
+ reader.Read ();
+ reader.MoveToContent ();
+ return reader.NodeType != XmlNodeType.EndElement;
}
+ // FIXME: this approach is not always safe and likely to cause bugs.
private void MoveToNextElement (XmlTextReader reader)
{
while (reader.Read ()) {
string nameValue = null;
string typeValue = null;
string allowLoc = null, allowDef = null;
+ bool requirePermission = false;
+ string requirePer = null;
bool allowLocation = true;
AllowDefinition allowDefinition = AllowDefinition.Everywhere;
continue;
}
+ if (attName == "requirePermission") {
+ if (requirePer != null)
+ ThrowException ("Duplicated requirePermission attribute.", reader);
+ requirePer = reader.Value;
+ requirePermission = (requirePer == "true");
+ if (!requirePermission && requirePer != "false")
+ ThrowException ("Invalid attribute value", reader);
+ continue;
+ }
+
if (attName == "allowDefinition") {
if (allowDef != null)
ThrowException ("Duplicated allowDefinition attribute.", reader);
object o = LookForFactory (nameValue);
if (o != null && o != removedMark)
ThrowException ("Already have a factory for " + nameValue, reader);
- SectionData section = new SectionData (nameValue, typeValue, allowLocation, allowDefinition);
+ SectionData section = new SectionData (nameValue, typeValue, allowLocation,
+ allowDefinition, requirePermission);
section.FileName = fileName;
factories [nameValue] = section;
- MoveToNextElement (reader);
+ if (reader.IsEmptyElement)
+ reader.Skip ();
+ else {
+ reader.Read ();
+ reader.MoveToContent ();
+ if (reader.NodeType != XmlNodeType.EndElement)
+ // sub-section inside a section
+ ReadSections (reader, nameValue);
+ reader.ReadEndElement ();
+ }
+ reader.MoveToContent ();
}
private void ReadRemoveSection (XmlTextReader reader, string sectionName)
ThrowException ("Duplicate 'name' attribute.", reader);
value = reader.Value;
}
- else
-#if NET_2_0 && CONFIGURATION_2_0
+ else
+#if NET_2_0
if (reader.Name != "type")
#endif
ThrowException ("Unrecognized attribute.", reader);
if (value == null)
ThrowException ("No 'name' attribute.", reader);
-
+
if (value == "location")
ThrowException ("location is a reserved section name", reader);
-
+
if (configSection != null)
value = configSection + '/' + value;
ThrowException ("Already have a factory for " + value, reader);
factories [value] = groupMark;
- MoveToNextElement (reader);
- ReadSections (reader, value);
+
+ if (reader.IsEmptyElement) {
+ reader.Skip ();
+ reader.MoveToContent ();
+ } else {
+ reader.Read ();
+ reader.MoveToContent ();
+ if (reader.NodeType != XmlNodeType.EndElement)
+ ReadSections (reader, value);
+ reader.ReadEndElement ();
+ reader.MoveToContent ();
+ }
}
+ // It stops XmlReader consumption at where it found
+ // surrounding EndElement i.e. EndElement is not consumed here
private void ReadSections (XmlTextReader reader, string configSection)
{
int depth = reader.Depth;
- while (reader.Depth == depth) {
+ for (reader.MoveToContent ();
+ reader.Depth == depth;
+ reader.MoveToContent ()) {
string name = reader.Name;
if (name == "section") {
ReadSection (reader, configSection);
private void ReadConfigFile (XmlTextReader reader)
{
- int depth = reader.Depth;
- while (!reader.EOF && reader.Depth == depth) {
+ //int depth = reader.Depth;
+ for (reader.MoveToContent ();
+ !reader.EOF && reader.NodeType != XmlNodeType.EndElement;
+ reader.MoveToContent ()) {
string name = reader.Name;
if (name == "configSections") {
if (reader.HasAttributes)
ThrowException ("Unrecognized attribute in <configSections>.", reader);
-
- MoveToNextElement (reader);
- if (reader.Depth > depth)
- ReadSections (reader, null);
+ if (reader.IsEmptyElement)
+ reader.Skip ();
+ else {
+ reader.Read ();
+ reader.MoveToContent ();
+ if (reader.NodeType != XmlNodeType.EndElement)
+ ReadSections (reader, null);
+ reader.ReadEndElement ();
+ }
} else if (name != null && name != "") {
StorePending (name, reader);
MoveToNextElement (reader);
}
}
}
-
+
private void ThrowException (string text, XmlTextReader reader)
{
throw new ConfigurationException (text, fileName, reader.LineNumber);