/// <summary> /// Convert a task item metadata to bool. Throw an exception if the string is badly formed and can't /// be converted. /// /// If the metadata is not found, then set metadataFound to false and then return false. /// </summary> /// <param name="item">The item that contains the metadata.</param> /// <param name="itemMetadataName">The name of the metadata.</param> /// <returns>The resulting boolean value.</returns> internal static bool TryConvertItemMetadataToBool(ITaskItem item, string itemMetadataName) { string metadataValue = item.GetMetadata(itemMetadataName); if (metadataValue == null || metadataValue.Length == 0) { return(false); } try { return(ConvertStringToBool(metadataValue)); } catch (System.ArgumentException e) { throw Utilities.GetLocalizedArgumentException( e, ErrorString.General_InvalidAttributeMetadata, item.ItemSpec, itemMetadataName, metadataValue, "bool" ); } }
/// <summary> /// Converts a string to a bool. We consider "true/false", "on/off", and /// "yes/no" to be valid boolean representations in the XML. /// </summary> /// <param name="parameterValue">The string to convert.</param> /// <returns>Boolean true or false, corresponding to the string.</returns> internal static bool ConvertStringToBool(string parameterValue) { if (ValidBooleanTrue(parameterValue)) { return(true); } else if (ValidBooleanFalse(parameterValue)) { return(false); } else { // Unsupported boolean representation. throw Utilities.GetLocalizedArgumentException( ErrorString.General_CannotConvertStringToBool, parameterValue); } }
/// <summary> /// vbc.exe only takes the BaseAddress in hexadecimal format. But we allow the caller /// of the task to pass in the BaseAddress in either decimal or hexadecimal format. /// Examples of supported hex formats include "0x10000000" or "&H10000000". /// </summary> internal string GetBaseAddressInHex() { string originalBaseAddress = this.BaseAddress; if (originalBaseAddress != null) { if (originalBaseAddress.Length > 2) { string twoLetterPrefix = originalBaseAddress.Substring(0, 2); if ( (0 == String.Compare(twoLetterPrefix, "0x", StringComparison.OrdinalIgnoreCase)) || (0 == String.Compare(twoLetterPrefix, "&h", StringComparison.OrdinalIgnoreCase)) ) { // The incoming string is already in hex format ... we just need to // remove the 0x or &H from the beginning. return(originalBaseAddress.Substring(2)); } } // The incoming BaseAddress is not in hexadecimal format, so we need to // convert it to hex. try { uint baseAddressDecimal = UInt32.Parse(originalBaseAddress, CultureInfo.InvariantCulture); return(baseAddressDecimal.ToString("X", CultureInfo.InvariantCulture)); } catch (FormatException e) { throw Utilities.GetLocalizedArgumentException(e, ErrorString.Vbc_ParameterHasInvalidValue, "BaseAddress", originalBaseAddress); } } return(null); }
internal static void AddReferencesToCommandLine( CommandLineBuilderExtension commandLine, ITaskItem[]?references, bool isInteractive = false) { // If there were no references passed in, don't add any /reference: switches // on the command-line. if (references == null) { return; } // Loop through all the references passed in. We'll be adding separate // /reference: switches for each reference, and in some cases even multiple // /reference: switches per reference. foreach (ITaskItem reference in references) { // See if there was an "Alias" attribute on the reference. string aliasString = reference.GetMetadata("Aliases"); string switchName = "/reference:"; if (!isInteractive) { bool embed = Utilities.TryConvertItemMetadataToBool(reference, "EmbedInteropTypes"); if (embed) { switchName = "/link:"; } } if (string.IsNullOrEmpty(aliasString)) { // If there was no "Alias" attribute, just add this as a global reference. commandLine.AppendSwitchIfNotNull(switchName, reference.ItemSpec); } else { // If there was an "Alias" attribute, it contains a comma-separated list // of aliases to use for this reference. For each one of those aliases, // we're going to add a separate /reference: switch to the csc.exe // command-line string[] aliases = aliasString.Split(','); foreach (string alias in aliases) { // Trim whitespace. string trimmedAlias = alias.Trim(); if (alias.Length == 0) { continue; } // The alias should be a valid C# identifier. Therefore it cannot // contain comma, space, semicolon, or double-quote. Let's check for // the existence of those characters right here, and bail immediately // if any are present. There are a whole bunch of other characters // that are not allowed in a C# identifier, but we'll just let csc.exe // error out on those. The ones we're checking for here are the ones // that could seriously screw up the command-line parsing or could // allow parameter injection. if (trimmedAlias.IndexOfAny(new char[] { ',', ' ', ';', '"' }) != -1) { throw Utilities.GetLocalizedArgumentException( ErrorString.Csc_AssemblyAliasContainsIllegalCharacters, reference.ItemSpec, trimmedAlias); } // The alias called "global" is special. It means that we don't // give it an alias on the command-line. if (string.Compare("global", trimmedAlias, StringComparison.OrdinalIgnoreCase) == 0) { commandLine.AppendSwitchIfNotNull(switchName, reference.ItemSpec); } else { // We have a valid (and explicit) alias for this reference. Add // it to the command-line using the syntax: // /reference:Goo=System.Xml.dll commandLine.AppendSwitchAliased(switchName, trimmedAlias, reference.ItemSpec); } } } } }