예제 #1
0
        public void ProcessGenericArgumentDataFlow(GenericParameter genericParameter, TypeReference genericArgument)
        {
            var genericParameterValue = _annotations.GetGenericParameterValue(genericParameter);

            Debug.Assert(genericParameterValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None);

            MultiValue genericArgumentValue = GetTypeValueNodeFromGenericArgument(genericArgument);

            var diagnosticContext = new DiagnosticContext(_origin, ShouldEnableReflectionPatternReporting(_origin.Provider), _context);

            RequireDynamicallyAccessedMembers(diagnosticContext, genericArgumentValue, genericParameterValue);
        }
        public ViewResult Index([FromQuery] string name = "SinjulMSBH")
        {
            Logger.LogInformation("Hello, {Name} .. !!!!", name);

            DiagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));

            IEnumerable <ILoggerProvider> providers = LoggerProvider.Providers;

            ShoppingCartService.AddItem("SinjulMSBH", 130);

            return(View());
        }
        public ViewResult Index([FromQuery] string name = "SinjulMSBH")
        {
            Logger.LogInformation("Hello, {Name} .. !!!!", name);

            DiagnosticContext.Set("IndexCallCount", Interlocked.Increment(ref _callCount));

            IEnumerable <ILoggerProvider> providers = new LoggerProviderCollection().Providers;

            Log.ForContext <ShoppingCartService>().Information("Adding {ItemId} x {Quantity} to cart", 13, 85);

            return(View());
        }
        public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, MarkStep markStep, LinkContext context)
        {
            bool diagnosticsEnabled = !context.Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode(Origin.Provider);
            var  diagnosticContext  = new DiagnosticContext(Origin, diagnosticsEnabled, context);

            ReflectionMethodBodyScanner.HandleCall(Operation, CalledMethod, Instance, Arguments,
                                                   diagnosticContext,
                                                   reflectionMarker,
                                                   context,
                                                   markStep,
                                                   out MultiValue _);
        }
예제 #5
0
        private static bool IsWellKnownModule(ISourceFile sourceFile, DiagnosticContext context)
        {
            if (context.Workspace == null)
            {
                // This rule is applicable only when the workspace is used.
                return(true);
            }

            var module = context.Workspace.GetModuleBySpecFileName(sourceFile.GetAbsolutePath(context.PathTable));

            return(WellKnownTransformerWrappers.Contains(module.Descriptor.Name));
        }
예제 #6
0
        private void ValidateTypeNode(INode node, DiagnosticContext context)
        {
            if (IsWellKnownModule(node.GetSourceFile(), context))
            {
                return;
            }

            var propertyAccess = node.Cast <ITypeReferenceNode>();
            var identifier     = propertyAccess.TypeName.As <IQualifiedName>()?.Left?.As <IIdentifier>();

            CheckIdentifier(node, context, identifier);
        }
예제 #7
0
        private void ValidateNode(INode node, DiagnosticContext context)
        {
            if (IsWellKnownModule(node.GetSourceFile(), context))
            {
                return;
            }

            var propertyAccess = node.Cast <IPropertyAccessExpression>();
            var identifier     = propertyAccess.Expression.As <IIdentifier>();

            CheckIdentifier(node, context, identifier);
        }
        public RequestLoggingMiddleware(RequestDelegate next, DiagnosticContext diagnosticContext, RequestLoggingOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            _next = next ?? throw new ArgumentNullException(nameof(next));
            _diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));

            _getLevel        = options.GetLevel;
            _messageTemplate = new MessageTemplateParser().Parse(options.MessageTemplate);
        }
예제 #9
0
        private void AnalyzeVariableStatement(INode node, DiagnosticContext context)
        {
            var variableStatement = node.Cast <IVariableStatement>();

            // Don't need to check whether a statement was declared at the namespace level,
            // because we'll skip non-exported variable declarations.
            // And export keyword is applicable only for top level variables!

            // We only care about exported statements
            if ((variableStatement.Flags & NodeFlags.Export) == 0)
            {
                return;
            }

            var declarations = variableStatement.DeclarationList.Declarations;

            foreach (var declaration in declarations)
            {
                // 'any' is not allowed for top level variables
                if (declaration.Type?.Kind == TypeScript.Net.Types.SyntaxKind.AnyKeyword ||
                    NodeWalker.ForEachChildRecursively <Bool>(declaration.Type, n => n?.Kind == TypeScript.Net.Types.SyntaxKind.AnyKeyword))
                {
                    context.Logger.ReportNotAllowedTypeAnyOnTopLevelDeclaration(
                        context.LoggingContext,
                        declaration.LocationForLogging(context.SourceFile),
                        declaration.Name.GetFormattedText(),
                        Name);
                }

                // If the variable has an initializer (there is another lint rule that enforces variable initialization,
                // but that can't be assumed here) that is an object literal, then there should be a non-any type annotation
                if (declaration.Initializer?.Kind == TypeScript.Net.Types.SyntaxKind.ObjectLiteralExpression)
                {
                    if (declaration.Type == null)
                    {
                        context.Logger.ReportMissingTypeAnnotationOnTopLevelDeclaration(
                            context.LoggingContext,
                            declaration.LocationForLogging(context.SourceFile),
                            declaration.Name.GetFormattedText(),
                            Name);
                    }
                    else if (declaration.Type.Kind == TypeScript.Net.Types.SyntaxKind.AnyKeyword)
                    {
                        context.Logger.ReportNotAllowedTypeAnyOnTopLevelDeclaration(
                            context.LoggingContext,
                            declaration.LocationForLogging(context.SourceFile),
                            declaration.Name.GetFormattedText(),
                            Name);
                    }
                }
            }
        }
예제 #10
0
        private static void CheckQualifierTypeNameIsNotUsed(INode node, DiagnosticContext context)
        {
            var interfaceDeclaration = node.As <IInterfaceDeclaration>();
            var name = interfaceDeclaration != null ? interfaceDeclaration.Name.Text : node.As <ITypeAliasDeclaration>().Name.Text;

            if (name == Names.BaseQualifierType)
            {
                context.Logger.ReportQualifierTypeNameIsReserved(
                    context.LoggingContext,
                    node.LocationForLogging(context.SourceFile),
                    Names.BaseQualifierType);
            }
        }
예제 #11
0
        private static void ValidateStatement(INode node, DiagnosticContext context)
        {
            if (!node.IsTopLevelOrNamespaceLevelDeclaration())
            {
                // Doing nothing if the declaration is not a namespace or top level declaration.
                return;
            }

            context.Logger.ReportOnlyTypeAndFunctionDeclarationsAndConstBindingsAreAllowedTopLevel(
                context.LoggingContext,
                node.LocationForLogging(context.SourceFile),
                node.Kind.ToString());
        }
예제 #12
0
        private static void CheckImportOrExportClause(INode node, DiagnosticContext context)
        {
            IExpression specifier         = node.GetModuleSpecifier();
            var         literalExpression = specifier?.As <IStringLiteral>();

            // There is a lint rule that enforces this, but it might have not run yet
            if (literalExpression == null)
            {
                return;
            }

            CheckImportedModule(node, literalExpression.Text, context);
        }
예제 #13
0
 public void ProcessAttributeDataflow(MethodDefinition method, IList <CustomAttributeArgument> arguments)
 {
     for (int i = 0; i < method.Parameters.Count; i++)
     {
         var parameterValue = _annotations.GetMethodParameterValue(method, i);
         if (parameterValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None)
         {
             MultiValue value             = GetValueNodeForCustomAttributeArgument(arguments[i]);
             var        diagnosticContext = new DiagnosticContext(_origin, diagnosticsEnabled: true, _context);
             RequireDynamicallyAccessedMembers(diagnosticContext, value, parameterValue);
         }
     }
 }
예제 #14
0
        private static void CheckImportedModule(INode node, string moduleName, DiagnosticContext context)
        {
            var module = context.Workspace.GetModuleBySpecFileName(context.SourceFile.GetAbsolutePath(context.PathTable));

            if (module.Definition.ResolutionSemantics == NameResolutionSemantics.ImplicitProjectReferences && module.Descriptor.Name == moduleName)
            {
                // The rule is enabled only for V2 modules. For V1 modules it still kind of make sense to import itself, instead of importing different files.
                context.Logger.ReportModuleShouldNotImportItself(
                    context.LoggingContext,
                    node.LocationForLogging(context.SourceFile),
                    moduleName);
            }
        }
예제 #15
0
        private void EnforceFunctionDeclareReturnType(INode node, DiagnosticContext context)
        {
            var functionDeclaration = node.As <IFunctionDeclaration>();

            if (functionDeclaration.Type == null || functionDeclaration.Type.Kind == TypeScript.Net.Types.SyntaxKind.AnyKeyword)
            {
                context.Logger.ReportFunctionShouldDeclareReturnType(
                    context.LoggingContext,
                    functionDeclaration.LocationForLogging(context.SourceFile),
                    functionDeclaration.Name.GetFormattedText(),
                    Name);
            }
        }
예제 #16
0
        private static void CheckImportFrom(INode node, DiagnosticContext context)
        {
            var callExpression = node.Cast <ICallExpression>();

            if (!callExpression.IsImportFrom())
            {
                return;
            }

            var moduleName = callExpression.Arguments[0].Cast <IStringLiteral>().Text;

            CheckImportedModule(node, moduleName, context);
        }
        public void MarkAndProduceDiagnostics(ReflectionMarker reflectionMarker, Logger logger)
        {
            var diagnosticContext = new DiagnosticContext(
                Origin,
                logger.ShouldSuppressAnalysisWarningsForRequires(Origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute),
                logger.ShouldSuppressAnalysisWarningsForRequires(Origin.MemberDefinition, DiagnosticUtilities.RequiresDynamicCodeAttribute),
                logger.ShouldSuppressAnalysisWarningsForRequires(Origin.MemberDefinition, DiagnosticUtilities.RequiresAssemblyFilesAttribute),
                logger);

            ReflectionMethodBodyScanner.HandleCall(MethodBody, CalledMethod, Operation, Offset, Instance, Arguments,
                                                   diagnosticContext,
                                                   reflectionMarker,
                                                   out MultiValue _);
        }
예제 #18
0
        private void CheckIdentifier(INode node, DiagnosticContext context, IIdentifier identifier)
        {
            if (identifier == null || identifier.Text != AmbientNamespaceName)
            {
                return;
            }

            var symbol = context.SemanticModel.TypeChecker.GetSymbolAtLocation(identifier);

            if (IsPrelude(symbol?.DeclarationList.FirstOrDefault()?.GetSourceFile(), context))
            {
                context.Logger.ReportAmbientTransformerIsDisallowed(context.LoggingContext, node.LocationForLogging(context.SourceFile), Name);
            }
        }
예제 #19
0
        /// <summary>
        /// Register serilog
        /// </summary>
        /// <param name="services">service container</param>
        /// <param name="logPath">Path to file savelog</param>
        public static void AddSerilog(this IServiceCollection services, string logPath = "logs\\systemlog.txt")
        {
            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.Debug()
                         .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                         .Enrich.FromLogContext()
                         .WriteTo.File(logPath, rollingInterval: RollingInterval.Day, encoding: Encoding.UTF8, rollOnFileSizeLimit: true)
                         .CreateLogger();
            var diagnosticContext = new DiagnosticContext(Log.Logger);

            services.AddSingleton(diagnosticContext);
            services.AddSingleton(Log.Logger);
            services.AddSingleton <ILoggerProvider, SerilogLoggerProvider>();
        }
예제 #20
0
        public void ProcessAttributeDataflow(FieldDefinition field, CustomAttributeArgument value)
        {
            MultiValue valueNode = GetValueNodeForCustomAttributeArgument(value);

            foreach (var fieldValueCandidate in GetFieldValue(field))
            {
                if (fieldValueCandidate is not ValueWithDynamicallyAccessedMembers fieldValue)
                {
                    continue;
                }

                var diagnosticContext = new DiagnosticContext(_origin, diagnosticsEnabled: true, _context);
                RequireDynamicallyAccessedMembers(diagnosticContext, valueNode, fieldValue);
            }
        }
        private static void EnforceFunctionDeclareReturnType(INode node, DiagnosticContext context)
        {
            var functionDeclaration = node.As <IFunctionDeclaration>();

            if (functionDeclaration.IsExported())
            {
                if (functionDeclaration?.IsReturnTypeMutable(context.SemanticModel) == true ||
                    functionDeclaration?.HasMutableParameterType(context.SemanticModel) == true)
                {
                    context.Logger.ReportNoMutableDeclarationsAtExposedFunctions(
                        context.LoggingContext,
                        functionDeclaration.LocationForLogging(context.SourceFile));
                }
            }
        }
예제 #22
0
        public void ScanAndProcessReturnValue(MethodBody methodBody)
        {
            Scan(methodBody);

            if (!methodBody.Method.ReturnsVoid())
            {
                var method            = methodBody.Method;
                var methodReturnValue = _annotations.GetMethodReturnValue(method);
                if (methodReturnValue.DynamicallyAccessedMemberTypes != 0)
                {
                    var diagnosticContext = new DiagnosticContext(_origin, ShouldEnableReflectionPatternReporting(_origin.Provider), _context);
                    RequireDynamicallyAccessedMembers(diagnosticContext, ReturnValue, methodReturnValue);
                }
            }
        }
예제 #23
0
        private void ValidateNode(INode node, DiagnosticContext context)
        {
            var callExpression = node.Cast <ICallExpression>();

            // We're interested only in invocation expression that're using named identifier.
            var callee = callExpression.Expression.As <IIdentifier>();

            if (callee != null)
            {
                if (IsGlobFunction(callee.Text))
                {
                    context.Logger.ReportGlobFunctionsIsNotAllowed(context.LoggingContext, node.LocationForLogging(context.SourceFile), Name);
                }
            }
        }
예제 #24
0
        public void ExistingPropertiesCanBeUpdated()
        {
            var dc = new DiagnosticContext(Some.Logger());

            var collector = dc.BeginCollection();

            dc.Set("name", 10);
            dc.Set("name", 20);

            Assert.True(collector.TryComplete(out var properties));
            var prop   = Assert.Single(properties);
            var scalar = Assert.IsType <ScalarValue>(prop.Value);

            Assert.Equal(20, scalar.Value);
        }
예제 #25
0
        private static void CheckCallToEvalIsNotAllowed(INode node, DiagnosticContext context)
        {
            var expression = node.Cast <ICallExpression>();

            if (expression.Expression.Kind == TypeScript.Net.Types.SyntaxKind.Identifier)
            {
                var expressionName = expression.Expression.Cast <IIdentifier>();
                if (expressionName.Text == "eval")
                {
                    context.Logger.ReportEvalIsNotAllowed(
                        context.LoggingContext,
                        expression.LocationForLogging(context.SourceFile));
                }
            }
        }
        private static void CheckExportSpecifierIsNotRootNamespace(INode node, DiagnosticContext context)
        {
            var export = node.Cast <IExportDeclaration>();

            if (export.ExportClause != null)
            {
                // export {a as $}
                foreach (var namedExport in export.ExportClause.Elements)
                {
                    if (ReportIfNameIsRootNamespace(namedExport.Name.Text, namedExport, context))
                    {
                        return;
                    }
                }
            }
        }
        static IEnumerable <Diagnostic> GetDynamicallyAccessedMembersDiagnostics(SingleValue sourceValue, SingleValue targetValue, Location location)
        {
            // The target should always be an annotated value, but the visitor design currently prevents
            // declaring this in the type system.
            if (targetValue is not ValueWithDynamicallyAccessedMembers targetWithDynamicallyAccessedMembers)
            {
                throw new NotImplementedException();
            }

            var diagnosticContext = new DiagnosticContext(location);
            var requireDynamicallyAccessedMembersAction = new RequireDynamicallyAccessedMembersAction(diagnosticContext, new ReflectionAccessAnalyzer());

            requireDynamicallyAccessedMembersAction.Invoke(sourceValue, targetWithDynamicallyAccessedMembers);

            return(diagnosticContext.Diagnostics);
        }
예제 #28
0
        private void DiscoverUrl()
        {
            string text = null;

            if (this.IsTraceEnabled(TraceType.DebugTrace))
            {
                this.Tracer.TraceDebug <string>(0L, "Will try to discover the URL for EWS with the Backendlocator for  mailbox {0}", this.connectionManager.GetPrincipalInfoForTracing());
            }
            Exception innerException = null;

            try
            {
                Uri backEndWebServicesUrl = this.connectionManager.GetBackEndWebServicesUrl();
                if (backEndWebServicesUrl != null)
                {
                    if (this.IsTraceEnabled(TraceType.DebugTrace))
                    {
                        this.Tracer.TraceDebug <string, string>(0L, "Found Uri from the back end locator.{0}, {1}", backEndWebServicesUrl.ToString(), this.connectionManager.GetPrincipalInfoForTracing());
                    }
                    text = backEndWebServicesUrl.ToString();
                }
                else if (this.IsTraceEnabled(TraceType.ErrorTrace))
                {
                    this.Tracer.TraceError <string>(0L, "Unable to discover internal URL for EWS for mailbox {0}. BackEndLocator call returned null", this.connectionManager.GetPrincipalInfoForTracing());
                }
            }
            catch (LocalizedException ex)
            {
                DiagnosticContext.TraceLocation((LID)51388U);
                innerException = ex;
                if (this.IsTraceEnabled(TraceType.ErrorTrace))
                {
                    this.Tracer.TraceError <string, LocalizedException>(0L, "Unable to discover internal URL for EWS for mailbox {0} due to exception {1}", this.connectionManager.GetPrincipalInfoForTracing(), ex);
                }
            }
            if (string.IsNullOrEmpty(text))
            {
                DiagnosticContext.TraceLocation((LID)45244U);
                throw new FailedToFindEwsEndpointException(this.connectionManager.GetPrincipalInfoForTracing(), innerException);
            }
            this.binding.Url         = text;
            this.lastUrlDiscoverTime = ExDateTime.UtcNow;
            if (this.IsTraceEnabled(TraceType.DebugTrace))
            {
                this.Tracer.TraceDebug(0L, "Refreshed service binding (url and adminauditlogs folder), new url: " + text);
            }
        }
예제 #29
0
        public override MultiValue HandleMethodCall(IMethodSymbol calledMethod, MultiValue instance, ImmutableArray <MultiValue> arguments, IOperation operation)
        {
            // For .ctors:
            // - The instance value is empty (TopValue) and that's a bit wrong.
            //   Technically this is an instance call and the instance is some valid value, we just don't know which
            //   but for example it does have a static type. For now this is OK since we don't need the information
            //   for anything yet.
            // - The return here is also technically problematic, the return value is an instance of a known type,
            //   but currently we return empty (since the .ctor is declared as returning void).
            //   Especially with DAM on type, this can lead to incorrectly analyzed code (as in unknown type which leads
            //   to noise). Linker has the same problem currently: https://github.com/dotnet/linker/issues/1952

            var diagnosticContext = DiagnosticContext.CreateDisabled();
            var handleCallAction  = new HandleCallAction(diagnosticContext, Context.OwningSymbol, operation);

            if (!handleCallAction.Invoke(new MethodProxy(calledMethod), instance, arguments, out MultiValue methodReturnValue))
            {
                if (!calledMethod.ReturnsVoid && calledMethod.ReturnType.IsTypeInterestingForDataflow())
                {
                    methodReturnValue = new MethodReturnValue(calledMethod);
                }
                else
                {
                    methodReturnValue = TopValue;
                }
            }

            TrimAnalysisPatterns.Add(new TrimAnalysisMethodCallPattern(
                                         calledMethod,
                                         instance,
                                         arguments,
                                         operation,
                                         Context.OwningSymbol));

            foreach (var argument in arguments)
            {
                foreach (var argumentValue in argument)
                {
                    if (argumentValue is ArrayValue arrayValue)
                    {
                        arrayValue.IndexValues.Clear();
                    }
                }
            }

            return(methodReturnValue);
        }
예제 #30
0
        public static string GetDiagnosticContextFromThread()
        {
            if (!DiagnosticContext.HasData)
            {
                return(string.Empty);
            }
            byte[] array  = DiagnosticContext.PackInfo();
            byte[] array2 = new byte[array.Length + 6];
            int    num    = 0;

            ExBitConverter.Write(0, array2, num);
            num += 2;
            ExBitConverter.Write((uint)array.Length, array2, num);
            num += 4;
            Array.Copy(array, 0, array2, num, array.Length);
            return(string.Format("[diag::{0}]", Convert.ToBase64String(array2)));
        }
예제 #31
0
			/// <summary>
			/// Initializes a new instance of the <see cref="DiagnosticContext" /> class
			/// with the specified message and parent context.
			/// </summary>
			/// <param name="message">The message for this context.</param>
			/// <param name="parent">The parent context in the chain.</param>
			internal DiagnosticContext(string message, DiagnosticContext parent) 
			{
				m_message = message;
				if (parent != null) 
				{
					m_fullMessage = parent.FullMessage + ' ' + message;
				} 
				else 
				{
					m_fullMessage = message;
				}
			}