The Labs \ Source Viewer \ SSCLI \ System \ UncNameHelper

  1. #if !PLATFORM_UNIX
  2. //------------------------------------------------------------------------------
  3. // <copyright file="_UncName.cs" company="Microsoft">
  4. //
  5. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  6. //
  7. // The use and distribution terms for this software are contained in the file
  8. // named license.txt, which can be found in the root of this distribution.
  9. // By using this software in any fashion, you are agreeing to be bound by the
  10. // terms of this license.
  11. //
  12. // You must not remove this notice, or any other, from this software.
  13. //
  14. // </copyright>
  15. //------------------------------------------------------------------------------
  16. using System.Globalization;
  17. namespace System
  18. {
  19.    
  20.     // The class designed as to keep minimal the working set of Uri class.
  21.     // The idea is to stay with static helper methods and strings
  22.     internal class UncNameHelper
  23.     {
  24.        
  25.         // fields
  26.        
  27.         internal const int MaximumInternetNameLength = 256;
  28.        
  29.         private UncNameHelper()
  30.         {
  31.         }
  32.        
  33.        
  34.         // properties
  35.        
  36.         // methods
  37.         static internal string ParseCanonicalName(string str, int start, int end, ref bool loopback)
  38.         {
  39.             return DomainNameHelper.ParseCanonicalName(str, start, end, ref loopback);
  40.         }
  41.        
  42.         //
  43.         // IsValid
  44.         //
  45.         //
  46.         // ATTN: This class has been re-designed as to conform to XP+ UNC hostname format
  47.         // It is now similar to DNS name but can contain Unicode characters as well
  48.         // This class will be removed and replaced by IDN specification later,
  49.         // but for now we violate URI RFC cause we never escape Unicode characters on the wire
  50.         // For the same reason we never unescape UNC host names since we never accept
  51.         // them in escaped format.
  52.         //
  53.         //
  54.         // Valid UNC server name chars:
  55.         // a Unicode Letter (not allowed as the only in a segment)
  56.         // a Latin-1 digit
  57.         // '-' 45 0x2D
  58.         // '.' 46 0x2E (only as a host domain delimiter)
  59.         // '_' 95 0x5F
  60.         //
  61.         //
  62.         // Assumption is the caller will check on the resulting name length
  63.         // Remarks: MUST NOT be used unless all input indexes are are verified and trusted.
  64.         unsafe static internal bool IsValid(char* name, ushort start, ref int returnedEnd, bool notImplicitFile)
  65.         {
  66.             ushort end = (ushort)returnedEnd;
  67.            
  68.             if (start == end)
  69.                 return false;
  70.             //
  71.             // First segment could consist of only '_' or '-' but it cannot be all digits or empty
  72.             //
  73.             bool validShortName = false;
  74.             ushort i = start;
  75.             for (; i < end; ++i) {
  76.                 if (name[i] == '/' || name[i] == '\\' || (notImplicitFile && (name[i] == ':' || name[i] == '?' || name[i] == '#'))) {
  77.                     end = i;
  78.                     break;
  79.                 }
  80.                 else if (name[i] == '.') {
  81.                     ++i;
  82.                     break;
  83.                 }
  84.                 if (Char.IsLetter(name[i]) || name[i] == '-' || name[i] == '_') {
  85.                     validShortName = true;
  86.                 }
  87.                 else if (name[i] < '0' || name[i] > '9')
  88.                     return false;
  89.             }
  90.            
  91.             if (!validShortName)
  92.                 return false;
  93.            
  94.             //
  95.             // Subsequent segments must start with a letter or a digit
  96.             //
  97.            
  98.             for (; i < end; ++i) {
  99.                 if (name[i] == '/' || name[i] == '\\' || (notImplicitFile && (name[i] == ':' || name[i] == '?' || name[i] == '#'))) {
  100.                     end = i;
  101.                     break;
  102.                 }
  103.                 else if (name[i] == '.') {
  104.                     if (!validShortName || ((i - 1) >= start && name[i - 1] == '.'))
  105.                         return false;
  106.                    
  107.                     validShortName = false;
  108.                 }
  109.                 else if (name[i] == '-' || name[i] == '_') {
  110.                     if (!validShortName)
  111.                         return false;
  112.                 }
  113.                 else if (Char.IsLetter(name[i]) || (name[i] >= '0' && name[i] <= '9')) {
  114.                     if (!validShortName)
  115.                         validShortName = true;
  116.                 }
  117.                 else
  118.                     return false;
  119.             }
  120.            
  121.             // last segment can end with the dot
  122.             if (((i - 1) >= start && name[i - 1] == '.'))
  123.                 validShortName = true;
  124.            
  125.             if (!validShortName)
  126.                 return false;
  127.            
  128.             // caller must check for (end - start <= MaximumInternetNameLength)
  129.            
  130.             returnedEnd = end;
  131.             return true;
  132.         }
  133.     }
  134. }
  135. #endif // !PLATFORM_UNIX

Developer Fusion