protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { string name = reader.Name; base.DeserializeElement(reader, serializeCollectionKey); if ((this.File != null) && (this.File.Length > 0)) { string file; string source = base.ElementInformation.Source; if (string.IsNullOrEmpty(source)) { file = this.File; } else { file = Path.Combine(Path.GetDirectoryName(source), this.File); } if (System.IO.File.Exists(file)) { int lineOffset = 0; string rawXml = null; using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (XmlUtil util = new XmlUtil(stream, file, true)) { if (util.Reader.Name != name) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_name_value_file_section_file_invalid_root", new object[] { name }), util); } lineOffset = util.Reader.LineNumber; rawXml = util.CopySection(); while (!util.Reader.EOF) { if (util.Reader.NodeType != XmlNodeType.Comment) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_source_file_format"), util); } util.Reader.Read(); } } } ConfigXmlReader reader2 = new ConfigXmlReader(rawXml, file, lineOffset); reader2.Read(); if (reader2.MoveToNextAttribute()) { throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_base_unrecognized_attribute", new object[] { reader2.Name }), reader2); } reader2.MoveToElement(); base.DeserializeElement(reader2, serializeCollectionKey); } } }
internal static System.Configuration.OverrideMode ParseOverrideModeXmlValue(string value, XmlUtil xmlUtil) { switch (value) { case "Inherit": return System.Configuration.OverrideMode.Inherit; case "Allow": return System.Configuration.OverrideMode.Allow; case "Deny": return System.Configuration.OverrideMode.Deny; } throw new ConfigurationErrorsException(System.Configuration.SR.GetString("Config_section_override_mode_attribute_invalid"), xmlUtil); }
internal static OverrideMode ParseOverrideModeXmlValue(string value, XmlUtil xmlUtil) { // 'value' is the string representation of OverrideMode enum // Try to parse the string to the enum and generate errors if not possible switch (value) { case BaseConfigurationRecord.KeywordOverridemodeInherit: return OverrideMode.Inherit; case BaseConfigurationRecord.KeywordOverridemodeAllow: return OverrideMode.Allow; case BaseConfigurationRecord.KeywordOverridemodeDeny: return OverrideMode.Deny; default: throw new ConfigurationErrorsException( SR.Config_section_override_mode_attribute_invalid, xmlUtil); } }
// InitConfigFromFile // // Init the Config From the File. // private void InitConfigFromFile() { bool implicitSectionsAdded = false; try { // If initialization should be delayed, do not read the file. if (ClassFlags[ClassSupportsDelayedInit] && Host.IsInitDelayed(this)) { // determine the root of delayed initialization if (_parent._initDelayedRoot == null) { _initDelayedRoot = this; } else { _initDelayedRoot = _parent._initDelayedRoot; } } else { // // This parent of a record that is not initDelayed must also // not be initDelayed. // Debug.Assert(!_parent.IsInitDelayed, "!_parent.IsInitDelayed"); using (Impersonate()) { // // Get the stream name. Note that this may be an expensive operation // for the client configuration host, which is why it comes after the // check for delayed init. // ConfigStreamInfo.StreamName = Host.GetStreamName(_configPath); if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { // Lets listen to the stream ConfigStreamInfo.StreamVersion = MonitorStream(null, null, ConfigStreamInfo.StreamName); using (Stream stream = Host.OpenStreamForRead(ConfigStreamInfo.StreamName)) { if (stream == null) { // There is no stream to load from return; } ConfigStreamInfo.HasStream = true; // Determine whether or not to prefetch. _flags[PrefetchAll] = Host.PrefetchAll(_configPath, ConfigStreamInfo.StreamName); using (XmlUtil xmlUtil = new XmlUtil(stream, ConfigStreamInfo.StreamName, true, _initErrors)) { ConfigStreamInfo.StreamEncoding = xmlUtil.Reader.Encoding; // Read the factories Hashtable factoryList = ScanFactories(xmlUtil); _factoryRecords = factoryList; // Add implicit sections before scanning sections AddImplicitSections(null); implicitSectionsAdded = true; // Read the sections themselves if (xmlUtil.Reader.Depth == 1) { ScanSections(xmlUtil); } } } } } } } // // Capture all exceptions and include them in _initErrors so execution in Init can continue. // catch (XmlException e) { // // Treat invalid XML as unrecoverable by replacing all errors with the XML error. // _initErrors.SetSingleGlobalError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0)); } catch (Exception e) { _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, 0), ExceptionAction.Global); } catch { _initErrors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, ConfigStreamInfo.StreamName, 0), ExceptionAction.Global); } // // If there are global errors that make all input invalid, // reset our state so that inherited configuration can still be used, // including location sections that apply to this file. // if (_initErrors.HasGlobalErrors) { // // Parsing of a section may have been in progress when the exception // was thrown, so clear any accumulated local errors. // _initErrors.ResetLocalErrors(); // // Stop monitoring any configSource streams, but still continue // to monitor the main config file if it was successfully monitored. // HybridDictionary streamInfos = null; lock (this) { if (ConfigStreamInfo.HasStreamInfos) { streamInfos = ConfigStreamInfo.StreamInfos; ConfigStreamInfo.ClearStreamInfos(); if (!String.IsNullOrEmpty(ConfigStreamInfo.StreamName)) { StreamInfo fileStreamInfo = (StreamInfo) streamInfos[ConfigStreamInfo.StreamName]; // add this file's streaminfo to the now empty list if (fileStreamInfo != null) { streamInfos.Remove(ConfigStreamInfo.StreamName); ConfigStreamInfo.StreamInfos.Add(ConfigStreamInfo.StreamName, fileStreamInfo); } } } } // Stop monitoring streams outside the lock, to prevent deadlock. if (streamInfos != null) { foreach (StreamInfo streamInfo in streamInfos.Values) { if (streamInfo.IsMonitored) { Host.StopMonitoringStreamForChanges(streamInfo.StreamName, ConfigStreamInfo.CallbackDelegate); } } } // Remove file input if (_sectionRecords != null) { List<SectionRecord> removes = null; foreach (SectionRecord sectionRecord in _sectionRecords.Values) { if (sectionRecord.HasLocationInputs) { // Remove any file input sectionRecord.RemoveFileInput(); } else { // Remove the entire section record if (removes == null) { removes = new List<SectionRecord>(); } removes.Add(sectionRecord); } } if (removes != null) { foreach (SectionRecord sectionRecord in removes) { _sectionRecords.Remove(sectionRecord.ConfigKey); } } } // Remove all location section input defined here if (_locationSections != null) { _locationSections.Clear(); } // Remove all factory records if (_factoryRecords != null) { _factoryRecords.Clear(); } } if (!implicitSectionsAdded) { // Always add implicit sections no matter we have a file or not. AddImplicitSections(null); } }
private void ScanLocationSection(XmlUtil xmlUtil) { string locationSubPath = null; bool allowOverride = true; bool inheritInChildApp = true; int errorCountBeforeScan = xmlUtil.SchemaErrors.GlobalErrorCount; // Get the location section attributes while (xmlUtil.Reader.MoveToNextAttribute()) { switch (xmlUtil.Reader.Name) { case KEYWORD_LOCATION_PATH: locationSubPath = xmlUtil.Reader.Value; break; case KEYWORD_LOCATION_ALLOWOVERRIDE: xmlUtil.VerifyAndGetBooleanAttribute( ExceptionAction.Global, true, out allowOverride); break; case KEYWORD_LOCATION_INHERITINCHILDAPPLICATIONS: xmlUtil.VerifyAndGetBooleanAttribute( ExceptionAction.Global, true, out inheritInChildApp); break; default: xmlUtil.AddErrorUnrecognizedAttribute(ExceptionAction.Global); break; } } xmlUtil.Reader.MoveToElement(); // if on an attribute move back to the element try { locationSubPath = NormalizeLocationSubPath(locationSubPath, xmlUtil); // // if (locationSubPath == null && !inheritInChildApp && Host.IsDefinitionAllowed(_configPath, ConfigurationAllowDefinition.MachineToWebRoot, ConfigurationAllowExeDefinition.MachineOnly)) { throw new ConfigurationErrorsException(SR.GetString(SR.Location_invalid_inheritInChildApplications_in_machine_or_root_web_config), xmlUtil); } } catch (ConfigurationErrorsException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Global); } // Skip over this location section if there are errors if (xmlUtil.SchemaErrors.GlobalErrorCount > errorCountBeforeScan) { xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); return; } // Scan elements of the location section if the path is the current path. // We do not add <location path="." /> to the _locationSections list. if (locationSubPath == null) { ScanSectionsRecursive(xmlUtil, string.Empty, true, null, !allowOverride, !inheritInChildApp); return; } // Skip over location sections for client config if (!_flags[SupportsLocation]) { xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); return; } AddLocation(locationSubPath); ScanSectionsRecursive(xmlUtil, string.Empty, true, locationSubPath, !allowOverride, !inheritInChildApp); }
static protected void VerifySectionName(string name, XmlUtil xmlUtil, ExceptionAction action, bool allowImplicit) { try { VerifySectionName(name, (IConfigErrorInfo) xmlUtil, allowImplicit); } catch (ConfigurationErrorsException ce) { xmlUtil.SchemaErrors.AddError(ce, action); } }
private int UpdateIndent(int oldIndent, XmlUtil xmlUtil, XmlUtilWriter utilWriter, int parentLinePosition) { int num = oldIndent; if ((xmlUtil.Reader.NodeType == XmlNodeType.Element) && utilWriter.IsLastLineBlank) { int trueLinePosition = xmlUtil.TrueLinePosition; if ((parentLinePosition < trueLinePosition) && (trueLinePosition <= (parentLinePosition + 10))) { num = trueLinePosition - parentLinePosition; } } return num; }
private void ScanSectionsRecursive( XmlUtil xmlUtil, string parentConfigKey, bool inLocation, string locationSubPath, bool lockChildren, bool skipInChildApps) { // discard any accumulated local errors xmlUtil.SchemaErrors.ResetLocalErrors(); int depth; // only move to child nodes when not on first level (we've already passed the first <configsections>) if (parentConfigKey.Length == 0 && !inLocation) { depth = 0; } else { depth = xmlUtil.Reader.Depth; xmlUtil.StrictReadToNextElement(ExceptionAction.NonSpecific); } while (xmlUtil.Reader.Depth == depth + 1) { string tagName = xmlUtil.Reader.Name; // // Check for reserved elements before looking up the factory, // which may have the same name if it is in error. // if (tagName == KEYWORD_CONFIGSECTIONS) { // Error: duplicate <configSections> tag, or <configSections> not the first tag under <configuration> xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_client_config_too_many_configsections_elements, tagName), xmlUtil), ExceptionAction.NonSpecific); xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); continue; } if (tagName == KEYWORD_LOCATION) { if (parentConfigKey.Length > 0 || inLocation) { // Error: <location> section not at top level xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_location_location_not_allowed), xmlUtil), ExceptionAction.Global); xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); } else { // Recurse into the location section ScanLocationSection(xmlUtil); } continue; } string configKey = CombineConfigKey(parentConfigKey, tagName); FactoryRecord factoryRecord = FindFactoryRecord(configKey, true); if (factoryRecord == null) { // // if (!ClassFlags[ClassIgnoreLocalErrors]) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_unrecognized_configuration_section, configKey), xmlUtil), ExceptionAction.Local); } VerifySectionName(tagName, xmlUtil, ExceptionAction.Local, false); factoryRecord = new FactoryRecord( configKey, parentConfigKey, tagName, typeof(DefaultSection).AssemblyQualifiedName, true, // allowLocation ConfigurationAllowDefinition.Everywhere, ConfigurationAllowExeDefinition.MachineToRoamingUser, true, // restartOnExternalChanges true, // requirePermission _flags[IsTrusted], true, // isUndeclared null, -1); // Add any errors we may have encountered to the factory record, // so that child config that also refer to this unrecognized section // get the error. factoryRecord.AddErrors(xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(true)); // Add the factory to the list of factories EnsureFactories()[configKey] = factoryRecord; } if (factoryRecord.IsGroup) { // // Section Group // if (factoryRecord.HasErrors) { xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); } else { if (xmlUtil.Reader.AttributeCount > 0) { while (xmlUtil.Reader.MoveToNextAttribute()) { if (IsReservedAttributeName(xmlUtil.Reader.Name)) { xmlUtil.AddErrorReservedAttribute(ExceptionAction.NonSpecific); } } xmlUtil.Reader.MoveToElement(); // if on an attribute move back to the element } // Recurse into group definition ScanSectionsRecursive(xmlUtil, configKey, inLocation, locationSubPath, lockChildren, skipInChildApps); } } else { // // Section // configKey = factoryRecord.ConfigKey; string fileName = xmlUtil.Filename; int lineNumber = xmlUtil.LineNumber; string rawXml = null; string configSource = null; string configSourceStreamName = null; object configSourceStreamVersion = null; string protectionProviderName = null; bool isSectionLocked = false; bool positionedAtNextElement = false; bool isFileInput = (locationSubPath == null); if (!factoryRecord.HasErrors) { // We have a valid factoryRecord for a section if (inLocation && factoryRecord.AllowLocation == false) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_section_cannot_be_used_in_location), xmlUtil), ExceptionAction.Local); } // Verify correctness for file inputs. if (isFileInput) { // Verify that the section is unique SectionRecord sectionRecord = GetSectionRecord(configKey, true); if (sectionRecord != null && sectionRecord.HasFileInput) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_sections_must_be_unique), xmlUtil), ExceptionAction.Local); } // Verify that the definition is allowed. try { VerifyDefinitionAllowed(factoryRecord, _configPath, xmlUtil); } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } } // Verify that section is unlocked, both for file and location inputs. try { VerifySectionUnlocked(configKey, xmlUtil); } catch (ConfigurationException ce) { isSectionLocked = true; xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } // check for configSource or protectionProvider if (xmlUtil.Reader.AttributeCount >= 1) { // First do all the attributes reading without advancing the reader. string configSourceAttribute = xmlUtil.Reader.GetAttribute(KEYWORD_CONFIGSOURCE); if (configSourceAttribute != null) { try { configSource = NormalizeConfigSource(configSourceAttribute, xmlUtil); } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } if (xmlUtil.Reader.AttributeCount != 1) { // Error: elements with configSource should not have other attributes xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_source_syntax_error), xmlUtil), ExceptionAction.Local); } } string protectionProviderAttribute = xmlUtil.Reader.GetAttribute(KEYWORD_PROTECTION_PROVIDER); if (protectionProviderAttribute != null) { try { protectionProviderName = ValidateProtectionProviderAttribute(protectionProviderAttribute, xmlUtil); } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } if (xmlUtil.Reader.AttributeCount != 1) { // Error: elements with protectionProvider should not have other attributes xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Protection_provider_syntax_error), xmlUtil), ExceptionAction.Local); } } // The 2nd part of the configSource check requires advancing the reader. // Please note that this part should be done only AFTER all other attributes // checking are done. if (configSourceAttribute != null) { if (!xmlUtil.Reader.IsEmptyElement) { while (xmlUtil.Reader.Read()) { XmlNodeType t = xmlUtil.Reader.NodeType; if (t == XmlNodeType.EndElement) break; if (t != XmlNodeType.Comment) { // Error: elements with configSource should not subelements other than comments xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_source_syntax_error), xmlUtil), ExceptionAction.Local); if (t == XmlNodeType.Element) { xmlUtil.StrictSkipToOurParentsEndElement(ExceptionAction.NonSpecific); } else { xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); } positionedAtNextElement = true; break; } } } } } if (configSource != null) { try { try { configSourceStreamName = Host.GetStreamNameForConfigSource(ConfigStreamInfo.StreamName, configSource); } catch (Exception e) { throw ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_source_invalid), e, xmlUtil); } ValidateUniqueConfigSource(configKey, configSourceStreamName, configSource, xmlUtil); configSourceStreamVersion = MonitorStream(configKey, configSource, configSourceStreamName); } catch (ConfigurationException ex) { xmlUtil.SchemaErrors.AddError(ex, ExceptionAction.Local); } } // // prefetch the raw xml // if (!xmlUtil.SchemaErrors.HasLocalErrors) { if (configSource == null && ShouldPrefetchRawXml(factoryRecord)) { Debug.Assert(!positionedAtNextElement, "!positionedAtNextElement"); rawXml = xmlUtil.CopySection(); if (xmlUtil.Reader.NodeType != XmlNodeType.Element) { xmlUtil.VerifyIgnorableNodeType(ExceptionAction.NonSpecific); xmlUtil.StrictReadToNextElement(ExceptionAction.NonSpecific); } positionedAtNextElement = true; } } } // Get the list of errors before advancing the reader List<ConfigurationException> localErrors = xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(isFileInput); // advance the reader to the next element if (!positionedAtNextElement) { xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); } // Add the input either to: // 1. The file input at the current config level, or // 2. LocationSections, where it will be used in sub paths bool addInput = true; if (isFileInput) { // If isFileInput==true, Input added will be used against this config level. // Need to check if we need to skip it due to inheritInChildApplications. if (ShouldSkipDueToInheritInChildApplications(skipInChildApps)) { addInput = false; } } else { if (!_flags[SupportsLocation]) { // Skip if we have a location input but we don't support location tag. addInput = false; } } if (addInput) { string targetConfigPath = (locationSubPath == null) ? _configPath : null; SectionXmlInfo sectionXmlInfo = new SectionXmlInfo( configKey, _configPath, targetConfigPath, locationSubPath, fileName, lineNumber, ConfigStreamInfo.StreamVersion, rawXml, configSource, configSourceStreamName, configSourceStreamVersion, protectionProviderName, lockChildren, skipInChildApps); if (locationSubPath == null) { // // Add this file input to the section record // // We've already checked for locked above, so use skip the second check // and set the locked bit. SectionRecord sectionRecord = EnsureSectionRecordUnsafe(configKey, true); Debug.Assert(!sectionRecord.Locked || isSectionLocked, "!sectionRecord.Locked || isSectionLocked"); if (isSectionLocked) { sectionRecord.Locked = true; } SectionInput fileInput = new SectionInput(sectionXmlInfo, localErrors); sectionRecord.AddFileInput(fileInput); } else { // // Add this location input to this list of location sections // LocationSectionRecord locationSectionRecord = new LocationSectionRecord(sectionXmlInfo, localErrors); EnsureLocationSections().Add(locationSectionRecord); } } } } }
private bool CopyConfigDefinitionsRecursive(ConfigDefinitionUpdates configDefinitionUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, bool locationPathApplies, LocationUpdates locationUpdates, SectionUpdates sectionUpdates, bool addNewSections, string group, int parentLinePosition, int parentIndent) { int trueLinePosition; int num3; bool flag = false; XmlTextReader reader = xmlUtil.Reader; int indent = this.UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { trueLinePosition = xmlUtil.TrueLinePosition; num3 = trueLinePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { trueLinePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { trueLinePosition = parentLinePosition + indent; num3 = 0; } if ((sectionUpdates != null) && addNewSections) { sectionUpdates.IsNew = false; string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.AppendSpacesToLinePosition(trueLinePosition); bool skipFirstIndent = true; foreach (string str in movedSectionNames) { DefinitionUpdate definitionUpdate = sectionUpdates.GetDefinitionUpdate(str); this.WriteSectionUpdate(utilWriter, definitionUpdate, trueLinePosition, indent, skipFirstIndent); skipFirstIndent = false; utilWriter.AppendNewLine(); flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } } if (reader.NodeType == XmlNodeType.Element) { int depth = reader.Depth; while (reader.Depth == depth) { bool flag3 = false; DefinitionUpdate update = null; bool flag4 = locationPathApplies; LocationUpdates updates = locationUpdates; SectionUpdates updates2 = sectionUpdates; bool flag5 = addNewSections; string str2 = group; bool flag6 = false; indent = this.UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); trueLinePosition = xmlUtil.TrueLinePosition; string name = reader.Name; if (name == "location") { string locationSubPath = BaseConfigurationRecord.NormalizeLocationSubPath(reader.GetAttribute("path"), xmlUtil); flag4 = false; OverrideModeSetting locationDefault = OverrideModeSetting.LocationDefault; bool inheritInChildApps = true; if (base.IsLocationConfig) { if (locationSubPath == null) { flag4 = false; } else { flag4 = StringUtil.EqualsIgnoreCase(base.ConfigPath, base.Host.GetConfigPathFromLocationSubPath(base.Parent.ConfigPath, locationSubPath)); } } else { flag4 = locationSubPath == null; } if (flag4) { string attribute = reader.GetAttribute("allowOverride"); if (attribute != null) { locationDefault = OverrideModeSetting.CreateFromXmlReadValue(bool.Parse(attribute)); } string str6 = reader.GetAttribute("overrideMode"); if (str6 != null) { locationDefault = OverrideModeSetting.CreateFromXmlReadValue(OverrideModeSetting.ParseOverrideModeXmlValue(str6, null)); } string str7 = reader.GetAttribute("inheritInChildApplications"); if (str7 != null) { inheritInChildApps = bool.Parse(str7); } configDefinitionUpdates.FlagLocationWritten(); } if (reader.IsEmptyElement) { if (flag4 && (configDefinitionUpdates.FindLocationUpdates(locationDefault, inheritInChildApps) != null)) { flag4 = true; } else { flag4 = false; } } else if (flag4) { if (configDefinitionUpdates != null) { updates = configDefinitionUpdates.FindLocationUpdates(locationDefault, inheritInChildApps); if (updates != null) { flag3 = true; updates2 = updates.SectionUpdates; if ((base._locationSubPath == null) && updates.IsDefault) { flag5 = false; } } } } else if ((this.HasRemovedSectionsOrGroups && !base.IsLocationConfig) && base.Host.SupportsLocation) { flag3 = true; updates = null; updates2 = null; flag5 = false; } } else { string configKey = BaseConfigurationRecord.CombineConfigKey(group, name); FactoryRecord record = base.FindFactoryRecord(configKey, false); if (record == null) { if (!flag4 && !base.IsLocationConfig) { flag6 = true; } } else if (record.IsGroup) { if (reader.IsEmptyElement) { if (!flag4 && !base.IsLocationConfig) { flag6 = true; } } else if (sectionUpdates != null) { SectionUpdates sectionUpdatesForGroup = sectionUpdates.GetSectionUpdatesForGroup(name); if (sectionUpdatesForGroup != null) { flag3 = true; str2 = configKey; updates2 = sectionUpdatesForGroup; } } else if (!flag4 && !base.IsLocationConfig) { if ((this._removedSectionGroups != null) && this._removedSectionGroups.Contains(configKey)) { flag6 = true; } else { flag3 = true; str2 = configKey; updates = null; updates2 = null; flag5 = false; } } } else if (sectionUpdates != null) { update = sectionUpdates.GetDefinitionUpdate(configKey); } else if ((!flag4 && !base.IsLocationConfig) && ((this._removedSections != null) && this._removedSections.Contains(configKey))) { flag6 = true; } } if (flag3) { object o = utilWriter.CreateStreamCheckpoint(); xmlUtil.CopyXmlNode(utilWriter); xmlUtil.CopyReaderToNextElement(utilWriter, true); bool flag8 = this.CopyConfigDefinitionsRecursive(configDefinitionUpdates, xmlUtil, utilWriter, flag4, updates, updates2, flag5, str2, trueLinePosition, indent); xmlUtil.CopyXmlNode(utilWriter); if (flag8) { flag = true; } else { utilWriter.RestoreStreamCheckpoint(o); } xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool flag9; if (update == null) { flag9 = flag4 || flag6; } else { flag9 = false; if (update.UpdatedXml != null) { ConfigurationSection result = (ConfigurationSection) update.SectionRecord.Result; if (string.IsNullOrEmpty(result.SectionInformation.ConfigSource) || result.SectionInformation.ConfigSourceModified) { flag9 = true; this.WriteSectionUpdate(utilWriter, update, trueLinePosition, indent, true); flag = true; } } } if (flag9) { xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); flag = true; } } } } if (((sectionUpdates != null) && addNewSections) && sectionUpdates.HasNewSectionGroups()) { trueLinePosition = parentLinePosition + indent; if (reader.NodeType == XmlNodeType.EndElement) { if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { num3 = 0; } utilWriter.AppendSpacesToLinePosition(trueLinePosition); if (this.WriteNewConfigDefinitionsRecursive(utilWriter, sectionUpdates, trueLinePosition, indent, true)) { flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } return flag; }
protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { string elementName = reader.Name; base.DeserializeElement(reader, serializeCollectionKey); if (!(File?.Length > 0)) return; string sourceFileFullPath; // Determine file location string configFile = ElementInformation.Source; if (string.IsNullOrEmpty(configFile)) sourceFileFullPath = File; else { string configFileDirectory = Path.GetDirectoryName(configFile); sourceFileFullPath = Path.Combine(configFileDirectory, File); } if (!IO.File.Exists(sourceFileFullPath)) return; int lineOffset; string rawXml; using ( Stream sourceFileStream = new FileStream(sourceFileFullPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (XmlUtil xmlUtil = new XmlUtil(sourceFileStream, sourceFileFullPath, true)) { if (xmlUtil.Reader.Name != elementName) { throw new ConfigurationErrorsException( string.Format(SR.Config_name_value_file_section_file_invalid_root, elementName), xmlUtil); } lineOffset = xmlUtil.Reader.LineNumber; rawXml = xmlUtil.CopySection(); // Detect if there is any XML left over after the section while (!xmlUtil.Reader.EOF) { XmlNodeType t = xmlUtil.Reader.NodeType; if (t != XmlNodeType.Comment) { throw new ConfigurationErrorsException(SR.Config_source_file_format, xmlUtil); } xmlUtil.Reader.Read(); } } } ConfigXmlReader internalReader = new ConfigXmlReader(rawXml, sourceFileFullPath, lineOffset); internalReader.Read(); if (internalReader.MoveToNextAttribute()) { throw new ConfigurationErrorsException( string.Format(SR.Config_base_unrecognized_attribute, internalReader.Name), (XmlReader)internalReader); } internalReader.MoveToElement(); base.DeserializeElement(internalReader, serializeCollectionKey); }
internal static OverrideMode ParseOverrideModeXmlValue(string value, XmlUtil xmlUtil) { // 'value' is the string representation of OverrideMode enum // Try to parse the string to the enum and generate errors if not possible switch (value) { case BaseConfigurationRecord.KEYWORD_OVERRIDEMODE_INHERIT: return OverrideMode.Inherit; case BaseConfigurationRecord.KEYWORD_OVERRIDEMODE_ALLOW: return OverrideMode.Allow; case BaseConfigurationRecord.KEYWORD_OVERRIDEMODE_DENY: return OverrideMode.Deny; default: throw new ConfigurationErrorsException( SR.GetString(SR.Config_section_override_mode_attribute_invalid), xmlUtil); } }
// Copy a config file, replacing sections with updates. private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { CheckPreamble(ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, filename, false)) { // copy up to the <configuration> node XmlTextReader reader = xmlUtil.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); xmlUtil.CopyReaderToNextElement(utilWriter, false); Debug.Assert(reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION, "reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGURATION"); int indent = DEFAULT_INDENT; int configurationElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigurationElement = reader.IsEmptyElement; // copy <configuration> node // if the node is an empty element, we may need to open it. string configurationStartElement; if (namespaceChange == NamespaceChange.Add) { configurationStartElement = string.Format( CultureInfo.InvariantCulture, FORMAT_CONFIGURATION_NAMESPACE, KEYWORD_CONFIGURATION_NAMESPACE); } else if (namespaceChange == NamespaceChange.Remove) { configurationStartElement = FORMAT_CONFIGURATION; } else { configurationStartElement = null; } bool needsChildren = (declarationUpdates != null || definitionUpdates != null); string configurationEndElement = xmlUtil.UpdateStartElement(utilWriter, configurationStartElement, needsChildren, configurationElementLinePosition, indent); bool foundConfigSectionsElement = false; if (!isEmptyConfigurationElement) { // copy up to the first element under <configuration> xmlUtil.CopyReaderToNextElement(utilWriter, true); // updateIndent indent = UpdateIndent(indent, xmlUtil, utilWriter, configurationElementLinePosition); if (reader.NodeType == XmlNodeType.Element && reader.Name == KEYWORD_CONFIGSECTIONS) { foundConfigSectionsElement = true; int configSectionsElementLinePosition = xmlUtil.TrueLinePosition; bool isEmptyConfigSectionsElement = reader.IsEmptyElement; // if no updates, copy the entire <configSections> element if (declarationUpdates == null) { xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } else { // copy <configSections>, and open it if it is an empty element string configSectionsEndElement = xmlUtil.UpdateStartElement( utilWriter, null, true, configSectionsElementLinePosition, indent); if (!isEmptyConfigSectionsElement) { // copy to next element under <configSections>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); // copy config declarations CopyConfigDeclarationsRecursive(declarationUpdates, xmlUtil, utilWriter, string.Empty, configSectionsElementLinePosition, indent); Debug.Assert(reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGSECTIONS, "reader.NodeType == XmlNodeType.EndElement && reader.Name == \"KEYWORD_CONFIGSECTIONS\""); } // write declarations not written by above copy if (declarationUpdates.HasUnretrievedSections()) { // determine the line position of the end element int endElementLinePosition = 0; if (configSectionsEndElement == null) { endElementLinePosition = xmlUtil.TrueLinePosition; } // indent a new line if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, configSectionsElementLinePosition + indent, indent, false); // restore spaces to end element if (configSectionsEndElement == null) { utilWriter.AppendSpacesToLinePosition(endElementLinePosition); } } // Copy the </configSections> element if (configSectionsEndElement == null) { xmlUtil.CopyXmlNode(utilWriter); } else { // note that configSectionsEndElement already contains the proper indenting utilWriter.Write(configSectionsEndElement); } // copy up to the next element under <configuration>, or up to closing </configSections> xmlUtil.CopyReaderToNextElement(utilWriter, true); } } } // Write new declarations if (!foundConfigSectionsElement && declarationUpdates != null) { bool skipFirstIndent = reader.Depth > 0 && reader.NodeType == XmlNodeType.Element; int newConfigSectionsLinePosition; if (skipFirstIndent) { newConfigSectionsLinePosition = xmlUtil.TrueLinePosition; } else { newConfigSectionsLinePosition = configurationElementLinePosition + indent; } WriteNewConfigDeclarations(declarationUpdates, utilWriter, newConfigSectionsLinePosition, indent, skipFirstIndent); } if (definitionUpdates != null) { // // Copy sections recursively. In the file we copy we start out at // location path="." allowOverride="true" inheritInChildApps="true" // bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } CopyConfigDefinitionsRecursive(definitionUpdates, xmlUtil, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, configurationElementLinePosition, indent); // Write new config sections from new groups. WriteNewConfigDefinitions(definitionUpdates, utilWriter, configurationElementLinePosition + indent, indent); #if DBG Debug.Assert(configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION), "configurationEndElement != null || (reader.NodeType == XmlNodeType.EndElement && reader.Name == KEYWORD_CONFIGURATION)"); #endif #if DBG { foreach (LocationUpdates l in definitionUpdates.LocationUpdatesList) { Debug.Assert(!l.SectionUpdates.HasUnretrievedSections(), "!l.SectionUpdates.HasUnretrievedSections()"); } } #endif } if (configurationEndElement != null) { // If we have to add closing config tag, then do it now // before copying extra whitespace/comments if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(configurationEndElement); } // // Copy the remainder of the file, the closing </configuration> node plus any whitespace // and comments // while (xmlUtil.CopyXmlNode(utilWriter)) { } } } }
private ConfigXmlReader FindSectionRecursive(string [] keys, int iKey, XmlUtil xmlUtil, ref int lineNumber) { string name = keys[iKey]; ConfigXmlReader section = null; int depth = xmlUtil.Reader.Depth; xmlUtil.ReadToNextElement(); while (xmlUtil.Reader.Depth > depth) { if (xmlUtil.Reader.Name == name) { if (iKey < keys.Length - 1) { // // We haven't reached the section yet, so keep evaluating // section = FindSectionRecursive(keys, iKey + 1, xmlUtil, ref lineNumber); if (section != null) { break; } continue; // don't call "Skip" -- FindSectionRecursive forwards the reader } else { // // We've reached the section. Load the section into a string. // string filename = ((IConfigErrorInfo)xmlUtil).Filename; int lineOffset = xmlUtil.Reader.LineNumber; string rawXml = xmlUtil.CopySection(); section = new ConfigXmlReader(rawXml, filename, lineOffset); break; } } else if (iKey == 0 && xmlUtil.Reader.Name == KEYWORD_LOCATION) { string locationSubPath = xmlUtil.Reader.GetAttribute(KEYWORD_LOCATION_PATH); bool isValid = false; try { locationSubPath = NormalizeLocationSubPath(locationSubPath, xmlUtil); isValid = true; } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.NonSpecific); } if (isValid && locationSubPath == null) { // // Location sections that don't have a subpath are treated // as ordinary sections. // section = FindSectionRecursive(keys, iKey, xmlUtil, ref lineNumber); if (section != null) { break; } continue; // don't call "Skip" -- FindSectionRecursive forwards the reader } } xmlUtil.SkipToNextElement(); } return section; }
private ConfigXmlReader LoadConfigSource(string name, SectionXmlInfo sectionXmlInfo) { string configSourceStreamName = sectionXmlInfo.ConfigSourceStreamName; try { using (Impersonate()) { using (Stream stream = Host.OpenStreamForRead(configSourceStreamName)) { if (stream == null) { throw new ConfigurationErrorsException( SR.GetString(SR.Config_cannot_open_config_source, sectionXmlInfo.ConfigSource), sectionXmlInfo); } using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, true)) { if (xmlUtil.Reader.Name != name) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_source_file_format), xmlUtil); } // Check for protectionProvider string protectionProviderAttribute = xmlUtil.Reader.GetAttribute(KEYWORD_PROTECTION_PROVIDER); if (protectionProviderAttribute != null) { if (xmlUtil.Reader.AttributeCount != 1) { // Error: elements with protectionProvider should not have other attributes throw new ConfigurationErrorsException(SR.GetString(SR.Protection_provider_syntax_error), xmlUtil); } sectionXmlInfo.ProtectionProviderName = ValidateProtectionProviderAttribute(protectionProviderAttribute, xmlUtil); } int lineOffset = xmlUtil.Reader.LineNumber; string rawXml = xmlUtil.CopySection(); // Detect if there is any XML left over after the section while (!xmlUtil.Reader.EOF) { XmlNodeType t = xmlUtil.Reader.NodeType; if (t != XmlNodeType.Comment) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_source_file_format), xmlUtil); } xmlUtil.Reader.Read(); } ConfigXmlReader section = new ConfigXmlReader(rawXml, configSourceStreamName, lineOffset); return section; } } } } catch { // Don't allow frames up the stack to run exception filters while impersonated. throw; } }
private ConfigXmlReader FindSection(string [] keys, SectionXmlInfo sectionXmlInfo, out int lineNumber) { lineNumber = 0; ConfigXmlReader section = null; try { using (Impersonate()) { using (Stream stream = Host.OpenStreamForRead(sectionXmlInfo.Filename)) { if ( !_flags[SupportsRefresh] && (stream == null || HasStreamChanged(sectionXmlInfo.Filename, sectionXmlInfo.StreamVersion))) { throw new ConfigurationErrorsException(SR.GetString(SR.Config_file_has_changed), sectionXmlInfo.Filename, 0); } if (stream != null) { using (XmlUtil xmlUtil = new XmlUtil(stream, sectionXmlInfo.Filename, true)) { if (sectionXmlInfo.SubPath == null) { section = FindSectionRecursive(keys, 0, xmlUtil, ref lineNumber); } else { // search children of <configuration> for <location> xmlUtil.ReadToNextElement(); while (xmlUtil.Reader.Depth > 0) { if (xmlUtil.Reader.Name == KEYWORD_LOCATION) { bool locationValid = false; string locationSubPathAttribute = xmlUtil.Reader.GetAttribute(KEYWORD_LOCATION_PATH); try { locationSubPathAttribute = NormalizeLocationSubPath(locationSubPathAttribute, xmlUtil); locationValid = true; } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.NonSpecific); } if (locationValid && StringUtil.EqualsIgnoreCase(sectionXmlInfo.SubPath, locationSubPathAttribute)) { section = FindSectionRecursive(keys, 0, xmlUtil, ref lineNumber); if (section != null) break; } } xmlUtil.SkipToNextElement(); } } // Throw accumulated errors ThrowIfParseErrors(xmlUtil.SchemaErrors); } } } } } // Don't allow frames up the stack to run exception filters while impersonated. catch { throw; } return section; }
private void CopyConfig(SectionUpdates declarationUpdates, ConfigDefinitionUpdates definitionUpdates, byte[] buffer, string filename, NamespaceChange namespaceChange, XmlUtilWriter utilWriter) { this.CheckPreamble(base.ConfigStreamInfo.StreamEncoding.GetPreamble(), utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil util = new XmlUtil(stream, filename, false)) { string str; XmlTextReader reader = util.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); util.CopyReaderToNextElement(utilWriter, false); int indent = 4; int trueLinePosition = util.TrueLinePosition; bool isEmptyElement = reader.IsEmptyElement; if (namespaceChange == NamespaceChange.Add) { str = string.Format(CultureInfo.InvariantCulture, "<configuration xmlns=\"{0}\">\r\n", new object[] { "http://schemas.microsoft.com/.NetConfiguration/v2.0" }); } else if (namespaceChange == NamespaceChange.Remove) { str = "<configuration>\r\n"; } else { str = null; } bool needsChildren = (declarationUpdates != null) || (definitionUpdates != null); string s = util.UpdateStartElement(utilWriter, str, needsChildren, trueLinePosition, indent); bool flag3 = false; if (!isEmptyElement) { util.CopyReaderToNextElement(utilWriter, true); indent = this.UpdateIndent(indent, util, utilWriter, trueLinePosition); if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "configSections")) { flag3 = true; int linePosition = util.TrueLinePosition; bool flag4 = reader.IsEmptyElement; if (declarationUpdates == null) { util.CopyOuterXmlToNextElement(utilWriter, true); } else { string str3 = util.UpdateStartElement(utilWriter, null, true, linePosition, indent); if (!flag4) { util.CopyReaderToNextElement(utilWriter, true); this.CopyConfigDeclarationsRecursive(declarationUpdates, util, utilWriter, string.Empty, linePosition, indent); } if (declarationUpdates.HasUnretrievedSections()) { int num4 = 0; if (str3 == null) { num4 = util.TrueLinePosition; } if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } this.WriteUnwrittenConfigDeclarations(declarationUpdates, utilWriter, linePosition + indent, indent, false); if (str3 == null) { utilWriter.AppendSpacesToLinePosition(num4); } } if (str3 == null) { util.CopyXmlNode(utilWriter); } else { utilWriter.Write(str3); } util.CopyReaderToNextElement(utilWriter, true); } } } if (!flag3 && (declarationUpdates != null)) { int num5; bool skipFirstIndent = (reader.Depth > 0) && (reader.NodeType == XmlNodeType.Element); if (skipFirstIndent) { num5 = util.TrueLinePosition; } else { num5 = trueLinePosition + indent; } this.WriteNewConfigDeclarations(declarationUpdates, utilWriter, num5, indent, skipFirstIndent); } if (definitionUpdates != null) { bool locationPathApplies = false; LocationUpdates locationUpdates = null; SectionUpdates sectionUpdates = null; if (!base.IsLocationConfig) { locationPathApplies = true; locationUpdates = definitionUpdates.FindLocationUpdates(OverrideModeSetting.LocationDefault, true); if (locationUpdates != null) { sectionUpdates = locationUpdates.SectionUpdates; } } this.CopyConfigDefinitionsRecursive(definitionUpdates, util, utilWriter, locationPathApplies, locationUpdates, sectionUpdates, true, string.Empty, trueLinePosition, indent); this.WriteNewConfigDefinitions(definitionUpdates, utilWriter, trueLinePosition + indent, indent); } if (s != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.Write(s); } while (util.CopyXmlNode(utilWriter)) { } } } }
private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (new XmlUtil(stream, configSourceStreamName, true)) { preamble = base.ConfigStreamInfo.StreamEncoding.GetPreamble(); } } this.CheckPreamble(preamble, utilWriter, buffer); using (Stream stream2 = new MemoryStream(buffer)) { using (XmlUtil util2 = new XmlUtil(stream2, configSourceStreamName, false)) { XmlTextReader reader = util2.Reader; reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); int indent = 4; int linePosition = 1; bool flag = util2.CopyReaderToNextElement(utilWriter, false); if (flag) { int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int num4 = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { num4 = reader.LinePosition - linePosition; break; } } int num5 = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { num5 = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (num5 > 0) { indent = num5; } else if (num4 > 0) { indent = num4; } } string s = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(s); if (flag) { while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || (reader.NodeType == XmlNodeType.EndElement)) { reader.Read(); } while (util2.CopyXmlNode(utilWriter)) { } } } } }
// RefreshFactoryRecord // // Refresh the Factory Record for a particular section. // private void RefreshFactoryRecord(string configKey) { Hashtable factoryList = null; FactoryRecord factoryRecord = null; ConfigurationSchemaErrors errors; errors = new ConfigurationSchemaErrors(); // Get Updated Factory List from File int lineNumber = 0; try { using (Impersonate()) { using (Stream stream = Host.OpenStreamForRead(ConfigStreamInfo.StreamName)) { if (stream != null) { ConfigStreamInfo.HasStream = true; using (XmlUtil xmlUtil = new XmlUtil(stream, ConfigStreamInfo.StreamName, true, errors)) { try { factoryList = ScanFactories(xmlUtil); ThrowIfParseErrors(xmlUtil.SchemaErrors); } catch { lineNumber = xmlUtil.LineNumber; throw; } } } } } // Add implicit sections to the factory list if (factoryList == null) { // But if factoryList isn't found in this config, we still try to // add implicit sections to an empty factoryList. factoryList = new Hashtable(); } AddImplicitSections(factoryList); if (factoryList != null) { factoryRecord = (FactoryRecord) factoryList[configKey]; } } // // Guarantee that exceptions contain the name of the stream and an approximate line number if available. // // And don't allow frames up the stack to run exception filters while impersonated. catch (Exception e) { errors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), e, ConfigStreamInfo.StreamName, lineNumber), ExceptionAction.Global); } catch { errors.AddError( ExceptionUtil.WrapAsConfigException(SR.GetString(SR.Config_error_loading_XML_file), null, ConfigStreamInfo.StreamName, lineNumber), ExceptionAction.Global); } // Set/Add/Remove Record // Note that the _factoryRecords hashtable is protected by the hierarchy lock. if (factoryRecord != null || HasFactoryRecords) { EnsureFactories()[configKey] = factoryRecord; } // Throw accumulated errors ThrowIfParseErrors(errors); }
// Copy configuration sections from the original configuration file. private bool CopyConfigDefinitionsRecursive( ConfigDefinitionUpdates configDefinitionUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, bool locationPathApplies, LocationUpdates locationUpdates, SectionUpdates sectionUpdates, bool addNewSections, string group, int parentLinePosition, int parentIndent) { bool wroteASection = false; XmlTextReader reader = xmlUtil.Reader; int linePosition; int indent; int startingLinePosition; indent = UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { linePosition = xmlUtil.TrueLinePosition; startingLinePosition = linePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { linePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { linePosition = parentLinePosition + indent; startingLinePosition = 0; } // // Write any new sections that apply to this group // if (sectionUpdates != null && addNewSections) { // Remove newness, so we won't write again sectionUpdates.IsNew = false; Debug.Assert(locationPathApplies, "locationPathApplies"); string[] movedSectionNames = sectionUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } utilWriter.AppendSpacesToLinePosition(linePosition); bool skipFirstIndent = true; foreach (string configKey in movedSectionNames) { DefinitionUpdate update = sectionUpdates.GetDefinitionUpdate(configKey); WriteSectionUpdate(utilWriter, update, linePosition, indent, skipFirstIndent); skipFirstIndent = false; utilWriter.AppendNewLine(); wroteASection = true; } // Restore the whitespace we used for the first element, which is either a start or an end element. utilWriter.AppendSpacesToLinePosition(startingLinePosition); } } if (reader.NodeType == XmlNodeType.Element) { // // For each element at this depth, either: // - Write the element verbatim and recurse due to a location section or group hierarchy element. // - Write the element verbatim because it is unchanged, or because the current location does // not apply. // - Write the updated XML for the section. // - Skip it because the section has been removed. // int depth = reader.Depth; while (reader.Depth == depth) { bool recurse = false; DefinitionUpdate update = null; bool elementLocationPathApplies = locationPathApplies; LocationUpdates recurseLocationUpdates = locationUpdates; SectionUpdates recurseSectionUpdates = sectionUpdates; bool recurseAddNewSections = addNewSections; string recurseGroup = group; bool removedSectionOrGroup = false; // update the lineposition and indent for each element indent = UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); linePosition = xmlUtil.TrueLinePosition; string elementName = reader.Name; if (elementName == KEYWORD_LOCATION) { string locationSubPathAttribute = reader.GetAttribute(KEYWORD_LOCATION_PATH); locationSubPathAttribute = NormalizeLocationSubPath(locationSubPathAttribute, xmlUtil); elementLocationPathApplies = false; OverrideModeSetting overrideMode = OverrideModeSetting.LocationDefault; bool inheritInChildApps = true; if (IsLocationConfig) { // For location config we will compare config paths instead of location strings // so that we dont end up comparing "1" with "Default Web Site" and ending up with the wrong result if (locationSubPathAttribute == null) { elementLocationPathApplies = false; } else { elementLocationPathApplies = StringUtil.EqualsIgnoreCase(ConfigPath, Host.GetConfigPathFromLocationSubPath(Parent.ConfigPath, locationSubPathAttribute)); } } else { Debug.Assert(LocationSubPath == null); // This is the same as doing StringUtil.EqualsIgnoreCase(_locationSubPath, locationSubPathAttribute) // but remember the first one is null. Also remember locationSubPathAttribute is already normalized elementLocationPathApplies = (locationSubPathAttribute == null); } if (elementLocationPathApplies) { // Retrieve overrideMode and InheritInChildApps string allowOverrideAttribute = reader.GetAttribute(KEYWORD_LOCATION_ALLOWOVERRIDE); if (allowOverrideAttribute != null) { overrideMode = OverrideModeSetting.CreateFromXmlReadValue(Boolean.Parse(allowOverrideAttribute)); } string overrideModeAttribute = reader.GetAttribute(KEYWORD_LOCATION_OVERRIDEMODE); if (overrideModeAttribute != null) { overrideMode = OverrideModeSetting.CreateFromXmlReadValue(OverrideModeSetting.ParseOverrideModeXmlValue(overrideModeAttribute, null)); Debug.Assert(allowOverrideAttribute == null, "allowOverride and overrideMode both detected in a <location> tag"); } string inheritInChildAppsAttribute = reader.GetAttribute(KEYWORD_LOCATION_INHERITINCHILDAPPLICATIONS); if (inheritInChildAppsAttribute != null) { inheritInChildApps = Boolean.Parse(inheritInChildAppsAttribute); } // Flag that we already have one of these locations configDefinitionUpdates.FlagLocationWritten(); } if (reader.IsEmptyElement) { if (elementLocationPathApplies && (configDefinitionUpdates.FindLocationUpdates(overrideMode, inheritInChildApps) != null)) { // If we are going to make updates here, then // delete the one that is here (so we can update later) elementLocationPathApplies = true; } else { // If not lets leave it elementLocationPathApplies = false; } } else { // recurse if this location applies to us if (elementLocationPathApplies) { if (configDefinitionUpdates != null) { recurseLocationUpdates = configDefinitionUpdates.FindLocationUpdates(overrideMode, inheritInChildApps); if (recurseLocationUpdates != null) { recurse = true; recurseSectionUpdates = recurseLocationUpdates.SectionUpdates; // If this is <location path=".">, we don't want to add moved sections // to it. if (_locationSubPath == null && recurseLocationUpdates.IsDefault) { recurseAddNewSections = false; } } } } else { // recurse if necessary to remove items in _removedSections and _removedGroups if (HasRemovedSectionsOrGroups && !IsLocationConfig && Host.SupportsLocation) { recurse = true; recurseLocationUpdates = null; recurseSectionUpdates = null; recurseAddNewSections = false; } } } } else { string configKey = CombineConfigKey(group, elementName); FactoryRecord factoryRecord = FindFactoryRecord(configKey, false); if (factoryRecord == null) { // The factory was deleted, so regardless of whether this is a // section or sectionGroup, it can be skipped. if (!elementLocationPathApplies && !IsLocationConfig) { removedSectionOrGroup = true; } } else if (factoryRecord.IsGroup) { if (reader.IsEmptyElement) { if (!elementLocationPathApplies && !IsLocationConfig) { removedSectionOrGroup = true; } } else { // if the location path applies, recurse if there are updates if (sectionUpdates != null) { SectionUpdates sectionUpdatesChild = sectionUpdates.GetSectionUpdatesForGroup(elementName); if (sectionUpdatesChild != null) { recurse = true; recurseGroup = configKey; recurseSectionUpdates = sectionUpdatesChild; } } else if (!elementLocationPathApplies && !IsLocationConfig) { if (_removedSectionGroups != null && _removedSectionGroups.Contains(configKey)) { removedSectionOrGroup = true; } else { recurse = true; recurseGroup = configKey; recurseLocationUpdates = null; recurseSectionUpdates = null; recurseAddNewSections = false; } } } } else { // it is a section - get the update if (sectionUpdates != null) { update = sectionUpdates.GetDefinitionUpdate(configKey); } else if (!elementLocationPathApplies && !IsLocationConfig) { if (_removedSections != null && _removedSections.Contains(configKey)) { removedSectionOrGroup = true; } } } } if (recurse) { #if DBG string startElementName = reader.Name; #endif // flush, and get length of underlying stream object checkpoint = utilWriter.CreateStreamCheckpoint(); // Copy this element node and up to the first subelement xmlUtil.CopyXmlNode(utilWriter); xmlUtil.CopyReaderToNextElement(utilWriter, true); // Recurse bool recurseWroteASection = CopyConfigDefinitionsRecursive( configDefinitionUpdates, xmlUtil, utilWriter, elementLocationPathApplies, recurseLocationUpdates, recurseSectionUpdates, recurseAddNewSections, recurseGroup, linePosition, indent); // Copy the end element xmlUtil.CopyXmlNode(utilWriter); if (recurseWroteASection) { wroteASection = true; } else { // back out the change utilWriter.RestoreStreamCheckpoint(checkpoint); } // Copy up to the next element, or exit this level. xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool skip; if (update == null) { // remove the section from the file if we're in the correct location, // or if the section or group should be removed from all locations skip = elementLocationPathApplies || removedSectionOrGroup; } else { // replace the section if the xml for it has been updated // if it is a configSource, don't write it unless the configSource parameters have changed skip = false; if (update.UpdatedXml != null) { ConfigurationSection configSection = (ConfigurationSection) update.SectionRecord.Result; if ( String.IsNullOrEmpty(configSection.SectionInformation.ConfigSource) || configSection.SectionInformation.ConfigSourceModified) { skip = true; WriteSectionUpdate(utilWriter, update, linePosition, indent, true); wroteASection = true; } } } if (skip) { // // Skip over the existing element, then // copy up to the next element, or exit this level. // xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { // Copy this entire contents of this element and then to the next element, or exit this level. xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); wroteASection = true; } } } } // // Write new section groups // if (sectionUpdates != null && addNewSections && sectionUpdates.HasNewSectionGroups()) { // Add whitespace to align us with the other elements in this group linePosition = parentLinePosition + indent; if (reader.NodeType == XmlNodeType.EndElement) { if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { startingLinePosition = 0; } utilWriter.AppendSpacesToLinePosition(linePosition); bool wroteNewSection = WriteNewConfigDefinitionsRecursive(utilWriter, sectionUpdates, linePosition, indent, true); if (wroteNewSection) { wroteASection = true; } // Restore the whitespace of the end element utilWriter.AppendSpacesToLinePosition(startingLinePosition); } return wroteASection; }
private Hashtable ScanFactories(XmlUtil xmlUtil) { Hashtable factoryList; factoryList = new Hashtable(); if (xmlUtil.Reader.NodeType != XmlNodeType.Element || xmlUtil.Reader.Name != KEYWORD_CONFIGURATION) { string safeFilename = ConfigurationErrorsException.AlwaysSafeFilename(((IConfigErrorInfo)xmlUtil).Filename); throw new ConfigurationErrorsException( SR.GetString(SR.Config_file_doesnt_have_root_configuration, safeFilename), xmlUtil); } // Ignore xmlns attribute while (xmlUtil.Reader.MoveToNextAttribute()) { switch (xmlUtil.Reader.Name) { case KEYWORD_XMLNS: if (xmlUtil.Reader.Value == KEYWORD_CONFIGURATION_NAMESPACE) { _flags[NamespacePresentInFile] = true; _flags[NamespacePresentCurrent] = true; } else { ConfigurationErrorsException ce; ce = new ConfigurationErrorsException( SR.GetString(SR.Config_namespace_invalid, xmlUtil.Reader.Value, KEYWORD_CONFIGURATION_NAMESPACE), xmlUtil); xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Global); } break; default: xmlUtil.AddErrorUnrecognizedAttribute(ExceptionAction.NonSpecific); break; } } // move to first child of <configuration> xmlUtil.StrictReadToNextElement(ExceptionAction.NonSpecific); if (xmlUtil.Reader.Depth == 1 && xmlUtil.Reader.Name == KEYWORD_CONFIGSECTIONS) { xmlUtil.VerifyNoUnrecognizedAttributes(ExceptionAction.NonSpecific); ScanFactoriesRecursive(xmlUtil, string.Empty, factoryList); } return factoryList; }
private bool CopyConfigDeclarationsRecursive(SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { int trueLinePosition; int num3; bool flag = false; XmlTextReader reader = xmlUtil.Reader; int oldIndent = this.UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { trueLinePosition = xmlUtil.TrueLinePosition; num3 = trueLinePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { trueLinePosition = parentLinePosition + oldIndent; if (utilWriter.IsLastLineBlank) { num3 = xmlUtil.TrueLinePosition; } else { num3 = parentLinePosition; } } else { trueLinePosition = parentLinePosition + oldIndent; num3 = 0; } if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string str in movedSectionNames) { DeclarationUpdate declarationUpdate = declarationUpdates.GetDeclarationUpdate(str); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(declarationUpdate.UpdatedXml); utilWriter.AppendNewLine(); flag = true; } utilWriter.AppendSpacesToLinePosition(num3); } } if (reader.NodeType == XmlNodeType.Element) { int depth = reader.Depth; while (reader.Depth == depth) { bool flag2 = false; DeclarationUpdate update2 = null; DeclarationUpdate sectionGroupUpdate = null; SectionUpdates sectionUpdatesForGroup = null; SectionUpdates updates2 = declarationUpdates; string str2 = group; oldIndent = this.UpdateIndent(oldIndent, xmlUtil, utilWriter, parentLinePosition); trueLinePosition = xmlUtil.TrueLinePosition; string name = reader.Name; string attribute = reader.GetAttribute("name"); string configKey = BaseConfigurationRecord.CombineConfigKey(group, attribute); if (name == "sectionGroup") { sectionUpdatesForGroup = declarationUpdates.GetSectionUpdatesForGroup(attribute); if (sectionUpdatesForGroup != null) { sectionGroupUpdate = sectionUpdatesForGroup.GetSectionGroupUpdate(); if (sectionUpdatesForGroup.HasUnretrievedSections()) { flag2 = true; str2 = configKey; updates2 = sectionUpdatesForGroup; } } } else { update2 = declarationUpdates.GetDeclarationUpdate(configKey); } bool flag3 = (sectionGroupUpdate != null) && (sectionGroupUpdate.UpdatedXml != null); if (flag2) { object o = utilWriter.CreateStreamCheckpoint(); string s = null; if (flag3) { utilWriter.Write(sectionGroupUpdate.UpdatedXml); reader.Read(); } else { s = xmlUtil.UpdateStartElement(utilWriter, null, true, trueLinePosition, oldIndent); } if (s == null) { xmlUtil.CopyReaderToNextElement(utilWriter, true); } bool flag4 = this.CopyConfigDeclarationsRecursive(updates2, xmlUtil, utilWriter, str2, trueLinePosition, oldIndent); if (s != null) { utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write(s); utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { xmlUtil.CopyXmlNode(utilWriter); } if (flag4 || flag3) { flag = true; } else { utilWriter.RestoreStreamCheckpoint(o); } xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool flag5; bool flag6 = false; if (update2 == null) { flag5 = true; if (flag3) { flag = true; utilWriter.Write(sectionGroupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); utilWriter.Write("</sectionGroup>"); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(trueLinePosition); } else if (sectionGroupUpdate != null) { flag = true; flag5 = false; flag6 = true; } } else { flag = true; if (update2.UpdatedXml == null) { flag5 = false; } else { flag5 = true; utilWriter.Write(update2.UpdatedXml); } } if (flag5) { xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (flag6) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); continue; } xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } return flag; }
// // Calculate a new indent based on the position of the parent element and the current node. // private int UpdateIndent(int oldIndent, XmlUtil xmlUtil, XmlUtilWriter utilWriter, int parentLinePosition) { int indent = oldIndent; if (xmlUtil.Reader.NodeType == XmlNodeType.Element && utilWriter.IsLastLineBlank) { int childLinePosition = xmlUtil.TrueLinePosition; if (parentLinePosition < childLinePosition && childLinePosition <= parentLinePosition + MAX_INDENT) { indent = childLinePosition - parentLinePosition; } } return indent; }
// Scans the <configSections> section of a configuration file. The function is recursive // to traverse arbitrarily nested config groups. // // <sectionGroup name="foo"> // <sectionGroup name="bar"> // <section name="fooBarSection" type="..." /> // ... // // Note: This function valiates that the factory record has not been // declared before in a parent record. (it does not check // current record, which allows you to update list) // private void ScanFactoriesRecursive(XmlUtil xmlUtil, string parentConfigKey, Hashtable factoryList) { // discard any accumulated local errors xmlUtil.SchemaErrors.ResetLocalErrors(); int depth = xmlUtil.Reader.Depth; xmlUtil.StrictReadToNextElement(ExceptionAction.NonSpecific); while (xmlUtil.Reader.Depth == depth + 1) { bool positionedAtNextElement = false; switch (xmlUtil.Reader.Name) { // // Handle <sectionGroup name="groupName" [type="typename"] /> // case KEYWORD_SECTIONGROUP: { string tagName = null; string typeName = null; int lineNumber = xmlUtil.Reader.LineNumber; while (xmlUtil.Reader.MoveToNextAttribute()) { switch (xmlUtil.Reader.Name) { case KEYWORD_SECTIONGROUP_NAME: tagName = xmlUtil.Reader.Value; VerifySectionName(tagName, xmlUtil, ExceptionAction.Local, false); break; case KEYWORD_SECTIONGROUP_TYPE: xmlUtil.VerifyAndGetNonEmptyStringAttribute(ExceptionAction.Local, out typeName); break; default: xmlUtil.AddErrorUnrecognizedAttribute(ExceptionAction.Local); break; } } xmlUtil.Reader.MoveToElement(); // if on an attribute move back to the element if (!xmlUtil.VerifyRequiredAttribute( tagName, KEYWORD_SECTIONGROUP_NAME, ExceptionAction.NonSpecific)) { // // Without a name, we cannot continue parsing the sections and groups within. // Skip the entire section. // xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(true); xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); } else { string configKey = CombineConfigKey(parentConfigKey, tagName); FactoryRecord factoryRecord = (FactoryRecord) factoryList[configKey]; if (factoryRecord != null) { // Error: duplicate sectionGroup declaration xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined_at_this_level, tagName), xmlUtil), ExceptionAction.Local); } else { FactoryRecord parentFactoryRecord = _parent.FindFactoryRecord(configKey, true); if (parentFactoryRecord != null) { configKey = parentFactoryRecord.ConfigKey; // make sure that an ancestor has not defined a section with the same name as the group if ( !parentFactoryRecord.IsGroup || !parentFactoryRecord.IsEquivalentSectionGroupFactory(Host, typeName)) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, tagName), xmlUtil), ExceptionAction.Local); parentFactoryRecord = null; } } if (parentFactoryRecord != null) { factoryRecord = parentFactoryRecord.CloneSectionGroup(typeName, xmlUtil.Filename, lineNumber); } else { factoryRecord = new FactoryRecord(configKey, parentConfigKey, tagName, typeName, xmlUtil.Filename, lineNumber); } factoryList[configKey] = factoryRecord; } // Add any errors we may have encountered factoryRecord.AddErrors(xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(true)); // continue recursive scan ScanFactoriesRecursive(xmlUtil, configKey, factoryList); } continue; } case KEYWORD_SECTION: { string tagName = null; string typeName = null; ConfigurationAllowDefinition allowDefinition = ConfigurationAllowDefinition.Everywhere; ConfigurationAllowExeDefinition allowExeDefinition = ConfigurationAllowExeDefinition.MachineToApplication; bool allowLocation = true; bool restartOnExternalChanges = true; bool requirePermission = true; bool gotType = false; // parse section attributes int lineNumber = xmlUtil.Reader.LineNumber; while (xmlUtil.Reader.MoveToNextAttribute()) { switch (xmlUtil.Reader.Name) { case KEYWORD_SECTION_NAME: tagName = xmlUtil.Reader.Value; VerifySectionName(tagName, xmlUtil, ExceptionAction.Local, false); break; case KEYWORD_SECTION_TYPE: xmlUtil.VerifyAndGetNonEmptyStringAttribute(ExceptionAction.Local, out typeName); gotType = true; break; case KEYWORD_SECTION_ALLOWLOCATION: xmlUtil.VerifyAndGetBooleanAttribute( ExceptionAction.Local, true, out allowLocation); break; case KEYWORD_SECTION_ALLOWEXEDEFINITION: try { allowExeDefinition = AllowExeDefinitionToEnum(xmlUtil.Reader.Value, xmlUtil); } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } break; case KEYWORD_SECTION_ALLOWDEFINITION: try { allowDefinition = AllowDefinitionToEnum(xmlUtil.Reader.Value, xmlUtil); } catch (ConfigurationException ce) { xmlUtil.SchemaErrors.AddError(ce, ExceptionAction.Local); } break; case KEYWORD_SECTION_RESTARTONEXTERNALCHANGES: xmlUtil.VerifyAndGetBooleanAttribute( ExceptionAction.Local, true, out restartOnExternalChanges); break; case KEYWORD_SECTION_REQUIREPERMISSION: xmlUtil.VerifyAndGetBooleanAttribute( ExceptionAction.Local, true, out requirePermission); break; default: xmlUtil.AddErrorUnrecognizedAttribute(ExceptionAction.Local); break; } } xmlUtil.Reader.MoveToElement(); // if on an attribute move back to the element if (!xmlUtil.VerifyRequiredAttribute( tagName, KEYWORD_SECTION_NAME, ExceptionAction.NonSpecific)) { // // Without a name, we cannot continue to create a factoryRecord. // xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(true); } else { // Verify that the Type attribute was present. // Note that 'typeName' will be null if the attribute was present // but specified as an empty string. if (!gotType) { xmlUtil.AddErrorRequiredAttribute(KEYWORD_SECTION_TYPE, ExceptionAction.Local); } string configKey = CombineConfigKey(parentConfigKey, tagName); FactoryRecord factoryRecord = (FactoryRecord) factoryList[configKey]; if (factoryRecord != null) { // Error: duplicate section declaration xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined_at_this_level, tagName), xmlUtil), ExceptionAction.Local); } else { FactoryRecord parentFactoryRecord = _parent.FindFactoryRecord(configKey, true); if (parentFactoryRecord != null) { configKey = parentFactoryRecord.ConfigKey; // make sure that an ancestor has not defined a section with the same name as the group if (parentFactoryRecord.IsGroup) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, tagName), xmlUtil), ExceptionAction.Local); parentFactoryRecord = null; } else if (!parentFactoryRecord.IsEquivalentSectionFactory(Host, typeName, allowLocation, allowDefinition, allowExeDefinition, restartOnExternalChanges, requirePermission)) { xmlUtil.SchemaErrors.AddError( new ConfigurationErrorsException(SR.GetString(SR.Config_tag_name_already_defined, tagName), xmlUtil), ExceptionAction.Local); parentFactoryRecord = null; } } if (parentFactoryRecord != null) { // Note - Clone will propagate the IsFromTrustedConfigRecord bit, // which is what we want - if this record is a duplicate of an ancestor, // the ancestor may be from a trusted config record. factoryRecord = parentFactoryRecord.CloneSection(xmlUtil.Filename, lineNumber); } else { factoryRecord = new FactoryRecord( configKey, parentConfigKey, tagName, typeName, allowLocation, allowDefinition, allowExeDefinition, restartOnExternalChanges, requirePermission, _flags[IsTrusted], false, // isUndeclared xmlUtil.Filename, lineNumber); } factoryList[configKey] = factoryRecord; } // Add any errors we may have encountered factoryRecord.AddErrors(xmlUtil.SchemaErrors.RetrieveAndResetLocalErrors(true)); } } break; case KEYWORD_REMOVE: { string name = null; int lineNumber = -1; // parse attributes while (xmlUtil.Reader.MoveToNextAttribute()) { if (xmlUtil.Reader.Name != KEYWORD_SECTION_NAME) { xmlUtil.AddErrorUnrecognizedAttribute(ExceptionAction.NonSpecific); } name = xmlUtil.Reader.Value; lineNumber = xmlUtil.Reader.LineNumber; } xmlUtil.Reader.MoveToElement(); if (xmlUtil.VerifyRequiredAttribute( name, KEYWORD_SECTION_NAME, ExceptionAction.NonSpecific)) { VerifySectionName(name, xmlUtil, ExceptionAction.NonSpecific, false); } } break; case KEYWORD_CLEAR: { xmlUtil.VerifyNoUnrecognizedAttributes(ExceptionAction.NonSpecific); } break; default: xmlUtil.AddErrorUnrecognizedElement(ExceptionAction.NonSpecific); xmlUtil.StrictSkipToNextElement(ExceptionAction.NonSpecific); positionedAtNextElement = true; break; } if (!positionedAtNextElement) { // Need to read to next element, and check if an unrecognized child // element is found. xmlUtil.StrictReadToNextElement(ExceptionAction.NonSpecific); // unrecognized children are not allowed in <configSections> if (xmlUtil.Reader.Depth > depth + 1) { xmlUtil.AddErrorUnrecognizedElement(ExceptionAction.NonSpecific); // Lets try to backup to where we are suppose to be while (xmlUtil.Reader.Depth > (depth + 1)) { xmlUtil.ReadToNextElement(); } } } } }
private bool CopyConfigDeclarationsRecursive( SectionUpdates declarationUpdates, XmlUtil xmlUtil, XmlUtilWriter utilWriter, string group, int parentLinePosition, int parentIndent) { bool wroteASection = false; XmlTextReader reader = xmlUtil.Reader; int linePosition; int indent; int startingLinePosition; indent = UpdateIndent(parentIndent, xmlUtil, utilWriter, parentLinePosition); if (reader.NodeType == XmlNodeType.Element) { linePosition = xmlUtil.TrueLinePosition; startingLinePosition = linePosition; } else if (reader.NodeType == XmlNodeType.EndElement) { linePosition = parentLinePosition + indent; if (utilWriter.IsLastLineBlank) { startingLinePosition = xmlUtil.TrueLinePosition; } else { startingLinePosition = parentLinePosition; } } else { linePosition = parentLinePosition + indent; startingLinePosition = 0; } // // Write any new section declarations that apply to this group // if (declarationUpdates != null) { string[] movedSectionNames = declarationUpdates.GetMovedSectionNames(); if (movedSectionNames != null) { if (!utilWriter.IsLastLineBlank) { utilWriter.AppendNewLine(); } foreach (string configKey in movedSectionNames) { DeclarationUpdate sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); // Write the one line section declaration. utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(sectionUpdate.UpdatedXml); utilWriter.AppendNewLine(); wroteASection = true; } // Restore the whitespace we used for the first element, which is either a start or an end element. utilWriter.AppendSpacesToLinePosition(startingLinePosition); } } if (reader.NodeType == XmlNodeType.Element) { // // For each element at this depth, either: // - Write the element verbatim and recurse due to a group hierarchy element. // - Write the element verbatim because it is unchanged // - Write the updated XML for the section. // - Skip it because the section has been removed. // int depth = reader.Depth; while (reader.Depth == depth) { bool recurse = false; DeclarationUpdate sectionUpdate = null; DeclarationUpdate groupUpdate = null; SectionUpdates declarationUpdatesChild = null; SectionUpdates recurseDeclarationUpdates = declarationUpdates; string recurseGroup = group; // update the lineposition and indent for each element indent = UpdateIndent(indent, xmlUtil, utilWriter, parentLinePosition); linePosition = xmlUtil.TrueLinePosition; string directive = reader.Name; string name = reader.GetAttribute(KEYWORD_SECTIONGROUP_NAME); string configKey = CombineConfigKey(group, name); if (directive == KEYWORD_SECTIONGROUP) { // it's a group - get the updates for children declarationUpdatesChild = declarationUpdates.GetSectionUpdatesForGroup(name); if (declarationUpdatesChild != null) { // get the group update groupUpdate = declarationUpdatesChild.GetSectionGroupUpdate(); // recurse if there are more sections to copy if (declarationUpdatesChild.HasUnretrievedSections()) { recurse = true; recurseGroup = configKey; recurseDeclarationUpdates = declarationUpdatesChild; } } } else { // it is a section - get the update Debug.Assert(!IsImplicitSection(configKey), "We should never write out an implicit section"); sectionUpdate = declarationUpdates.GetDeclarationUpdate(configKey); } bool writeGroupUpdate = (groupUpdate != null && groupUpdate.UpdatedXml != null); if (recurse) { #if DBG string startElementName = reader.Name; #endif // create a checkpoint that we can revert to if no children are written object checkpoint = utilWriter.CreateStreamCheckpoint(); string closingElement = null; // Copy this element node and up to the first subelement if (writeGroupUpdate) { // replace the element with the updated xml utilWriter.Write(groupUpdate.UpdatedXml); // skip over the start element reader.Read(); } else { closingElement= xmlUtil.UpdateStartElement(utilWriter, null, true, linePosition, indent); } if (closingElement == null) { // Only if there is a closing element should // we move to it xmlUtil.CopyReaderToNextElement(utilWriter, true); } // Recurse bool recurseWroteASection = CopyConfigDeclarationsRecursive( recurseDeclarationUpdates, xmlUtil, utilWriter, recurseGroup, linePosition, indent); if (closingElement != null) { utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(closingElement); // Since we already got to </configSections> in reader, lets // indent so we can copy the element in the right place utilWriter.AppendSpacesToLinePosition(parentLinePosition); } else { // Copy the end element xmlUtil.CopyXmlNode(utilWriter); } if (recurseWroteASection || writeGroupUpdate) { wroteASection = true; } else { // back out the change utilWriter.RestoreStreamCheckpoint(checkpoint); } // Copy up to the next element, or exit this level. xmlUtil.CopyReaderToNextElement(utilWriter, true); } else { bool skip; bool skipChildElements = false; if (sectionUpdate == null) { skip = true; if (writeGroupUpdate) { // Insert an empty <sectionGroup type="typename" > node, to introduce the type wroteASection = true; utilWriter.Write(groupUpdate.UpdatedXml); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); utilWriter.Write(FORMAT_SECTIONGROUP_ENDELEMENT); utilWriter.AppendNewLine(); utilWriter.AppendSpacesToLinePosition(linePosition); } else if (groupUpdate != null) { // VSWhidbey 522450 // If groupUpdate exists, that means we've decided in GetConfigDeclarationUpdates // that the section group should stay in the file. Debug.Assert(groupUpdate.UpdatedXml == null, "groupUpdate.UpdatedXml == null"); Debug.Assert(!declarationUpdatesChild.HasUnretrievedSections(), "If the group has any unretrieved section, we should have chosen the recursive code path above."); wroteASection = true; skip = false; // We should skip all the child sections. If we indeed need to keep any child // section, we should have chosen the recursive code path above. skipChildElements = true; } } else { wroteASection = true; if (sectionUpdate.UpdatedXml == null) { skip = false; } else { skip = true; // Write the updated XML on a single line utilWriter.Write(sectionUpdate.UpdatedXml); } } if (skip) { // // Skip over the existing element, then // copy up to the next element, or exit this level. // xmlUtil.SkipAndCopyReaderToNextElement(utilWriter, true); } else { if (skipChildElements) { xmlUtil.SkipChildElementsAndCopyOuterXmlToNextElement(utilWriter); } else { // Copy this entire contents of this element and then to the next element, or exit this level. xmlUtil.CopyOuterXmlToNextElement(utilWriter, true); } } } } } return wroteASection; }
AllowExeDefinitionToEnum(string allowExeDefinition, XmlUtil xmlUtil) { switch (allowExeDefinition) { case KEYWORD_SECTION_ALLOWDEFINITION_MACHINEONLY: return ConfigurationAllowExeDefinition.MachineOnly; case KEYWORD_SECTION_ALLOWDEFINITION_MACHINETOAPPLICATION: return ConfigurationAllowExeDefinition.MachineToApplication; case KEYWORD_SECTION_ALLOWEXEDEFINITION_MACHTOROAMING: return ConfigurationAllowExeDefinition.MachineToRoamingUser; case KEYWORD_SECTION_ALLOWEXEDEFINITION_MACHTOLOCAL: return ConfigurationAllowExeDefinition.MachineToLocalUser; default: throw new ConfigurationErrorsException( SR.GetString(SR.Config_section_allow_exe_definition_attribute_invalid), xmlUtil); } }
private void CopyConfigSource(XmlUtilWriter utilWriter, string updatedXml, string configSourceStreamName, byte[] buffer) { // only copy the byte order mark if it exists in the current web.config byte[] preamble; using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, true)) { preamble = ConfigStreamInfo.StreamEncoding.GetPreamble(); } } CheckPreamble(preamble, utilWriter, buffer); using (Stream stream = new MemoryStream(buffer)) { using (XmlUtil xmlUtil = new XmlUtil(stream, configSourceStreamName, false)) { XmlTextReader reader = xmlUtil.Reader; // copy up to the first element reader.WhitespaceHandling = WhitespaceHandling.All; reader.Read(); // determine the indent to use for the element int indent = DEFAULT_INDENT; int linePosition = 1; bool hasElement = xmlUtil.CopyReaderToNextElement(utilWriter, false); if (hasElement) { // find the indent of the first attribute, if any int lineNumber = reader.LineNumber; linePosition = reader.LinePosition - 1; int attributeIndent = 0; while (reader.MoveToNextAttribute()) { if (reader.LineNumber > lineNumber) { attributeIndent = reader.LinePosition - linePosition; break; } } // find the indent of the first sub element, if any int elementIndent = 0; reader.Read(); while (reader.Depth >= 1) { if (reader.NodeType == XmlNodeType.Element) { elementIndent = (reader.LinePosition - 1) - linePosition; break; } reader.Read(); } if (elementIndent > 0) { indent = elementIndent; } else if (attributeIndent > 0) { indent = attributeIndent; } } // Write the config source string formattedXml = XmlUtil.FormatXmlElement(updatedXml, linePosition, indent, true); utilWriter.Write(formattedXml); // Copy remaining contents if (hasElement) { // Skip over the existing element while (reader.Depth > 0) { reader.Read(); } if (reader.IsEmptyElement || reader.NodeType == XmlNodeType.EndElement) { reader.Read(); } // Copy remainder of file while (xmlUtil.CopyXmlNode(utilWriter)) { } } } } }
AllowDefinitionToEnum(string allowDefinition, XmlUtil xmlUtil) { switch (xmlUtil.Reader.Value) { case KEYWORD_SECTION_ALLOWDEFINITION_EVERYWHERE: return ConfigurationAllowDefinition.Everywhere; case KEYWORD_SECTION_ALLOWDEFINITION_MACHINEONLY: return ConfigurationAllowDefinition.MachineOnly; case KEYWORD_SECTION_ALLOWDEFINITION_MACHINETOAPPLICATION: return ConfigurationAllowDefinition.MachineToApplication; case KEYWORD_SECTION_ALLOWDEFINITION_MACHINETOWEBROOT: return ConfigurationAllowDefinition.MachineToWebRoot; default: throw new ConfigurationErrorsException( SR.GetString(SR.Config_section_allow_definition_attribute_invalid), xmlUtil); } }
private void ScanSections(XmlUtil xmlUtil) { ScanSectionsRecursive(xmlUtil, string.Empty, false, null, false, false); }
internal static OverrideMode ParseOverrideModeXmlValue(string value, XmlUtil xmlUtil) => // 'value' is the string representation of OverrideMode enum // Try to parse the string to the enum and generate errors if not possible value switch {