/// <summary> /// Decodes PermissionSetAttribute applied in source to determine if it needs any fixup during codegen. /// </summary> /// <remarks> /// PermissionSetAttribute needs fixup when it contains an assignment to the 'File' property as a single named attribute argument. /// Fixup performed is ported from SecurityAttributes::FixUpPermissionSetAttribute. /// It involves following steps: /// 1) Verifying that the specified file name resolves to a valid path. /// 2) Reading the contents of the file into a byte array. /// 3) Convert each byte in the file content into two bytes containing hexadecimal characters. /// 4) Replacing the 'File = fileName' named argument with 'Hex = hexFileContent' argument, where hexFileContent is the converted output from step 3) above. /// /// Step 1) is performed in this method, i.e. during binding. /// Remaining steps are performed during serialization as we want to avoid retaining the entire file contents throughout the binding/codegen pass. /// See <see cref="StarkPlatform.Compiler.CodeGen.PermissionSetAttributeWithFileReference"/> for remaining fixup steps. /// </remarks> /// <returns>String containing the resolved file path if PermissionSetAttribute needs fixup during codegen, null otherwise.</returns> private string DecodePermissionSetAttribute(CSharpCompilation compilation, AttributeSyntax nodeOpt, DiagnosticBag diagnostics) { Debug.Assert(!this.HasErrors); string resolvedFilePath = null; var namedArgs = this.CommonNamedArguments; if (namedArgs.Length == 1) { var namedArg = namedArgs[0]; NamedTypeSymbol attrType = this.AttributeClass; string filePropName = PermissionSetAttributeWithFileReference.FilePropertyName; string hexPropName = PermissionSetAttributeWithFileReference.HexPropertyName; if (namedArg.Key == filePropName && PermissionSetAttributeTypeHasRequiredProperty(attrType, filePropName)) { // resolve file prop path var fileName = (string)namedArg.Value.Value; var resolver = compilation.Options.XmlReferenceResolver; resolvedFilePath = (resolver != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null; if (resolvedFilePath == null) { // CS7053: Unable to resolve file path '{0}' specified for the named argument '{1}' for PermissionSet attribute Location argSyntaxLocation = nodeOpt != null?nodeOpt.GetNamedArgumentSyntax(filePropName).Location : NoLocation.Singleton; diagnostics.Add(ErrorCode.ERR_PermissionSetAttributeInvalidFile, argSyntaxLocation, fileName ?? "<null>", filePropName); } else if (!PermissionSetAttributeTypeHasRequiredProperty(attrType, hexPropName)) { // PermissionSetAttribute was defined in user source, but doesn't have the required Hex property. // Native compiler still emits the file content as named assignment to 'Hex' property, but this leads to a runtime exception. // We instead skip the fixup and emit the file property. // CONSIDER: We may want to consider taking a breaking change and generating an error here. return(null); } } } return(resolvedFilePath); }