1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.IO;
6 
7 namespace System.CodeDom.Compiler
8 {
9     // This is an internal helper class which walks the tree for the ValidateIdentifiers API in the CodeGenerator. For the most part the generator code has been copied and
10     // turned into validation code. This code will only validate identifiers and types to check that they are ok in a language
11     // independent manner. By default, this will not be turned on. This gives clients of codedom a mechanism to
12     // protect themselves against certain types of code injection attacks (using identifier and type names).
13     // You can pass in any node in the tree that is a subclass of CodeObject.
14     internal sealed class CodeValidator
15     {
16         private static readonly char[] s_newLineChars = new char[] { '\r', '\n', '\u2028', '\u2029', '\u0085' };
17         private CodeTypeDeclaration _currentClass;
18 
ValidateIdentifiers(CodeObject e)19         internal void ValidateIdentifiers(CodeObject e)
20         {
21             if (e is CodeCompileUnit)
22             {
23                 ValidateCodeCompileUnit((CodeCompileUnit)e);
24             }
25             else if (e is CodeComment)
26             {
27                 ValidateComment((CodeComment)e);
28             }
29             else if (e is CodeExpression)
30             {
31                 ValidateExpression((CodeExpression)e);
32             }
33             else if (e is CodeNamespace)
34             {
35                 ValidateNamespace((CodeNamespace)e);
36             }
37             else if (e is CodeNamespaceImport)
38             {
39                 ValidateNamespaceImport((CodeNamespaceImport)e);
40             }
41             else if (e is CodeStatement)
42             {
43                 ValidateStatement((CodeStatement)e);
44             }
45             else if (e is CodeTypeMember)
46             {
47                 ValidateTypeMember((CodeTypeMember)e);
48             }
49             else if (e is CodeTypeReference)
50             {
51                 ValidateTypeReference((CodeTypeReference)e);
52             }
53             else if (e is CodeDirective)
54             {
55                 ValidateCodeDirective((CodeDirective)e);
56             }
57             else
58             {
59                 throw new ArgumentException(SR.Format(SR.InvalidElementType, e.GetType().FullName), nameof(e));
60             }
61         }
62 
ValidateTypeMember(CodeTypeMember e)63         private void ValidateTypeMember(CodeTypeMember e)
64         {
65             ValidateCommentStatements(e.Comments);
66             ValidateCodeDirectives(e.StartDirectives);
67             ValidateCodeDirectives(e.EndDirectives);
68             if (e.LinePragma != null) ValidateLinePragmaStart(e.LinePragma);
69 
70             if (e is CodeMemberEvent)
71             {
72                 ValidateEvent((CodeMemberEvent)e);
73             }
74             else if (e is CodeMemberField)
75             {
76                 ValidateField((CodeMemberField)e);
77             }
78             else if (e is CodeMemberMethod)
79             {
80                 ValidateMemberMethod((CodeMemberMethod)e);
81             }
82             else if (e is CodeMemberProperty)
83             {
84                 ValidateProperty((CodeMemberProperty)e);
85             }
86             else if (e is CodeSnippetTypeMember)
87             {
88                 ValidateSnippetMember((CodeSnippetTypeMember)e);
89             }
90             else if (e is CodeTypeDeclaration)
91             {
92                 ValidateTypeDeclaration((CodeTypeDeclaration)e);
93             }
94             else
95             {
96                 throw new ArgumentException(SR.Format(SR.InvalidElementType, e.GetType().FullName), nameof(e));
97             }
98         }
99 
ValidateCodeCompileUnit(CodeCompileUnit e)100         private void ValidateCodeCompileUnit(CodeCompileUnit e)
101         {
102             ValidateCodeDirectives(e.StartDirectives);
103             ValidateCodeDirectives(e.EndDirectives);
104             if (e is CodeSnippetCompileUnit)
105             {
106                 ValidateSnippetCompileUnit((CodeSnippetCompileUnit)e);
107             }
108             else
109             {
110                 ValidateCompileUnitStart(e);
111                 ValidateNamespaces(e);
112                 ValidateCompileUnitEnd(e);
113             }
114         }
115 
ValidateSnippetCompileUnit(CodeSnippetCompileUnit e)116         private void ValidateSnippetCompileUnit(CodeSnippetCompileUnit e)
117         {
118             if (e.LinePragma != null) ValidateLinePragmaStart(e.LinePragma);
119         }
120 
ValidateCompileUnitStart(CodeCompileUnit e)121         private void ValidateCompileUnitStart(CodeCompileUnit e)
122         {
123             if (e.AssemblyCustomAttributes.Count > 0)
124             {
125                 ValidateAttributes(e.AssemblyCustomAttributes);
126             }
127         }
128 
ValidateCompileUnitEnd(CodeCompileUnit e)129         private void ValidateCompileUnitEnd(CodeCompileUnit e)
130         {
131         }
132 
ValidateNamespaces(CodeCompileUnit e)133         private void ValidateNamespaces(CodeCompileUnit e)
134         {
135             foreach (CodeNamespace n in e.Namespaces)
136             {
137                 ValidateNamespace(n);
138             }
139         }
140 
ValidateNamespace(CodeNamespace e)141         private void ValidateNamespace(CodeNamespace e)
142         {
143             ValidateCommentStatements(e.Comments);
144             ValidateNamespaceStart(e);
145             ValidateNamespaceImports(e);
146             ValidateTypes(e);
147         }
148 
149 
ValidateNamespaceStart(CodeNamespace e)150         private static void ValidateNamespaceStart(CodeNamespace e)
151         {
152             if (!string.IsNullOrEmpty(e.Name))
153             {
154                 ValidateTypeName(e, nameof(e.Name), e.Name);
155             }
156         }
157 
ValidateNamespaceImports(CodeNamespace e)158         private void ValidateNamespaceImports(CodeNamespace e)
159         {
160             foreach (CodeNamespaceImport imp in e.Imports)
161             {
162                 if (imp.LinePragma != null) ValidateLinePragmaStart(imp.LinePragma);
163                 ValidateNamespaceImport(imp);
164             }
165         }
166 
ValidateNamespaceImport(CodeNamespaceImport e)167         private static void ValidateNamespaceImport(CodeNamespaceImport e)
168         {
169             ValidateTypeName(e, nameof(e.Namespace), e.Namespace);
170         }
171 
ValidateAttributes(CodeAttributeDeclarationCollection attributes)172         private void ValidateAttributes(CodeAttributeDeclarationCollection attributes)
173         {
174             if (attributes.Count == 0) return;
175             foreach (CodeAttributeDeclaration current in attributes)
176             {
177                 ValidateTypeName(current, nameof(current.Name), current.Name);
178                 ValidateTypeReference(current.AttributeType);
179 
180                 foreach (CodeAttributeArgument arg in current.Arguments)
181                 {
182                     ValidateAttributeArgument(arg);
183                 }
184             }
185         }
186 
ValidateAttributeArgument(CodeAttributeArgument arg)187         private void ValidateAttributeArgument(CodeAttributeArgument arg)
188         {
189             if (!string.IsNullOrEmpty(arg.Name))
190             {
191                 ValidateIdentifier(arg, nameof(arg.Name), arg.Name);
192             }
193             ValidateExpression(arg.Value);
194         }
195 
ValidateTypes(CodeNamespace e)196         private void ValidateTypes(CodeNamespace e)
197         {
198             foreach (CodeTypeDeclaration type in e.Types)
199             {
200                 ValidateTypeDeclaration(type);
201             }
202         }
203 
ValidateTypeDeclaration(CodeTypeDeclaration e)204         private void ValidateTypeDeclaration(CodeTypeDeclaration e)
205         {
206             // This function can be called recursively and will modify the global variable currentClass
207             // We will save currentClass to a local, modify it to do whatever we want and restore it back when we exit so that it is re-entrant.
208             CodeTypeDeclaration savedClass = _currentClass;
209             _currentClass = e;
210 
211             ValidateTypeStart(e);
212             ValidateTypeParameters(e.TypeParameters);
213             ValidateTypeMembers(e); // Recursive call can come from here.
214             ValidateTypeReferences(e.BaseTypes);
215 
216             _currentClass = savedClass;
217         }
218 
ValidateTypeMembers(CodeTypeDeclaration e)219         private void ValidateTypeMembers(CodeTypeDeclaration e)
220         {
221             foreach (CodeTypeMember currentMember in e.Members)
222             {
223                 ValidateTypeMember(currentMember);
224             }
225         }
226 
ValidateTypeParameters(CodeTypeParameterCollection parameters)227         private void ValidateTypeParameters(CodeTypeParameterCollection parameters)
228         {
229             for (int i = 0; i < parameters.Count; i++)
230             {
231                 ValidateTypeParameter(parameters[i]);
232             }
233         }
234 
ValidateTypeParameter(CodeTypeParameter e)235         private void ValidateTypeParameter(CodeTypeParameter e)
236         {
237             ValidateIdentifier(e, nameof(e.Name), e.Name);
238             ValidateTypeReferences(e.Constraints);
239             ValidateAttributes(e.CustomAttributes);
240         }
241 
ValidateField(CodeMemberField e)242         private void ValidateField(CodeMemberField e)
243         {
244             if (e.CustomAttributes.Count > 0)
245             {
246                 ValidateAttributes(e.CustomAttributes);
247             }
248 
249             ValidateIdentifier(e, nameof(e.Name), e.Name);
250             if (!IsCurrentEnum)
251             {
252                 ValidateTypeReference(e.Type);
253             }
254 
255             if (e.InitExpression != null)
256             {
257                 ValidateExpression(e.InitExpression);
258             }
259         }
260 
ValidateConstructor(CodeConstructor e)261         private void ValidateConstructor(CodeConstructor e)
262         {
263             if (e.CustomAttributes.Count > 0)
264             {
265                 ValidateAttributes(e.CustomAttributes);
266             }
267 
268             ValidateParameters(e.Parameters);
269 
270             CodeExpressionCollection baseArgs = e.BaseConstructorArgs;
271             CodeExpressionCollection thisArgs = e.ChainedConstructorArgs;
272 
273             if (baseArgs.Count > 0)
274             {
275                 ValidateExpressionList(baseArgs);
276             }
277 
278             if (thisArgs.Count > 0)
279             {
280                 ValidateExpressionList(thisArgs);
281             }
282 
283             ValidateStatements(e.Statements);
284         }
285 
ValidateProperty(CodeMemberProperty e)286         private void ValidateProperty(CodeMemberProperty e)
287         {
288             if (e.CustomAttributes.Count > 0)
289             {
290                 ValidateAttributes(e.CustomAttributes);
291             }
292 
293             ValidateTypeReference(e.Type);
294             ValidateTypeReferences(e.ImplementationTypes);
295 
296             if (e.PrivateImplementationType != null && !IsCurrentInterface)
297             {
298                 ValidateTypeReference(e.PrivateImplementationType);
299             }
300 
301             if (e.Parameters.Count > 0 && string.Equals(e.Name, "Item", StringComparison.OrdinalIgnoreCase))
302             {
303                 ValidateParameters(e.Parameters);
304             }
305             else
306             {
307                 ValidateIdentifier(e, nameof(e.Name), e.Name);
308             }
309 
310             if (e.HasGet)
311             {
312                 if (!(IsCurrentInterface || (e.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract))
313                 {
314                     ValidateStatements(e.GetStatements);
315                 }
316             }
317 
318             if (e.HasSet)
319             {
320                 if (!(IsCurrentInterface || (e.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract))
321                 {
322                     ValidateStatements(e.SetStatements);
323                 }
324             }
325         }
326 
ValidateMemberMethod(CodeMemberMethod e)327         private void ValidateMemberMethod(CodeMemberMethod e)
328         {
329             ValidateCommentStatements(e.Comments);
330             if (e.LinePragma != null) ValidateLinePragmaStart(e.LinePragma);
331 
332             ValidateTypeParameters(e.TypeParameters);
333             ValidateTypeReferences(e.ImplementationTypes);
334 
335             if (e is CodeEntryPointMethod)
336             {
337                 ValidateStatements(((CodeEntryPointMethod)e).Statements);
338             }
339             else if (e is CodeConstructor)
340             {
341                 ValidateConstructor((CodeConstructor)e);
342             }
343             else if (e is CodeTypeConstructor)
344             {
345                 ValidateTypeConstructor((CodeTypeConstructor)e);
346             }
347             else
348             {
349                 ValidateMethod(e);
350             }
351         }
352 
ValidateTypeConstructor(CodeTypeConstructor e)353         private void ValidateTypeConstructor(CodeTypeConstructor e)
354         {
355             ValidateStatements(e.Statements);
356         }
357 
ValidateMethod(CodeMemberMethod e)358         private void ValidateMethod(CodeMemberMethod e)
359         {
360             if (e.CustomAttributes.Count > 0)
361             {
362                 ValidateAttributes(e.CustomAttributes);
363             }
364             if (e.ReturnTypeCustomAttributes.Count > 0)
365             {
366                 ValidateAttributes(e.ReturnTypeCustomAttributes);
367             }
368 
369             ValidateTypeReference(e.ReturnType);
370             if (e.PrivateImplementationType != null)
371             {
372                 ValidateTypeReference(e.PrivateImplementationType);
373             }
374 
375             ValidateIdentifier(e, nameof(e.Name), e.Name);
376             ValidateParameters(e.Parameters);
377 
378             if (!IsCurrentInterface
379                 && (e.Attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract)
380             {
381                 ValidateStatements(e.Statements);
382             }
383         }
384 
ValidateSnippetMember(CodeSnippetTypeMember e)385         private void ValidateSnippetMember(CodeSnippetTypeMember e)
386         {
387         }
388 
ValidateTypeStart(CodeTypeDeclaration e)389         private void ValidateTypeStart(CodeTypeDeclaration e)
390         {
391             ValidateCommentStatements(e.Comments);
392             if (e.CustomAttributes.Count > 0)
393             {
394                 ValidateAttributes(e.CustomAttributes);
395             }
396 
397             ValidateIdentifier(e, nameof(e.Name), e.Name);
398             if (IsCurrentDelegate)
399             {
400                 CodeTypeDelegate del = (CodeTypeDelegate)e;
401                 ValidateTypeReference(del.ReturnType);
402                 ValidateParameters(del.Parameters);
403             }
404             else
405             {
406                 foreach (CodeTypeReference typeRef in e.BaseTypes)
407                 {
408                     ValidateTypeReference(typeRef);
409                 }
410             }
411         }
412 
ValidateCommentStatements(CodeCommentStatementCollection e)413         private void ValidateCommentStatements(CodeCommentStatementCollection e)
414         {
415             foreach (CodeCommentStatement comment in e)
416             {
417                 ValidateCommentStatement(comment);
418             }
419         }
420 
ValidateCommentStatement(CodeCommentStatement e)421         private void ValidateCommentStatement(CodeCommentStatement e)
422         {
423             ValidateComment(e.Comment);
424         }
425 
ValidateComment(CodeComment e)426         private void ValidateComment(CodeComment e)
427         {
428         }
429 
ValidateStatement(CodeStatement e)430         private void ValidateStatement(CodeStatement e)
431         {
432             ValidateCodeDirectives(e.StartDirectives);
433             ValidateCodeDirectives(e.EndDirectives);
434 
435             if (e is CodeCommentStatement)
436             {
437                 ValidateCommentStatement((CodeCommentStatement)e);
438             }
439             else if (e is CodeMethodReturnStatement)
440             {
441                 ValidateMethodReturnStatement((CodeMethodReturnStatement)e);
442             }
443             else if (e is CodeConditionStatement)
444             {
445                 ValidateConditionStatement((CodeConditionStatement)e);
446             }
447             else if (e is CodeTryCatchFinallyStatement)
448             {
449                 ValidateTryCatchFinallyStatement((CodeTryCatchFinallyStatement)e);
450             }
451             else if (e is CodeAssignStatement)
452             {
453                 ValidateAssignStatement((CodeAssignStatement)e);
454             }
455             else if (e is CodeExpressionStatement)
456             {
457                 ValidateExpressionStatement((CodeExpressionStatement)e);
458             }
459             else if (e is CodeIterationStatement)
460             {
461                 ValidateIterationStatement((CodeIterationStatement)e);
462             }
463             else if (e is CodeThrowExceptionStatement)
464             {
465                 ValidateThrowExceptionStatement((CodeThrowExceptionStatement)e);
466             }
467             else if (e is CodeSnippetStatement)
468             {
469                 ValidateSnippetStatement((CodeSnippetStatement)e);
470             }
471             else if (e is CodeVariableDeclarationStatement)
472             {
473                 ValidateVariableDeclarationStatement((CodeVariableDeclarationStatement)e);
474             }
475             else if (e is CodeAttachEventStatement)
476             {
477                 ValidateAttachEventStatement((CodeAttachEventStatement)e);
478             }
479             else if (e is CodeRemoveEventStatement)
480             {
481                 ValidateRemoveEventStatement((CodeRemoveEventStatement)e);
482             }
483             else if (e is CodeGotoStatement)
484             {
485                 ValidateGotoStatement((CodeGotoStatement)e);
486             }
487             else if (e is CodeLabeledStatement)
488             {
489                 ValidateLabeledStatement((CodeLabeledStatement)e);
490             }
491             else
492             {
493                 throw new ArgumentException(SR.Format(SR.InvalidElementType, e.GetType().FullName), nameof(e));
494             }
495         }
496 
ValidateStatements(CodeStatementCollection stmts)497         private void ValidateStatements(CodeStatementCollection stmts)
498         {
499             foreach (CodeStatement stmt in stmts)
500             {
501                 ValidateStatement(stmt);
502             }
503         }
504 
ValidateExpressionStatement(CodeExpressionStatement e)505         private void ValidateExpressionStatement(CodeExpressionStatement e)
506         {
507             ValidateExpression(e.Expression);
508         }
509 
ValidateIterationStatement(CodeIterationStatement e)510         private void ValidateIterationStatement(CodeIterationStatement e)
511         {
512             ValidateStatement(e.InitStatement);
513             ValidateExpression(e.TestExpression);
514             ValidateStatement(e.IncrementStatement);
515             ValidateStatements(e.Statements);
516         }
517 
ValidateThrowExceptionStatement(CodeThrowExceptionStatement e)518         private void ValidateThrowExceptionStatement(CodeThrowExceptionStatement e)
519         {
520             if (e.ToThrow != null)
521             {
522                 ValidateExpression(e.ToThrow);
523             }
524         }
525 
ValidateMethodReturnStatement(CodeMethodReturnStatement e)526         private void ValidateMethodReturnStatement(CodeMethodReturnStatement e)
527         {
528             if (e.Expression != null)
529             {
530                 ValidateExpression(e.Expression);
531             }
532         }
533 
ValidateConditionStatement(CodeConditionStatement e)534         private void ValidateConditionStatement(CodeConditionStatement e)
535         {
536             ValidateExpression(e.Condition);
537             ValidateStatements(e.TrueStatements);
538 
539             CodeStatementCollection falseStatemetns = e.FalseStatements;
540             if (falseStatemetns.Count > 0)
541             {
542                 ValidateStatements(e.FalseStatements);
543             }
544         }
545 
ValidateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e)546         private void ValidateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e)
547         {
548             ValidateStatements(e.TryStatements);
549             CodeCatchClauseCollection catches = e.CatchClauses;
550             if (catches.Count > 0)
551             {
552                 foreach (CodeCatchClause current in catches)
553                 {
554                     ValidateTypeReference(current.CatchExceptionType);
555                     ValidateIdentifier(current, nameof(current.LocalName), current.LocalName);
556                     ValidateStatements(current.Statements);
557                 }
558             }
559 
560             CodeStatementCollection finallyStatements = e.FinallyStatements;
561             if (finallyStatements.Count > 0)
562             {
563                 ValidateStatements(finallyStatements);
564             }
565         }
566 
ValidateAssignStatement(CodeAssignStatement e)567         private void ValidateAssignStatement(CodeAssignStatement e)
568         {
569             ValidateExpression(e.Left);
570             ValidateExpression(e.Right);
571         }
572 
ValidateAttachEventStatement(CodeAttachEventStatement e)573         private void ValidateAttachEventStatement(CodeAttachEventStatement e)
574         {
575             ValidateEventReferenceExpression(e.Event);
576             ValidateExpression(e.Listener);
577         }
578 
ValidateRemoveEventStatement(CodeRemoveEventStatement e)579         private void ValidateRemoveEventStatement(CodeRemoveEventStatement e)
580         {
581             ValidateEventReferenceExpression(e.Event);
582             ValidateExpression(e.Listener);
583         }
584 
ValidateGotoStatement(CodeGotoStatement e)585         private static void ValidateGotoStatement(CodeGotoStatement e)
586         {
587             ValidateIdentifier(e, nameof(e.Label), e.Label);
588         }
589 
ValidateLabeledStatement(CodeLabeledStatement e)590         private void ValidateLabeledStatement(CodeLabeledStatement e)
591         {
592             ValidateIdentifier(e, nameof(e.Label), e.Label);
593             if (e.Statement != null)
594             {
595                 ValidateStatement(e.Statement);
596             }
597         }
598 
ValidateVariableDeclarationStatement(CodeVariableDeclarationStatement e)599         private void ValidateVariableDeclarationStatement(CodeVariableDeclarationStatement e)
600         {
601             ValidateTypeReference(e.Type);
602             ValidateIdentifier(e, nameof(e.Name), e.Name);
603             if (e.InitExpression != null)
604             {
605                 ValidateExpression(e.InitExpression);
606             }
607         }
608 
ValidateLinePragmaStart(CodeLinePragma e)609         private void ValidateLinePragmaStart(CodeLinePragma e)
610         {
611         }
612 
ValidateEvent(CodeMemberEvent e)613         private void ValidateEvent(CodeMemberEvent e)
614         {
615             if (e.CustomAttributes.Count > 0)
616             {
617                 ValidateAttributes(e.CustomAttributes);
618             }
619             if (e.PrivateImplementationType != null)
620             {
621                 ValidateTypeReference(e.Type);
622                 ValidateIdentifier(e, nameof(e.Name), e.Name);
623             }
624 
625             ValidateTypeReferences(e.ImplementationTypes);
626         }
627 
ValidateParameters(CodeParameterDeclarationExpressionCollection parameters)628         private void ValidateParameters(CodeParameterDeclarationExpressionCollection parameters)
629         {
630             foreach (CodeParameterDeclarationExpression current in parameters)
631             {
632                 ValidateParameterDeclarationExpression(current);
633             }
634         }
635 
ValidateSnippetStatement(CodeSnippetStatement e)636         private void ValidateSnippetStatement(CodeSnippetStatement e)
637         {
638         }
639 
ValidateExpressionList(CodeExpressionCollection expressions)640         private void ValidateExpressionList(CodeExpressionCollection expressions)
641         {
642             foreach (CodeExpression current in expressions)
643             {
644                 ValidateExpression(current);
645             }
646         }
647 
ValidateTypeReference(CodeTypeReference e)648         private static void ValidateTypeReference(CodeTypeReference e)
649         {
650             ValidateTypeName(e, nameof(e.BaseType), e.BaseType);
651             ValidateArity(e);
652             ValidateTypeReferences(e.TypeArguments);
653         }
654 
ValidateTypeReferences(CodeTypeReferenceCollection refs)655         private static void ValidateTypeReferences(CodeTypeReferenceCollection refs)
656         {
657             for (int i = 0; i < refs.Count; i++)
658             {
659                 ValidateTypeReference(refs[i]);
660             }
661         }
662 
ValidateArity(CodeTypeReference e)663         private static void ValidateArity(CodeTypeReference e)
664         {
665             // Verify that the number of TypeArguments agrees with the arity on the type.
666             string baseType = e.BaseType;
667             int totalTypeArgs = 0;
668             for (int i = 0; i < baseType.Length; i++)
669             {
670                 if (baseType[i] == '`')
671                 {
672                     i++;    // skip the '
673                     int numTypeArgs = 0;
674                     while (i < baseType.Length && baseType[i] >= '0' && baseType[i] <= '9')
675                     {
676                         numTypeArgs = numTypeArgs * 10 + (baseType[i] - '0');
677                         i++;
678                     }
679 
680                     totalTypeArgs += numTypeArgs;
681                 }
682             }
683 
684             // Check if we have zero type args for open types.
685             if ((totalTypeArgs != e.TypeArguments.Count) && (e.TypeArguments.Count != 0))
686             {
687                 throw new ArgumentException(SR.Format(SR.ArityDoesntMatch, baseType, e.TypeArguments.Count));
688             }
689         }
690 
ValidateTypeName(object e, string propertyName, string typeName)691         private static void ValidateTypeName(object e, string propertyName, string typeName)
692         {
693             if (!CodeGenerator.IsValidLanguageIndependentTypeName(typeName))
694             {
695                 string message = SR.Format(SR.InvalidTypeName, typeName, propertyName, e.GetType().FullName);
696                 throw new ArgumentException(message, nameof(typeName));
697             }
698         }
699 
ValidateIdentifier(object e, string propertyName, string identifier)700         private static void ValidateIdentifier(object e, string propertyName, string identifier)
701         {
702             if (!CodeGenerator.IsValidLanguageIndependentIdentifier(identifier))
703             {
704                 string message = SR.Format(SR.InvalidLanguageIdentifier, identifier, propertyName, e.GetType().FullName);
705                 throw new ArgumentException(message, nameof(identifier));
706             }
707         }
708 
ValidateExpression(CodeExpression e)709         private void ValidateExpression(CodeExpression e)
710         {
711             if (e is CodeArrayCreateExpression)
712             {
713                 ValidateArrayCreateExpression((CodeArrayCreateExpression)e);
714             }
715             else if (e is CodeBaseReferenceExpression)
716             {
717                 ValidateBaseReferenceExpression((CodeBaseReferenceExpression)e);
718             }
719             else if (e is CodeBinaryOperatorExpression)
720             {
721                 ValidateBinaryOperatorExpression((CodeBinaryOperatorExpression)e);
722             }
723             else if (e is CodeCastExpression)
724             {
725                 ValidateCastExpression((CodeCastExpression)e);
726             }
727             else if (e is CodeDefaultValueExpression)
728             {
729                 ValidateDefaultValueExpression((CodeDefaultValueExpression)e);
730             }
731             else if (e is CodeDelegateCreateExpression)
732             {
733                 ValidateDelegateCreateExpression((CodeDelegateCreateExpression)e);
734             }
735             else if (e is CodeFieldReferenceExpression)
736             {
737                 ValidateFieldReferenceExpression((CodeFieldReferenceExpression)e);
738             }
739             else if (e is CodeArgumentReferenceExpression)
740             {
741                 ValidateArgumentReferenceExpression((CodeArgumentReferenceExpression)e);
742             }
743             else if (e is CodeVariableReferenceExpression)
744             {
745                 ValidateVariableReferenceExpression((CodeVariableReferenceExpression)e);
746             }
747             else if (e is CodeIndexerExpression)
748             {
749                 ValidateIndexerExpression((CodeIndexerExpression)e);
750             }
751             else if (e is CodeArrayIndexerExpression)
752             {
753                 ValidateArrayIndexerExpression((CodeArrayIndexerExpression)e);
754             }
755             else if (e is CodeSnippetExpression)
756             {
757                 ValidateSnippetExpression((CodeSnippetExpression)e);
758             }
759             else if (e is CodeMethodInvokeExpression)
760             {
761                 ValidateMethodInvokeExpression((CodeMethodInvokeExpression)e);
762             }
763             else if (e is CodeMethodReferenceExpression)
764             {
765                 ValidateMethodReferenceExpression((CodeMethodReferenceExpression)e);
766             }
767             else if (e is CodeEventReferenceExpression)
768             {
769                 ValidateEventReferenceExpression((CodeEventReferenceExpression)e);
770             }
771             else if (e is CodeDelegateInvokeExpression)
772             {
773                 ValidateDelegateInvokeExpression((CodeDelegateInvokeExpression)e);
774             }
775             else if (e is CodeObjectCreateExpression)
776             {
777                 ValidateObjectCreateExpression((CodeObjectCreateExpression)e);
778             }
779             else if (e is CodeParameterDeclarationExpression)
780             {
781                 ValidateParameterDeclarationExpression((CodeParameterDeclarationExpression)e);
782             }
783             else if (e is CodeDirectionExpression)
784             {
785                 ValidateDirectionExpression((CodeDirectionExpression)e);
786             }
787             else if (e is CodePrimitiveExpression)
788             {
789                 ValidatePrimitiveExpression((CodePrimitiveExpression)e);
790             }
791             else if (e is CodePropertyReferenceExpression)
792             {
793                 ValidatePropertyReferenceExpression((CodePropertyReferenceExpression)e);
794             }
795             else if (e is CodePropertySetValueReferenceExpression)
796             {
797                 ValidatePropertySetValueReferenceExpression((CodePropertySetValueReferenceExpression)e);
798             }
799             else if (e is CodeThisReferenceExpression)
800             {
801                 ValidateThisReferenceExpression((CodeThisReferenceExpression)e);
802             }
803             else if (e is CodeTypeReferenceExpression)
804             {
805                 ValidateTypeReference(((CodeTypeReferenceExpression)e).Type);
806             }
807             else if (e is CodeTypeOfExpression)
808             {
809                 ValidateTypeOfExpression((CodeTypeOfExpression)e);
810             }
811             else
812             {
813                 if (e == null)
814                 {
815                     throw new ArgumentNullException(nameof(e));
816                 }
817                 else
818                 {
819                     throw new ArgumentException(SR.Format(SR.InvalidElementType, e.GetType().FullName), nameof(e));
820                 }
821             }
822         }
823 
ValidateArrayCreateExpression(CodeArrayCreateExpression e)824         private void ValidateArrayCreateExpression(CodeArrayCreateExpression e)
825         {
826             ValidateTypeReference(e.CreateType);
827             CodeExpressionCollection init = e.Initializers;
828             if (init.Count > 0)
829             {
830                 ValidateExpressionList(init);
831             }
832             else
833             {
834                 if (e.SizeExpression != null)
835                 {
836                     ValidateExpression(e.SizeExpression);
837                 }
838             }
839         }
840 
ValidateBaseReferenceExpression(CodeBaseReferenceExpression e)841         private void ValidateBaseReferenceExpression(CodeBaseReferenceExpression e)
842         { // Nothing to validate
843         }
844 
ValidateBinaryOperatorExpression(CodeBinaryOperatorExpression e)845         private void ValidateBinaryOperatorExpression(CodeBinaryOperatorExpression e)
846         {
847             ValidateExpression(e.Left);
848             ValidateExpression(e.Right);
849         }
850 
ValidateCastExpression(CodeCastExpression e)851         private void ValidateCastExpression(CodeCastExpression e)
852         {
853             ValidateTypeReference(e.TargetType);
854             ValidateExpression(e.Expression);
855         }
856 
ValidateDefaultValueExpression(CodeDefaultValueExpression e)857         private static void ValidateDefaultValueExpression(CodeDefaultValueExpression e)
858         {
859             ValidateTypeReference(e.Type);
860         }
861 
ValidateDelegateCreateExpression(CodeDelegateCreateExpression e)862         private void ValidateDelegateCreateExpression(CodeDelegateCreateExpression e)
863         {
864             ValidateTypeReference(e.DelegateType);
865             ValidateExpression(e.TargetObject);
866             ValidateIdentifier(e, nameof(e.MethodName), e.MethodName);
867         }
868 
ValidateFieldReferenceExpression(CodeFieldReferenceExpression e)869         private void ValidateFieldReferenceExpression(CodeFieldReferenceExpression e)
870         {
871             if (e.TargetObject != null)
872             {
873                 ValidateExpression(e.TargetObject);
874             }
875             ValidateIdentifier(e, nameof(e.FieldName), e.FieldName);
876         }
877 
ValidateArgumentReferenceExpression(CodeArgumentReferenceExpression e)878         private static void ValidateArgumentReferenceExpression(CodeArgumentReferenceExpression e)
879         {
880             ValidateIdentifier(e, nameof(e.ParameterName), e.ParameterName);
881         }
882 
ValidateVariableReferenceExpression(CodeVariableReferenceExpression e)883         private static void ValidateVariableReferenceExpression(CodeVariableReferenceExpression e)
884         {
885             ValidateIdentifier(e, nameof(e.VariableName), e.VariableName);
886         }
887 
ValidateIndexerExpression(CodeIndexerExpression e)888         private void ValidateIndexerExpression(CodeIndexerExpression e)
889         {
890             ValidateExpression(e.TargetObject);
891             foreach (CodeExpression exp in e.Indices)
892             {
893                 ValidateExpression(exp);
894             }
895         }
896 
ValidateArrayIndexerExpression(CodeArrayIndexerExpression e)897         private void ValidateArrayIndexerExpression(CodeArrayIndexerExpression e)
898         {
899             ValidateExpression(e.TargetObject);
900             foreach (CodeExpression exp in e.Indices)
901             {
902                 ValidateExpression(exp);
903             }
904         }
905 
ValidateSnippetExpression(CodeSnippetExpression e)906         private void ValidateSnippetExpression(CodeSnippetExpression e)
907         {
908         }
909 
ValidateMethodInvokeExpression(CodeMethodInvokeExpression e)910         private void ValidateMethodInvokeExpression(CodeMethodInvokeExpression e)
911         {
912             ValidateMethodReferenceExpression(e.Method);
913             ValidateExpressionList(e.Parameters);
914         }
915 
ValidateMethodReferenceExpression(CodeMethodReferenceExpression e)916         private void ValidateMethodReferenceExpression(CodeMethodReferenceExpression e)
917         {
918             if (e.TargetObject != null)
919             {
920                 ValidateExpression(e.TargetObject);
921             }
922             ValidateIdentifier(e, nameof(e.MethodName), e.MethodName);
923             ValidateTypeReferences(e.TypeArguments);
924         }
925 
ValidateEventReferenceExpression(CodeEventReferenceExpression e)926         private void ValidateEventReferenceExpression(CodeEventReferenceExpression e)
927         {
928             if (e.TargetObject != null)
929             {
930                 ValidateExpression(e.TargetObject);
931             }
932             ValidateIdentifier(e, nameof(e.EventName), e.EventName);
933         }
934 
ValidateDelegateInvokeExpression(CodeDelegateInvokeExpression e)935         private void ValidateDelegateInvokeExpression(CodeDelegateInvokeExpression e)
936         {
937             if (e.TargetObject != null)
938             {
939                 ValidateExpression(e.TargetObject);
940             }
941             ValidateExpressionList(e.Parameters);
942         }
943 
ValidateObjectCreateExpression(CodeObjectCreateExpression e)944         private void ValidateObjectCreateExpression(CodeObjectCreateExpression e)
945         {
946             ValidateTypeReference(e.CreateType);
947             ValidateExpressionList(e.Parameters);
948         }
949 
ValidateParameterDeclarationExpression(CodeParameterDeclarationExpression e)950         private void ValidateParameterDeclarationExpression(CodeParameterDeclarationExpression e)
951         {
952             if (e.CustomAttributes.Count > 0)
953             {
954                 ValidateAttributes(e.CustomAttributes);
955             }
956 
957             ValidateTypeReference(e.Type);
958             ValidateIdentifier(e, nameof(e.Name), e.Name);
959         }
960 
ValidateDirectionExpression(CodeDirectionExpression e)961         private void ValidateDirectionExpression(CodeDirectionExpression e)
962         {
963             ValidateExpression(e.Expression);
964         }
965 
ValidatePrimitiveExpression(CodePrimitiveExpression e)966         private void ValidatePrimitiveExpression(CodePrimitiveExpression e)
967         {
968         }
969 
ValidatePropertyReferenceExpression(CodePropertyReferenceExpression e)970         private void ValidatePropertyReferenceExpression(CodePropertyReferenceExpression e)
971         {
972             if (e.TargetObject != null)
973             {
974                 ValidateExpression(e.TargetObject);
975             }
976             ValidateIdentifier(e, nameof(e.PropertyName), e.PropertyName);
977         }
978 
ValidatePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e)979         private void ValidatePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e)
980         { // Do nothing
981         }
982 
ValidateThisReferenceExpression(CodeThisReferenceExpression e)983         private void ValidateThisReferenceExpression(CodeThisReferenceExpression e)
984         {  // Do nothing
985         }
986 
ValidateTypeOfExpression(CodeTypeOfExpression e)987         private static void ValidateTypeOfExpression(CodeTypeOfExpression e)
988         {
989             ValidateTypeReference(e.Type);
990         }
991 
ValidateCodeDirectives(CodeDirectiveCollection e)992         private static void ValidateCodeDirectives(CodeDirectiveCollection e)
993         {
994             for (int i = 0; i < e.Count; i++)
995                 ValidateCodeDirective(e[i]);
996         }
997 
ValidateCodeDirective(CodeDirective e)998         private static void ValidateCodeDirective(CodeDirective e)
999         {
1000             if (e is CodeChecksumPragma)
1001             {
1002                 ValidateChecksumPragma((CodeChecksumPragma)e);
1003             }
1004             else if (e is CodeRegionDirective)
1005             {
1006                 ValidateRegionDirective((CodeRegionDirective)e);
1007             }
1008             else
1009             {
1010                 throw new ArgumentException(SR.Format(SR.InvalidElementType, e.GetType().FullName), nameof(e));
1011             }
1012         }
1013 
ValidateChecksumPragma(CodeChecksumPragma e)1014         private static void ValidateChecksumPragma(CodeChecksumPragma e)
1015         {
1016             if (e.FileName.IndexOfAny(Path.GetInvalidPathChars()) != -1)
1017                 throw new ArgumentException(SR.Format(SR.InvalidPathCharsInChecksum, e.FileName));
1018         }
1019 
ValidateRegionDirective(CodeRegionDirective e)1020         private static void ValidateRegionDirective(CodeRegionDirective e)
1021         {
1022             if (e.RegionText.IndexOfAny(s_newLineChars) != -1)
1023                 throw new ArgumentException(SR.Format(SR.InvalidRegion, e.RegionText));
1024         }
1025 
1026         private bool IsCurrentInterface => _currentClass != null && !(_currentClass is CodeTypeDelegate) ? _currentClass.IsInterface : false;
1027 
1028         private bool IsCurrentEnum => _currentClass != null && !(_currentClass is CodeTypeDelegate) ? _currentClass.IsEnum : false;
1029 
1030         private bool IsCurrentDelegate => _currentClass != null && _currentClass is CodeTypeDelegate;
1031     }
1032 }
1033