version 1.58, 2006/11/10 18:14:57
|
version 1.58.4.4, 2008/02/19 22:09:39
|
|
|
#include "XmlWriter.h" | #include "XmlWriter.h" |
#include "XmlReader.h" | #include "XmlReader.h" |
#include "ArrayInternal.h" | #include "ArrayInternal.h" |
|
#include "HostLocator.h" |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
|
| |
static Boolean isValidHostname(const String& hostname) | static Boolean isValidHostname(const String& hostname) |
{ | { |
//------------------------------------------------------------------ |
HostLocator addr(hostname); |
// Validate the hostname. The hostname value may or may not be a |
|
// fully-qualified domain name (e.g., xyz.company.com) or may be an |
|
// IP address. A port number may follow the hostname. |
|
// Hostnames must match one of the following regular expressions: |
|
// ^([A-Za-z0-9][A-Za-z0-9-]*)(\.[A-Za-z][A-Za-z0-9-]*)*(:[0-9]*)?$ |
|
// ^([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)(:[0-9]*)?$ |
|
// Note for Bug#1462. Be careful here, from RFC 1123: |
|
// - The syntax of a legal Internet host name was specified in |
|
// RFC-952 [DNS:4]. One aspect of host name syntax is hereby |
|
// changed: the restriction on the first character is relaxed to |
|
// allow either a letter or a digit. |
|
// - If a dotted-decimal number can be entered without identifying |
|
// delimiters, then a full syntactic check must be made, because |
|
// a segment of a host domain name is now allowed to begin with a |
|
// digit and could legally be entirely numeric (see Section 6.1.2.4). |
|
// However, a valid host name can never have the dotted-decimal form |
|
// #.#.#.#, since at least the highest-level component label will be |
|
// alphabetic. |
|
// The algorithm below has been updated accordingly. |
|
//------------------------------------------------------------------ |
|
| |
Uint32 i = 0; |
return addr.isValid(); |
|
|
Boolean isValid = false; |
|
|
|
if (isascii(hostname[0]) && isdigit(hostname[0])) |
|
{ |
|
//-------------------------------------------------------------- |
|
// Attempt to validate an IP address, but keep in mind that it |
|
// might be a host name, since the leading character can now be |
|
// a digit. |
|
//-------------------------------------------------------------- |
|
isValid = true; |
|
|
|
for (Uint32 octet=1; octet<=4; octet++) |
|
{ |
|
Uint32 octetValue = 0; |
|
|
|
//---------------------------------------------------------- |
|
// If a non-digit is encountered in the input parameter, |
|
// then break from here and attempt to validate as host name. |
|
//---------------------------------------------------------- |
|
if (!(isascii(hostname[i]) && isdigit(hostname[i]))) |
|
{ |
|
isValid = false; |
|
break; |
|
} |
|
|
|
// skip over digits |
|
while (isascii(hostname[i]) && isdigit(hostname[i])) |
|
{ |
|
octetValue = octetValue*10 + (hostname[i] - '0'); |
|
i++; |
|
} |
|
|
|
if (octetValue > 255) |
|
{ |
|
isValid = false; |
|
break; |
|
} |
|
|
|
// Check for invalid character in IP address |
|
if ((octet != 4) && (hostname[i++] != '.')) |
|
{ |
|
isValid = false; |
|
break; |
|
} |
|
|
|
// Check for the case where it's a valid host name that happens |
|
// to have 4 (or more) leading all-numeric host segments. |
|
if ((octet == 4) && (hostname[i] != ':') && |
|
hostname[i] != char(0)) |
|
{ |
|
isValid = false; |
|
break; |
|
} |
|
} |
|
} |
|
if (!isValid) // if it is not a valid IP address |
|
{ |
|
i = 0; // reset index for host name check |
|
|
|
// Validate a host name |
|
isValid = true; |
|
|
|
Boolean expectHostSegment = true; |
|
Boolean hostSegmentIsNumeric; |
|
|
|
while (expectHostSegment == true) |
|
{ |
|
expectHostSegment = false; |
|
hostSegmentIsNumeric = true; // assume all-numeric host segment |
|
|
|
if (!(isascii(hostname[i]) && |
|
(isalnum(hostname[i]) || (hostname[i] == '_')))) |
|
{ |
|
return false; |
|
} |
|
|
|
while (isascii(hostname[i]) && |
|
(isalnum(hostname[i]) || (hostname[i] == '-') || |
|
(hostname[i] == '_'))) |
|
{ |
|
// If a non-digit is encountered, set "all-numeric" |
|
// flag to false |
|
if (isalpha(hostname[i]) || (hostname[i] == '-') || |
|
(hostname[i] == '_')) |
|
{ |
|
hostSegmentIsNumeric = false; |
|
} |
|
i++; |
|
} |
|
|
|
if (hostname[i] == '.') |
|
{ |
|
i++; |
|
expectHostSegment = true; |
|
} |
|
} |
|
// If the last Host Segment is all numeric, then return false. |
|
// RFC 1123 says "highest-level component label will be alphabetic". |
|
if (hostSegmentIsNumeric) |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
if (!isValid) // if not a valid IP address or host name |
|
{ |
|
return false; |
|
} |
|
|
|
// Check for a port number: |
|
|
|
if (hostname[i] == ':') |
|
{ |
|
i++; |
|
if (!(isascii(hostname[i]) && isdigit(hostname[i]))) |
|
{ |
|
return false; |
|
} |
|
i++; |
|
|
|
while (isascii(hostname[i]) && isdigit(hostname[i])) |
|
{ |
|
i++; |
|
} |
|
} |
|
|
|
return (hostname[i] == char(0)); |
|
} | } |
| |
// | // |
|
|
| |
p++; | p++; |
| |
|
Array<Uint8> keyValueUTF8; |
|
keyValueUTF8.reserveCapacity(128); |
|
|
while (*p && *p != '"') | while (*p && *p != '"') |
{ | { |
if (*p == '\\') | if (*p == '\\') |
{ | { |
*p++; |
p++; |
| |
if ((*p != '\\') && (*p != '"')) | if ((*p != '\\') && (*p != '"')) |
{ | { |
|
|
} | } |
} | } |
| |
valueString.append(*p++); |
keyValueUTF8.append(*p++); |
} | } |
| |
if (*p++ != '"') | if (*p++ != '"') |
throw MalformedObjectNameException(objectName); | throw MalformedObjectNameException(objectName); |
| |
|
// Convert the UTF-8 value to a UTF-16 String |
|
|
|
valueString.assign( |
|
(const char*)keyValueUTF8.getData(), |
|
keyValueUTF8.size()); |
|
|
/* | /* |
Guess at the type of this quoted key value. If the value | Guess at the type of this quoted key value. If the value |
can be parsed into a CIMObjectPath with at least one key | can be parsed into a CIMObjectPath with at least one key |
|
|
*/ | */ |
type = CIMKeyBinding::STRING; | type = CIMKeyBinding::STRING; |
| |
|
/* Performance shortcut will check for |
|
equal sign instead of doing the full |
|
CIMObjectPath creation and exception handling |
|
*/ |
|
keyValueUTF8.append('\0'); |
|
if (strchr((const char*)keyValueUTF8.getData(), '=')) |
|
{ |
|
// found an equal sign, high probability for a reference |
try | try |
{ | { |
CIMObjectPath testForPath(valueString); | CIMObjectPath testForPath(valueString); |
|
|
// Not a reference value; leave type as STRING | // Not a reference value; leave type as STRING |
} | } |
} | } |
|
} |
else if (toupper(*p) == 'T' || toupper(*p) == 'F') | else if (toupper(*p) == 'T' || toupper(*p) == 'F') |
{ | { |
type = CIMKeyBinding::BOOLEAN; | type = CIMKeyBinding::BOOLEAN; |