public static byte[] ConvertDataUrlToBinary(string url) { var parser = new Parser(null); Options options = new Options(null); options.CaseSensitive = true; // The main statement list StatementList mainStatements = new StatementList(null); mainStatements.Add(AggregateComparisons.WildcardComparison("data:*/*;base64,", null, options)); // Capture the remaining string var capturing = new Dictionary <string, Capture>(); var capture = new Capture(null); capturing.Add("base64string", capture); mainStatements.Add(capture); capture.Comparison = new AdvanceToTheEnd(null).AsComparisonWithAdvance(); string replaceWith = "'base64string'"; var stateList = new List <State>(); string b64String = parser.Replace(url, replaceWith, mainStatements, capturing, stateList); var binData = Convert.FromBase64String(b64String); return(binData); }
public static IComparisonWithAdvance CreateVBScriptQuotedString( Options options, string name = null, ILog log = null) { // We can use a pattern comparison to do this // First character is a quote // Subsequent characters can either be anything BUT a single ", or double "" but advance 2. // Although it seems un-intuitive this gives us the behaviour we require: skip double quotes. var isQuote = new CharComparison(log, options, '\"'); // This requires more than one statement StatementList statementList = new StatementList(log); statementList.Name = name; // The pattern comparison that will do the work PatternComparison patternComp = new PatternComparison(log, options); statementList.Add(patternComp); patternComp.MinLength = 2; // First character is open quote var first = new ComparisonRange <IComparisonWithAdvance>(); first.Range.Min = 1; first.Range.Max = 1; first.Comparison = isQuote; patternComp.AddComparisonRange(first); // Subsequent characters var subsequent = new ComparisonRange <IComparisonWithAdvance>(); subsequent.Range.Min = 2; OrComparison isNotSingleQuoteOrIsDoubleQuotesAndAdvance2 = new OrComparison(log); var notQuote = new NotCharComparison(log, isQuote); isNotSingleQuoteOrIsDoubleQuotesAndAdvance2.Add(notQuote); var doubleQuote = new StringComparison(log, options, "\"\""); isNotSingleQuoteOrIsDoubleQuotesAndAdvance2.Add(doubleQuote); subsequent.Comparison = isNotSingleQuoteOrIsDoubleQuotesAndAdvance2; patternComp.AddComparisonRange(subsequent); // End when find the terminating " patternComp.EndComparison = isQuote; // Skip the trailing quote by advancing by 1 statementList.Add(new OffsetAdvance(log, 1)); return(statementList); }
internal static void UnitTest() { var parser = new Parser(null); var stmtList = new StatementList(null); var options = new Options(null); options.CaseSensitive = false; stmtList.Add(new StringOffsetComparison( null, options, Operand.CallFunction <int>("ReturnTwo"), Operand.StaticValue(2), true)); int numMatches; Action <RunState> InitRunState = (RunState runState) => { runState.SetFunction <int>("ReturnTwo", (int pos, string str, RunState rs) => 2); }; parser.Extract("abbA", "", stmtList, null, null, out numMatches, null, InitRunState); if (numMatches == 1) { Console.WriteLine("matches (success)"); } else { Console.WriteLine("doesnt match (fail)"); } }
// Convert an operation into a comparison public IComparisonWithAdvance AsComparisonWithAdvance() { var list = new StatementList(Log); list.Add(this); return(list); }
// Get a value between two comparisons public static IComparisonWithAdvance GetValuesBetweenComp( ILog log, IComparisonWithAdvance begin, IComparisonWithAdvance after) { StatementList mainComp = new StatementList(null); // Find the beginning mainComp.Add(begin); // Remember the position mainComp.Add(new StorePosAsVariable(log, "ValueBegin")); // Find the end and store the preceeding position mainComp.Add(new AdvanceUntilComparison(log, new CompareNoAdvance(log, after))); mainComp.Add(new StorePosAsVariable(log, "ValueEnd")); return(mainComp); }
public static void MatchVBScriptFunction_T2(ILog log) { const string input = "ignorethis obj.Func(1)"; const string funcStr = "obj.Func"; var statementList = new StatementList(log); var mainComp = TokenComparison.CreateVBScriptFunctionOrVar(null, null, null, null, log); statementList.Add(new StorePosAsVariable(log, "BeginPos")); statementList.Add(mainComp); Action <RunState> InitRunState = (runState) => { { var funcIndex = input.IndexOf(funcStr); IAssertion sub = new PositionAssertion(true, funcIndex, funcIndex + funcStr.Length); sub.Name = "sub"; runState.AddAssertion("sub", sub); } { var funcIndex = input.IndexOf(funcStr); IAssertion isEndOrArgList = new PositionAssertion( true, funcIndex + funcStr.Length, funcIndex + funcStr.Length + 3 ); isEndOrArgList.Name = "IsEndOrArgumentList"; runState.AddAssertion("IsEndOrArgumentList", isEndOrArgList); } }; Func <RunState, string, int, string> ReplaceFunc = (runState, _input, pos) => { var beginPos = (int)runState.GetVariable("BeginPos"); var str = input.Substring(beginPos, pos - beginPos); return(str); }; var parser = new Parser(log); int numMatches; parser.Extract(input, null, statementList, null, null, out numMatches, ReplaceFunc, InitRunState); System.Diagnostics.Debug.Assert(numMatches == 1); }
public static IComparisonWithAdvance VBScriptLineWrap( ILog log, Options options) { // In VB script you can have the underscore character which signifies wrapping to the next line. // E.g: // Response.Write _ // (test & _ // args) IOperation skipWhitespace = SkipWhitespace(log); StatementList lineWrap = new StatementList(log); lineWrap.Add(skipWhitespace); var isUnderscore = new CharComparison(log, options, '_'); lineWrap.Add(isUnderscore); lineWrap.Add(skipWhitespace); return(lineWrap); }
// This relies on there being the variables 'ValueBegin' and 'ValueEnd' public static string GetSingleValue( string input, Parser parser, IComparisonWithAdvance comp, ILog log) { // Skip to the end var statementList = new StatementList(log); statementList.Add(comp); statementList.Add(new AdvanceToTheEnd(log)); int numAmount; string singleValue = parser.Extract(input, null, statementList, null, null, out numAmount, GetSingleValue_ReplaceFunc); if (numAmount == 1) { return(singleValue); } return(null); }
public static IComparisonWithAdvance HTMLTag( ILog log, Options options, string tagName, OrComparison attributes, string name = null) { ICharComparison isWhitespace = IsWhitespace(log); IOperation skipWhitespace = SkipWhitespace(log); StatementList statementList = new StatementList(log); statementList.Name = name; statementList.Add(new CharComparison(log, options, '<')); statementList.Add(new StringComparison(log, options, tagName)); statementList.Add(isWhitespace); // The reason for the or list is in case the tags appear in a different order on different browsers DelimitedListComparison list = new DelimitedListComparison(log, options, attributes, isWhitespace); statementList.Add(list); list.MinAmount = attributes.Count; list.MaxAmount = attributes.Count; statementList.Add(skipWhitespace); statementList.Add(new CharComparison(log, options, '>')); return(statementList); }
public static IComparisonWithAdvance VBScriptKeywords( ILog log, Options options) { // Need more than one statement to achieve this StatementList statements = new StatementList(log); // Start of the string //// Starts with whitespace or is the start of the input string StartOfInputStringComparison isStartOfString = new StartOfInputStringComparison(log); var isWhitespace = IsWhitespace(log); OrComparison startsWithWhitespaceOrIsStartOfInputString = new OrComparison(log); startsWithWhitespaceOrIsStartOfInputString.Add(isStartOfString); startsWithWhitespaceOrIsStartOfInputString.Add(isWhitespace); statements.Add(startsWithWhitespaceOrIsStartOfInputString); // Trim left - skip whitespace var skipWhitespace = SkipWhitespace(log); statements.Add(skipWhitespace); //// Keywords OrComparison orComp = new OrComparison(log); statements.Add(orComp); for (int i = 0; i < VBKeywords.Length; ++i) { orComp.Add(new StringComparison(log, options, VBKeywords[i])); } // Trim right statements.Add(skipWhitespace); return(statements); }
// E.g. Test123 matches // 1Test123 doesn't (cann't lead with a number) // test"123 doesn't match (can only contain letters and numbers) public static IComparisonWithAdvance CreateIdentifier( Options options, IComparisonWithAdvance end, IComparison exclusion, string name = null, ILog log = null) { StatementList stmtList = new StatementList(log); stmtList.Name = name; PatternComparison patternComp = new PatternComparison(log, options); patternComp.EndComparison = end; patternComp.MinLength = 1; // First character is a letter var firstCharacter = new ComparisonRange <IComparisonWithAdvance>(); firstCharacter.Range.Min = 1; firstCharacter.Range.Max = 1; var isLetter = new CharDelegateComparison(log, Char.IsLetter); firstCharacter.Comparison = isLetter; patternComp.AddComparisonRange(firstCharacter); // Subsequent (2+) characters can be a letter or digit (0-9) var subsequentCharacters = new ComparisonRange <IComparisonWithAdvance>(); subsequentCharacters.Range.Min = 2; var isLetterOrDigit = new CharDelegateComparison(log, Char.IsLetterOrDigit); subsequentCharacters.Comparison = isLetterOrDigit; patternComp.AddComparisonRange(subsequentCharacters); stmtList.Add(patternComp); stmtList.Exclusion = exclusion; return(stmtList); }
public static IComparisonWithAdvance CreateVBScriptSub( Options options, string name = null, ILog log = null) { // This requires more than one statement StatementList statementList = new StatementList(log); statementList.Name = name; // Function end: . , ", or whitespace CharComparison isDot = new CharComparison(log, options, '.'); CharComparison isQuote = new CharComparison(log, options, '\"'); CharDelegateComparison isWhitespace = new CharDelegateComparison(log, Char.IsWhiteSpace); OrComparison funcNameEnd = new OrComparison(log); funcNameEnd.Add(isDot); funcNameEnd.Add(isQuote); funcNameEnd.Add(isWhitespace); // Identifier but not including classes/namespaces var identifier = TokenComparison.CreateIdentifier( options, end: funcNameEnd, exclusion: null, name: null, log: log); // List of identifiers seperated by . which will include classes/namespaces var sub = TokenComparison.CreateListOfTokens( options, token: identifier, segment: isDot, name: null, log: null); statementList.Add(sub); return(statementList); }
public static IComparisonWithAdvance CreateNumber( Options options, IComparisonWithAdvance end, string name = null, ILog log = null) { //// List of 1 or 2 sets of numbers seperated by a . StatementList stmtList = new StatementList(log); stmtList.Name = name; OrComparison isDotOrEnd = new OrComparison(log); isDotOrEnd.Add(end); ICharComparison isDot = new CharComparison(log, options, '.'); isDotOrEnd.Add(isDot); PatternComparison patternComp = new PatternComparison(log, options); patternComp.MinLength = 1; patternComp.EndComparison = isDotOrEnd; // All characters must be between 0 and 9 var allCharacters = new ComparisonRange <IComparisonWithAdvance>(); allCharacters.Range.Min = 1; var isNumber = new CharDelegateComparison(log, Char.IsNumber); allCharacters.Comparison = isNumber; patternComp.AddComparisonRange(allCharacters); // List consisting of 1 or 2 items seperated by . DelimitedListComparison functionName = new DelimitedListComparison(log, options, patternComp, isDot); functionName.MinAmount = 1; functionName.MaxAmount = 2; stmtList.Add(functionName); return(stmtList); }
// E.g. // class.Function _ \r\n (p1, p2, class.Function2( _\r\n p1,p2 ) ) // or // class.FunctionWithNoArgs // or // variableName public static IComparisonWithAdvance CreateVBScriptFunctionOrVar( Options options, IComparisonWithAdvance vbScriptConcatCommaOrWhitespaceOrEnd, IComparison vbScriptKeywords, string name = null, ILog log = null) { if (options == null) { options = CreateVBScriptParserOptions(log); } if (vbScriptConcatCommaOrWhitespaceOrEnd == null) { vbScriptConcatCommaOrWhitespaceOrEnd = CreateVBScriptConcatCommaOrWhitespaceOrEnd(log); } if (vbScriptKeywords == null) { vbScriptKeywords = TokenComparison.VBScriptKeywords(log, options); } if (options.SkipLineWrapOperation == null) { Parser.ThrowParseError("The line wrap comparison has not been specified. This is mandatory."); } // This requires more than one statement StatementList statementList = new StatementList(log); statementList.Name = name; // Function CharComparison isDot = new CharComparison(log, options, '.'); OrComparison isDotOrParenOrEnd = new OrComparison(log); isDotOrParenOrEnd.Add(isDot); isDotOrParenOrEnd.Add(vbScriptConcatCommaOrWhitespaceOrEnd); CharComparison openParen = new CharComparison(log, options, '('); isDotOrParenOrEnd.Add(openParen); var identifier = TokenComparison.CreateIdentifier( options, end: isDotOrParenOrEnd, exclusion: vbScriptKeywords, name: "identifier", log: log); // List of identifiers seperated by . which will include classes/namespaces var sub = TokenComparison.CreateListOfTokens( options, token: identifier, segment: isDot, name: "sub", log: log); statementList.Add(sub); // Skip whitespace { var skip = SkipWhitespace(log); skip.Name = "SkipWhitespace1"; statementList.Add(skip); } // Skip the line wrap character statementList.Add(options.SkipLineWrapOperation); // Function parenthesis and arguments CharComparison close = new CharComparison(log, options, ')'); // Either the end (and don't advance past it), or function argument list OrComparison isEndOrArgumentList = new OrComparison(log); isEndOrArgumentList.Name = "IsEndOrArgumentList"; isEndOrArgumentList.Add(new CompareNoAdvance(log, vbScriptConcatCommaOrWhitespaceOrEnd)); isEndOrArgumentList.Add(new NestedOpenCloseComparison(log, openParen, close)); statementList.Add(isEndOrArgumentList); return(statementList); }
//TODO: this doesn't work! //TODO: this only understands '*' at the moment. '?' would be useful public static IComparisonWithAdvance WildcardComparison( string wildcardStr, ILog log, Options options) { // The list of parser statements StatementList mainStatements = new StatementList(log); // Length of the input string var len = wildcardStr.Length; // The current fixed string that we are building up var currentString = new StringBuilder(); // Add the current string as a string comparison Action ConditionalAddCurrentString = () => { if (currentString.Length > 0) { mainStatements.Add(new StringComparison(log, options, currentString.ToString(), null)); currentString.Clear(); } }; for (int i = 0; i < len; ++i) { var chr = wildcardStr[i]; // * means match all if (chr == '*') { // Escape an asterix? if (++i < len) { var nextChar = wildcardStr[i]; if (nextChar == '*') { currentString.Append('*'); } else { // Match the string so far ConditionalAddCurrentString(); // Skip till we find the next character in the sequence (nextChr) mainStatements.Add(new AdvanceUntilComparison(log, new CharComparison(log, options, nextChar))); } } else { // We've reached the end of the wild character string and the last character is an asterix // All we can do in this case is advance until the end of the string // You wouldn't really use this if you had additional comparisons after this, because it wouldn't // work as expected (it wouldn't match because after this you would be at the end of the string) //sidtodo not tested mainStatements.Add(new AdvanceToTheEnd(log)); } } else { currentString.Append(chr); } } ConditionalAddCurrentString(); return(mainStatements); }
// From "response.write blah" // To "response.write(blah)" public static string AddParenthesisToFunctionCalls( ILog log, string input, out int numMatches, Action <Action <string, IAssertion> > fCreateAssertList = null) { // The parser object that will do the work Parser parser = new Parser(log); //// Parser options // This create a special line wrap Options parserOptions = TokenComparison.CreateVBScriptParserOptions(log); CharDelegateComparison isWhitespace = new CharDelegateComparison(log, Char.IsWhiteSpace); IOperation skipWhitespace = TokenComparison.SkipWhitespace(log); // State List <State> stateList = VBScriptState(log, parserOptions); // The main statement list StatementList mainStatements = new StatementList(log); // Capturing Dictionary <string, Capture> capturing = new Dictionary <string, Capture>(); // Function name capture Capture funcNameCapture = new Capture(log); funcNameCapture.Name = "FunctionName"; capturing.Add("funcName", funcNameCapture); mainStatements.Add(funcNameCapture); // Function name capture statements var vbScriptKeywords = TokenComparison.VBScriptKeywords(log, parserOptions); StatementList funcNameCaptureStatements = new StatementList(log); funcNameCapture.Comparison = funcNameCaptureStatements; funcNameCaptureStatements.Exclusion = vbScriptKeywords; //// Starts with whitespace or is the start of the input string StartOfInputStringComparison isStartOfString = new StartOfInputStringComparison(log); OrComparison startsWithWhitespaceOrIsStartOfInputString = new OrComparison(log); startsWithWhitespaceOrIsStartOfInputString.Add(isStartOfString); startsWithWhitespaceOrIsStartOfInputString.Add(isWhitespace); funcNameCaptureStatements.Add(startsWithWhitespaceOrIsStartOfInputString); // Skip whitespace funcNameCaptureStatements.Add(skipWhitespace); //// Function/sub name. //// For example: class1.Func or class1.Func"string arg" funcNameCaptureStatements.Add(TokenComparison.CreateVBScriptSub(parserOptions, name: null, log: log)); //// Arguments list // Skip whitespace and don't capture it mainStatements.Add(skipWhitespace); // Capture Capture argListCapture = new Capture(log); capturing.Add("funcArgs", argListCapture); mainStatements.Add(argListCapture); // Function argument list capture statements StatementList argListCaptureStatements = new StatementList(log); argListCapture.Comparison = argListCaptureStatements; // Skip the line wrap (and capture it) argListCaptureStatements.Add(parserOptions.SkipLineWrapOperation); // Concatenated single arguments // Delimited by whitespace, comma & or + var vbScriptConcatCommaOrWhitespaceOrEnd = TokenComparison.CreateVBScriptConcatCommaOrWhitespaceOrEnd(log, parserOptions); // Numbers var numberComparison = TokenComparison.CreateNumber(parserOptions, vbScriptConcatCommaOrWhitespaceOrEnd, "ArgsNumber", log: log); // VB script quoted strings var quotedText = TokenComparison.CreateVBScriptQuotedString(parserOptions, name: "Args quoted text", log: log); // VB script function which could include arguments, or a variable name var VbScriptFunctionOrVar = TokenComparison.CreateVBScriptFunctionOrVar( parserOptions, vbScriptConcatCommaOrWhitespaceOrEnd, vbScriptKeywords, "VbScriptFunctionOrVar", log: log); // Individual arguments // Types OrComparison individualArgumentTypes = new OrComparison(log); individualArgumentTypes.Add(numberComparison); individualArgumentTypes.Add(quotedText); individualArgumentTypes.Add(VbScriptFunctionOrVar); // List delimiter for the individual arguments OrComparison vbScriptConcactOrComma = new OrComparison(log); { var matchAmpersand = new CharComparison(log, parserOptions, '&'); matchAmpersand.Name = "ArgsStringConcatenation"; vbScriptConcactOrComma.Add(matchAmpersand); } vbScriptConcactOrComma.Add(new CharComparison(log, parserOptions, '+')); var isComma = new CharComparison(log, parserOptions, ','); vbScriptConcactOrComma.Add(isComma); DelimitedListComparison individualArgumentList = new DelimitedListComparison( log, parserOptions, individualArgumentTypes, seperator: vbScriptConcactOrComma ); individualArgumentList.MinAmount = 1; individualArgumentList.ItemTrim = skipWhitespace; // The argument list - comma seperated list of function arguments DelimitedListComparison argumentList = new DelimitedListComparison( log, parserOptions, individualArgumentList, seperator: isComma ); argumentList.Name = "ArgumentList"; argumentList.MinAmount = 1; argumentList.ItemTrim = skipWhitespace; argListCaptureStatements.Add(argumentList); Action <RunState> InitRunState = null; if (fCreateAssertList != null) { InitRunState = (runState) => { fCreateAssertList(runState.AddAssertion); }; } const string replaceWith = "'funcName'('funcArgs')"; string replaced = parser.Replace( input, replaceWith, mainStatements, capturing, stateList, out numMatches, null, InitRunState ); return(replaced); }
//TODO this is not fully tested. needs a new feature to allow repeats // - "repeated comparison" // - also doesn't work inside quotes. needs a state // I think state ment list should have a state member // <script ..>function blah end function </script> public static string WrapFunctionsInScriptBlock( ILog log, string input) { // The parser object that will do the work Parser parser = new Parser(log); //// Parser options Options parserOptions = new Options(log); parserOptions.CaseSensitive = false; // Line wrap parserOptions.LineWrap = TokenComparison.VBScriptLineWrap( log, parserOptions); // State List <State> stateList = VBScriptState(log, parserOptions); // The main statement list StatementList mainStatements = new StatementList(log); // Begins with whitespace (don't capture the space) CharDelegateComparison isWhitespace = new CharDelegateComparison(log, Char.IsWhiteSpace); mainStatements.Add(isWhitespace); // Skip whitespace (don't capture the space) mainStatements.Add(TokenComparison.SkipWhitespace(log)); // Capturing Dictionary <string, Capture> capturing = new Dictionary <string, Capture>(); // The capture Capture capture = new Capture(log); capture.Name = "capture"; capturing.Add("functionDefinition", capture); mainStatements.Add(capture); // Capture statements StatementList captureStatements = new StatementList(log); capture.Comparison = captureStatements; // Function or sub OrComparison functionOrSub = new OrComparison(log); functionOrSub.Add(new StringComparison(log, parserOptions, "function")); functionOrSub.Add(new StringComparison(log, parserOptions, "sub")); captureStatements.Add(functionOrSub); // Whitespace captureStatements.Add(isWhitespace); // Line wrap captureStatements.Add(parserOptions.SkipLineWrapOperation); //// Name of function/sub // End is either whitespace or ( OrComparison whiteSpaceOrOpenParen = new OrComparison(log); whiteSpaceOrOpenParen.Add(isWhitespace); whiteSpaceOrOpenParen.Add(new CharComparison(log, parserOptions, '(')); var funcName = TokenComparison.CreateIdentifier( parserOptions, end: whiteSpaceOrOpenParen, exclusion: null, name: null, log: log); captureStatements.Add(funcName); //// Find the end of the sub/function StatementList functionEnd = new StatementList(log); // Whitespace functionEnd.Add(isWhitespace); // 'end' functionEnd.Add(new StringComparison(log, parserOptions, "end")); // Whitespace functionEnd.Add(isWhitespace); // Skip the line wrap functionEnd.Add(parserOptions.SkipLineWrapOperation); // Function or sub functionEnd.Add(functionOrSub); // Whitespace or %> OrComparison whitespaceOrPageDirective = new OrComparison(log); whitespaceOrPageDirective.Add(isWhitespace); whitespaceOrPageDirective.Add(new CompareNoAdvance(log, new StringComparison(log, parserOptions, "%>"))); functionEnd.Add(whitespaceOrPageDirective); // Skip till find the function name captureStatements.Add(new AdvanceUntilComparison(log, functionEnd)); //const string replaceWith = "'funcName'('funcArgs')"; string replaceWith = string.Format( "{0}<script language=\"VB\" runat=\"Server\">{0}'functionDefinition'{0}</script>{0}", Environment.NewLine); string replaced = parser.Replace(input, replaceWith, mainStatements, capturing, stateList); return(replaced); }