Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.09 KB | None | 0 0
  1. internal static unsafe long ParseNonCanonical(char* name, int start, ref int end, bool notImplicitFile)
  2.         {
  3.             int numberBase = Decimal;
  4.             char ch;
  5.             long* parts = stackalloc long[4];
  6.             long currentValue = 0;
  7.             bool atLeastOneChar = false;
  8.  
  9.             // Parse one dotted section at a time
  10.             int dotCount = 0; // Limit 3
  11.             int current = start;
  12.             for (; current < end; current++)
  13.             {
  14.                 ch = name[current];
  15.                 currentValue = 0;
  16.  
  17.                 // Figure out what base this section is in
  18.                 numberBase = Decimal;
  19.                 if (ch == '0')
  20.                 {
  21.                     numberBase = Octal;
  22.                     current++;
  23.                     atLeastOneChar = true;
  24.                     if (current < end)
  25.                     {
  26.                         ch = name[current];
  27.                         if (ch == 'x' || ch == 'X')
  28.                         {
  29.                             numberBase = Hex;
  30.                             current++;
  31.                             atLeastOneChar = false;
  32.                         }
  33.                     }
  34.                 }
  35.  
  36.                 // Parse this section
  37.                 for (; current < end; current++)
  38.                 {
  39.                     ch = name[current];
  40.                     int digitValue;
  41.  
  42.                     if ((numberBase == Decimal || numberBase == Hex) && '0' <= ch && ch <= '9')
  43.                     {
  44.                         digitValue = ch - '0';
  45.                     }
  46.                     else if (numberBase == Octal && '0' <= ch && ch <= '7')
  47.                     {
  48.                         digitValue = ch - '0';
  49.                     }
  50.                     else if (numberBase == Hex && 'a' <= ch && ch <= 'f')
  51.                     {
  52.                         digitValue = ch + 10 - 'a';
  53.                     }
  54.                     else if (numberBase == Hex && 'A' <= ch && ch <= 'F')
  55.                     {
  56.                         digitValue = ch + 10 - 'A';
  57.                     }
  58.                     else
  59.                     {
  60.                         break; // Invalid/terminator
  61.                     }
  62.  
  63.                     currentValue = (currentValue * numberBase) + digitValue;
  64.  
  65.                     if (currentValue > MaxIPv4Value) // Overflow
  66.                     {
  67.                         return Invalid;
  68.                     }
  69.  
  70.                     atLeastOneChar = true;
  71.                 }
  72.  
  73.                 if (current < end && name[current] == '.')
  74.                 {
  75.                     if (dotCount >= 3 // Max of 3 dots and 4 segments
  76.                         || !atLeastOneChar // No empty segmets: 1...1
  77.                                            // Only the last segment can be more than 255 (if there are less than 3 dots)
  78.                         || currentValue > 0xFF)
  79.                     {
  80.                         return Invalid;
  81.                     }
  82.                     parts[dotCount] = currentValue;
  83.                     dotCount++;
  84.                     atLeastOneChar = false;
  85.                     continue;
  86.                 }
  87.                 // We don't get here unless We find an invalid character or a terminator
  88.                 break;
  89.             }
  90.  
  91.             // Terminators
  92.             if (!atLeastOneChar)
  93.             {
  94.                 return Invalid;  // Empty trailing segment: 1.1.1.
  95.             }
  96.             else if (current >= end)
  97.             {
  98.                 // end of string, allowed
  99.             }
  100.             else if ((ch = name[current]) == '/' || ch == '\\' || (notImplicitFile && (ch == ':' || ch == '?' || ch == '#')))
  101.             {
  102.                 end = current;
  103.             }
  104.             else
  105.             {
  106.                 // not a valid terminating character
  107.                 return Invalid;
  108.             }
  109.  
  110.             parts[dotCount] = currentValue;
  111.  
  112.             // Parsed, reassemble and check for overflows
  113.             switch (dotCount)
  114.             {
  115.                 case 0: // 0xFFFFFFFF
  116.                     if (parts[0] > MaxIPv4Value)
  117.                     {
  118.                         return Invalid;
  119.                     }
  120.                     return parts[0];
  121.                 case 1: // 0xFF.0xFFFFFF
  122.                     if (parts[1] > 0xffffff)
  123.                     {
  124.                         return Invalid;
  125.                     }
  126.                     return (parts[0] << 24) | (parts[1] & 0xffffff);
  127.                 case 2: // 0xFF.0xFF.0xFFFF
  128.                     if (parts[2] > 0xffff)
  129.                     {
  130.                         return Invalid;
  131.                     }
  132.                     return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | (parts[2] & 0xffff);
  133.                 case 3: // 0xFF.0xFF.0xFF.0xFF
  134.                     if (parts[3] > 0xff)
  135.                     {
  136.                         return Invalid;
  137.                     }
  138.                     return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
  139.                 default:
  140.                     return Invalid;
  141.             }
  142.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement