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