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); } } }
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; sourceFileFullPath = string.IsNullOrEmpty(configFile) ? File : Path.Combine(Path.GetDirectoryName(configFile), 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( SR.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( SR.Format(SR.Config_base_unrecognized_attribute, internalReader.Name), (XmlReader)internalReader); } internalReader.MoveToElement(); base.DeserializeElement(internalReader, serializeCollectionKey); }
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); }
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 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 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; }