Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- internal static unsafe long ParseNonCanonical(char* name, int start, ref int end, bool notImplicitFile)
- {
- int numberBase = Decimal;
- char ch;
- long* parts = stackalloc long[4];
- long currentValue = 0;
- bool atLeastOneChar = false;
- // Parse one dotted section at a time
- int dotCount = 0; // Limit 3
- int current = start;
- for (; current < end; current++)
- {
- ch = name[current];
- currentValue = 0;
- // Figure out what base this section is in
- numberBase = Decimal;
- if (ch == '0')
- {
- numberBase = Octal;
- current++;
- atLeastOneChar = true;
- if (current < end)
- {
- ch = name[current];
- if (ch == 'x' || ch == 'X')
- {
- numberBase = Hex;
- current++;
- atLeastOneChar = false;
- }
- }
- }
- // Parse this section
- for (; current < end; current++)
- {
- ch = name[current];
- int digitValue;
- if ((numberBase == Decimal || numberBase == Hex) && '0' <= ch && ch <= '9')
- {
- digitValue = ch - '0';
- }
- else if (numberBase == Octal && '0' <= ch && ch <= '7')
- {
- digitValue = ch - '0';
- }
- else if (numberBase == Hex && 'a' <= ch && ch <= 'f')
- {
- digitValue = ch + 10 - 'a';
- }
- else if (numberBase == Hex && 'A' <= ch && ch <= 'F')
- {
- digitValue = ch + 10 - 'A';
- }
- else
- {
- break; // Invalid/terminator
- }
- currentValue = (currentValue * numberBase) + digitValue;
- if (currentValue > MaxIPv4Value) // Overflow
- {
- return Invalid;
- }
- atLeastOneChar = true;
- }
- if (current < end && name[current] == '.')
- {
- if (dotCount >= 3 // Max of 3 dots and 4 segments
- || !atLeastOneChar // No empty segmets: 1...1
- // Only the last segment can be more than 255 (if there are less than 3 dots)
- || currentValue > 0xFF)
- {
- return Invalid;
- }
- parts[dotCount] = currentValue;
- dotCount++;
- atLeastOneChar = false;
- continue;
- }
- // We don't get here unless We find an invalid character or a terminator
- break;
- }
- // Terminators
- if (!atLeastOneChar)
- {
- return Invalid; // Empty trailing segment: 1.1.1.
- }
- else if (current >= end)
- {
- // end of string, allowed
- }
- else if ((ch = name[current]) == '/' || ch == '\\' || (notImplicitFile && (ch == ':' || ch == '?' || ch == '#')))
- {
- end = current;
- }
- else
- {
- // not a valid terminating character
- return Invalid;
- }
- parts[dotCount] = currentValue;
- // Parsed, reassemble and check for overflows
- switch (dotCount)
- {
- case 0: // 0xFFFFFFFF
- if (parts[0] > MaxIPv4Value)
- {
- return Invalid;
- }
- return parts[0];
- case 1: // 0xFF.0xFFFFFF
- if (parts[1] > 0xffffff)
- {
- return Invalid;
- }
- return (parts[0] << 24) | (parts[1] & 0xffffff);
- case 2: // 0xFF.0xFF.0xFFFF
- if (parts[2] > 0xffff)
- {
- return Invalid;
- }
- return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | (parts[2] & 0xffff);
- case 3: // 0xFF.0xFF.0xFF.0xFF
- if (parts[3] > 0xff)
- {
- return Invalid;
- }
- return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
- default:
- return Invalid;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement