private static Hashtable SplitConnectionString(string connectionString, Hashtable synonyms) { var parsetable = new Hashtable(); var parser = _connectionStringRegex; const int KeyIndex = 1, ValueIndex = 2; Debug.Assert(KeyIndex == parser.GroupNumberFromName("key"), "wrong key index"); Debug.Assert(ValueIndex == parser.GroupNumberFromName("value"), "wrong value index"); if (null != connectionString) { var match = parser.Match(connectionString); if (!match.Success || (match.Length != connectionString.Length)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(match.Length)); } var indexValue = 0; var keyvalues = match.Groups[ValueIndex].Captures; foreach (Capture keypair in match.Groups[KeyIndex].Captures) { var keyname = keypair.Value.Replace("==", "=").ToLowerInvariant(); var keyvalue = keyvalues[indexValue++].Value; if (0 < keyvalue.Length) { switch (keyvalue[0]) { case '\"': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\"\"", "\""); break; case '\'': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\'\'", "\'"); break; default: break; } } else { keyvalue = null; } var realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); if (!IsKeyNameValid(realkeyname)) { throw new ArgumentException(Strings.ADP_KeywordNotSupported(keyname)); } parsetable[realkeyname] = keyvalue; // last key-value pair wins (or first) } } return(parsetable); }
private static int GetKeyValuePair( string connectionString, int currentPosition, StringBuilder buffer, out string keyname, out string keyvalue) { var startposition = currentPosition; buffer.Length = 0; keyname = null; keyvalue = null; var currentChar = '\0'; var parserState = ParserState.NothingYet; var length = connectionString.Length; for (; currentPosition < length; ++currentPosition) { currentChar = connectionString[currentPosition]; switch (parserState) { case ParserState.NothingYet: // [\\s;]* if ((';' == currentChar) || Char.IsWhiteSpace(currentChar)) { continue; } if ('\0' == currentChar) { parserState = ParserState.NullTermination; continue; } if (Char.IsControl(currentChar)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } startposition = currentPosition; if ('=' != currentChar) { parserState = ParserState.Key; break; } else { parserState = ParserState.KeyEqual; continue; } case ParserState.Key: // (?<key>([^=\\s\\p{Cc}]|\\s+[^=\\s\\p{Cc}]|\\s+==|==)+) if ('=' == currentChar) { parserState = ParserState.KeyEqual; continue; } if (Char.IsWhiteSpace(currentChar)) { break; } if (Char.IsControl(currentChar)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } break; case ParserState.KeyEqual: // \\s*=(?!=)\\s* if ('=' == currentChar) { parserState = ParserState.Key; break; } keyname = GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } buffer.Length = 0; parserState = ParserState.KeyEnd; goto case ParserState.KeyEnd; case ParserState.KeyEnd: if (Char.IsWhiteSpace(currentChar)) { continue; } if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValue; continue; } if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValue; continue; } if (';' == currentChar) { goto ParserExit; } if ('\0' == currentChar) { goto ParserExit; } if (Char.IsControl(currentChar)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } parserState = ParserState.UnquotedValue; break; case ParserState.UnquotedValue: // "((?![\"'\\s])" + "([^;\\s\\p{Cc}]|\\s+[^;\\s\\p{Cc}])*" + "(?<![\"']))" if (Char.IsWhiteSpace(currentChar)) { break; } if (Char.IsControl(currentChar) || ';' == currentChar) { goto ParserExit; } break; case ParserState.DoubleQuoteValue: // "(\"([^\"\u0000]|\"\")*\")" if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValueQuote; continue; } if ('\0' == currentChar) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } break; case ParserState.DoubleQuoteValueQuote: if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValue; break; } keyvalue = GetKeyValue(buffer, false); parserState = ParserState.QuotedValueEnd; goto case ParserState.QuotedValueEnd; case ParserState.SingleQuoteValue: // "('([^'\u0000]|'')*')" if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValueQuote; continue; } if ('\0' == currentChar) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } break; case ParserState.SingleQuoteValueQuote: if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValue; break; } keyvalue = GetKeyValue(buffer, false); parserState = ParserState.QuotedValueEnd; goto case ParserState.QuotedValueEnd; case ParserState.QuotedValueEnd: if (Char.IsWhiteSpace(currentChar)) { continue; } if (';' == currentChar) { goto ParserExit; } if ('\0' == currentChar) { parserState = ParserState.NullTermination; continue; } throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); // unbalanced single quote case ParserState.NullTermination: // [\\s;\u0000]* if ('\0' == currentChar) { continue; } if (Char.IsWhiteSpace(currentChar)) { continue; } throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(currentPosition)); default: throw new InvalidOperationException( Strings.ADP_InternalProviderError((int)EntityUtil.InternalErrorCode.InvalidParserState1)); } buffer.Append(currentChar); } ParserExit: switch (parserState) { case ParserState.Key: case ParserState.DoubleQuoteValue: case ParserState.SingleQuoteValue: // keyword not found/unbalanced double/single quote throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); case ParserState.KeyEqual: // equal sign at end of line keyname = GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); } break; case ParserState.UnquotedValue: // unquoted value at end of line keyvalue = GetKeyValue(buffer, true); var tmpChar = keyvalue[keyvalue.Length - 1]; if (('\'' == tmpChar) || ('"' == tmpChar)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax(startposition)); // unquoted value must not end in quote } break; case ParserState.DoubleQuoteValueQuote: case ParserState.SingleQuoteValueQuote: case ParserState.QuotedValueEnd: // quoted value at end of line keyvalue = GetKeyValue(buffer, false); break; case ParserState.NothingYet: case ParserState.KeyEnd: case ParserState.NullTermination: // do nothing break; default: throw new InvalidOperationException( Strings.ADP_InternalProviderError((int)EntityUtil.InternalErrorCode.InvalidParserState2)); } if ((';' == currentChar) && (currentPosition < connectionString.Length)) { currentPosition++; } return(currentPosition); }
private static int GetKeyValuePair( string connectionString, int currentPosition, StringBuilder buffer, out string keyname, out string keyvalue) { int num = currentPosition; buffer.Length = 0; keyname = (string)null; keyvalue = (string)null; char minValue = char.MinValue; DbConnectionOptions.ParserState parserState = DbConnectionOptions.ParserState.NothingYet; for (int length = connectionString.Length; currentPosition < length; ++currentPosition) { minValue = connectionString[currentPosition]; switch (parserState) { case DbConnectionOptions.ParserState.NothingYet: if (';' != minValue && !char.IsWhiteSpace(minValue)) { if (minValue == char.MinValue) { parserState = DbConnectionOptions.ParserState.NullTermination; continue; } if (char.IsControl(minValue)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } num = currentPosition; if ('=' != minValue) { parserState = DbConnectionOptions.ParserState.Key; break; } parserState = DbConnectionOptions.ParserState.KeyEqual; continue; } continue; case DbConnectionOptions.ParserState.Key: if ('=' == minValue) { parserState = DbConnectionOptions.ParserState.KeyEqual; continue; } if (!char.IsWhiteSpace(minValue) && char.IsControl(minValue)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } break; case DbConnectionOptions.ParserState.KeyEqual: if ('=' == minValue) { parserState = DbConnectionOptions.ParserState.Key; break; } keyname = DbConnectionOptions.GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } buffer.Length = 0; parserState = DbConnectionOptions.ParserState.KeyEnd; goto case DbConnectionOptions.ParserState.KeyEnd; case DbConnectionOptions.ParserState.KeyEnd: if (!char.IsWhiteSpace(minValue)) { if ('\'' == minValue) { parserState = DbConnectionOptions.ParserState.SingleQuoteValue; continue; } if ('"' == minValue) { parserState = DbConnectionOptions.ParserState.DoubleQuoteValue; continue; } if (';' != minValue && minValue != char.MinValue) { if (char.IsControl(minValue)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } parserState = DbConnectionOptions.ParserState.UnquotedValue; break; } goto label_54; } else { continue; } case DbConnectionOptions.ParserState.UnquotedValue: if (char.IsWhiteSpace(minValue) || !char.IsControl(minValue) && ';' != minValue) { break; } goto label_54; case DbConnectionOptions.ParserState.DoubleQuoteValue: if ('"' == minValue) { parserState = DbConnectionOptions.ParserState.DoubleQuoteValueQuote; continue; } if (minValue == char.MinValue) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } break; case DbConnectionOptions.ParserState.DoubleQuoteValueQuote: if ('"' == minValue) { parserState = DbConnectionOptions.ParserState.DoubleQuoteValue; break; } keyvalue = DbConnectionOptions.GetKeyValue(buffer, false); parserState = DbConnectionOptions.ParserState.QuotedValueEnd; goto case DbConnectionOptions.ParserState.QuotedValueEnd; case DbConnectionOptions.ParserState.SingleQuoteValue: if ('\'' == minValue) { parserState = DbConnectionOptions.ParserState.SingleQuoteValueQuote; continue; } if (minValue == char.MinValue) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } break; case DbConnectionOptions.ParserState.SingleQuoteValueQuote: if ('\'' == minValue) { parserState = DbConnectionOptions.ParserState.SingleQuoteValue; break; } keyvalue = DbConnectionOptions.GetKeyValue(buffer, false); parserState = DbConnectionOptions.ParserState.QuotedValueEnd; goto case DbConnectionOptions.ParserState.QuotedValueEnd; case DbConnectionOptions.ParserState.QuotedValueEnd: if (!char.IsWhiteSpace(minValue)) { if (';' != minValue) { if (minValue != char.MinValue) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } parserState = DbConnectionOptions.ParserState.NullTermination; continue; } goto label_54; } else { continue; } case DbConnectionOptions.ParserState.NullTermination: if (minValue != char.MinValue && !char.IsWhiteSpace(minValue)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)currentPosition)); } continue; default: throw new InvalidOperationException(Strings.ADP_InternalProviderError((object)1015)); } buffer.Append(minValue); } label_54: switch (parserState) { case DbConnectionOptions.ParserState.NothingYet: case DbConnectionOptions.ParserState.KeyEnd: case DbConnectionOptions.ParserState.NullTermination: if (';' == minValue && currentPosition < connectionString.Length) { ++currentPosition; } return(currentPosition); case DbConnectionOptions.ParserState.Key: case DbConnectionOptions.ParserState.DoubleQuoteValue: case DbConnectionOptions.ParserState.SingleQuoteValue: throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); case DbConnectionOptions.ParserState.KeyEqual: keyname = DbConnectionOptions.GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } goto case DbConnectionOptions.ParserState.NothingYet; case DbConnectionOptions.ParserState.UnquotedValue: keyvalue = DbConnectionOptions.GetKeyValue(buffer, true); char ch = keyvalue[keyvalue.Length - 1]; if ('\'' == ch || '"' == ch) { throw new ArgumentException(Strings.ADP_ConnectionStringSyntax((object)num)); } goto case DbConnectionOptions.ParserState.NothingYet; case DbConnectionOptions.ParserState.DoubleQuoteValueQuote: case DbConnectionOptions.ParserState.SingleQuoteValueQuote: case DbConnectionOptions.ParserState.QuotedValueEnd: keyvalue = DbConnectionOptions.GetKeyValue(buffer, false); goto case DbConnectionOptions.ParserState.NothingYet; default: throw new InvalidOperationException(Strings.ADP_InternalProviderError((object)1016)); } }