From 202a0916a393f8e865e41e9b41e0a006b8ab2b75 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 23 Jun 2022 09:03:16 -0700 Subject: [PATCH 001/203] IdentityModel_tokenvalidation --- .../JsonWebTokenHandlerLib.qll | 263 ++++++++++++++++++ ...rity-validations-always-return-true-bad.cs | 10 + ...ity-validations-always-return-true-good.cs | 17 ++ ...urity-validations-always-return-true.qhelp | 28 ++ ...security-validations-always-return-true.ql | 24 ++ .../security-validation-disabled-bad.cs | 13 + .../security-validation-disabled-good.cs | 13 + .../security-validation-disabled.qhelp | 27 ++ .../security-validation-disabled.ql | 24 ++ ...ty-validations-always-return-true.expected | 2 + ...urity-validations-always-return-true.qlref | 1 + .../JsonWebTokenHandler/delegation-test.cs | 115 ++++++++ .../security-validation-disabled-test.cs | 43 +++ .../security-validation-disabled.expected | 4 + .../security-validation-disabled.qlref | 1 + .../JsonWebTokenHandler/stubs.cs | 115 ++++++++ 16 files changed, 700 insertions(+) create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp create mode 100644 csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref create mode 100644 csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll new file mode 100644 index 00000000000..b2f3a2fab16 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -0,0 +1,263 @@ +import csharp +import DataFlow + +/** + * Abstract PropertyWrite for `TokenValidationParameters`. + * Not really necessary anymore, but keeping it in case we want to extend the queries to check on other properties. + */ +abstract class TokenValidationParametersPropertyWrite extends PropertyWrite { } + +/** + * An access to a sensitive property for `TokenValidationParameters` that updates the underlying value. + */ +class TokenValidationParametersPropertyWriteToBypassSensitiveValidation extends TokenValidationParametersPropertyWrite { + TokenValidationParametersPropertyWriteToBypassSensitiveValidation() { + exists(Property p, Class c | + c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") + | + p.getAnAccess() = this and + c.getAProperty() = p and + p.getName() in [ + "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime" + ] + ) + } +} + +/** + * Dataflow from a `false` value to an to a write sensitive property for `TokenValidationParameters`. + */ +class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation extends TaintTracking::Configuration { + FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation() { + this = "FlowsToTokenValidationResultIsValidCall" + } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(BoolLiteral).getValue() = "false" + } + + override predicate isSink(DataFlow::Node sink) { + exists(TokenValidationParametersPropertyWrite pw, Assignment a | a.getLValue() = pw | + sink.asExpr() = a.getRValue() + ) + } +} + +/** + * Holds if `assemblyName` is older than version `ver` + */ +bindingset[ver] +predicate isAssemblyOlderVersion(string assemblyName, string ver) { + exists(Assembly a | + a.getName() = assemblyName and + a.getVersion().isEarlierThan(ver) + ) +} + +/** + * Method `ValidateToken` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler` or other Token handler that shares the same behavior characteristics + */ +class JsonWebTokenHandlerValidateTokenMethod extends Method { + JsonWebTokenHandlerValidateTokenMethod() { + this.hasQualifiedName("Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken") or + this.hasQualifiedName("Microsoft.AzureAD.DeviceIdentification.Common.Tokens.JwtValidator.ValidateEncryptedToken") + //// TODO: ValidateEncryptedToken has the same behavior than ValidateToken, but it will be changed in a future release + //// The line below would allow to check if the ValidateEncryptedToken version used meets the minimum requirement + //// Once we have the fixed assembly version we can uncomment the line below + // and isAssemblyOlderVersion("Microsoft.AzureAD.DeviceIdentification", "0.0.0") + } +} + +/** + * A Call to `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` + */ +class JsonWebTokenHandlerValidateTokenCall extends MethodCall { + JsonWebTokenHandlerValidateTokenCall() { + exists(JsonWebTokenHandlerValidateTokenMethod m | m.getACall() = this) + } +} + +/** + * Read access for properties `IsValid` or `Exception` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` + */ +class TokenValidationResultIsValidCall extends PropertyRead { + TokenValidationResultIsValidCall() { + exists(Property p | p.getAnAccess().(PropertyRead) = this | + p.hasName("IsValid") or + p.hasName("Exception") + ) + } +} + +/** + * Dataflow from the output of `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` call to access the `IsValid` or `Exception` property + */ +private class FlowsToTokenValidationResultIsValidCall extends TaintTracking::Configuration { + FlowsToTokenValidationResultIsValidCall() { this = "FlowsToTokenValidationResultIsValidCall" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof JsonWebTokenHandlerValidateTokenCall + } + + override predicate isSink(DataFlow::Node sink) { + exists(TokenValidationResultIsValidCall call | sink.asExpr() = call.getQualifier()) + } +} + +/** + * Holds if the call to `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` flows to any `IsValid` or `Exception` property access + */ +predicate hasAFlowToTokenValidationResultIsValidCall(JsonWebTokenHandlerValidateTokenCall call) { + exists(FlowsToTokenValidationResultIsValidCall config, DataFlow::Node source | + call = source.asExpr() + | + config.hasFlow(source, _) + ) +} + +/** + * Property write for security-sensitive properties for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` + */ +class TokenValidationParametersPropertyWriteToValidationDelegated extends PropertyWrite { + TokenValidationParametersPropertyWriteToValidationDelegated() { + exists(Property p, Class c | + c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") + | + p.getAnAccess() = this and + c.getAProperty() = p and + p.getName() in [ + "SignatureValidator", "TokenReplayValidator", "AlgorithmValidator", "AudienceValidator", + "IssuerSigningKeyValidator", "LifetimeValidator" + ] + ) + } +} + +/** + * Holds if the callable has a return statement and it always returns true for all such statements + */ +predicate callableHasARetrunStmtAndAlwaysReturnsTrue(Callable c) { + c.getReturnType().toString() = "Boolean" and + forall(ReturnStmt rs | rs.getEnclosingCallable() = c | + rs.getChildExpr(0).(BoolLiteral).getBoolValue() = true + ) and + exists(ReturnStmt rs | rs.getEnclosingCallable() = c) +} + +/** + * Holds if the lambda expression `le` always returns true + */ +predicate lambdaExprReturnsOnlyLiteralTrue(LambdaExpr le) { + le.getExpressionBody().(BoolLiteral).getBoolValue() = true +} + +class CallableAlwaysReturnsTrue extends Callable { + CallableAlwaysReturnsTrue() { + callableHasARetrunStmtAndAlwaysReturnsTrue(this) + or + lambdaExprReturnsOnlyLiteralTrue(this) + or + exists(LambdaExpr le, Call call, CallableAlwaysReturnsTrue cat | this = le | + call = le.getExpressionBody() and + cat.getACall() = call + ) + } +} + +/** + * Holds if any exception being thrown by the callable is of type `System.ArgumentNullException` + * It will also hold if no exceptions are thrown by the callable + */ +predicate callableOnlyThrowsArgumentNullException(Callable c) { + forall(ThrowElement thre | c = thre.getEnclosingCallable() | + thre.getThrownExceptionType().hasQualifiedName("System.ArgumentNullException") + ) +} + +/** + * A specialization of `CallableAlwaysReturnsTrue` that takes into consideration exceptions being thrown for higher precision. + */ +class CallableAlwaysReturnsTrueHigherPrecision extends CallableAlwaysReturnsTrue { + CallableAlwaysReturnsTrueHigherPrecision() { + callableOnlyThrowsArgumentNullException(this) and + ( + forall(Call call, Callable callable | call.getEnclosingCallable() = this | + callable.getACall() = call and + callable instanceof CallableAlwaysReturnsTrueHigherPrecision + ) + or + exists(LambdaExpr le, Call call, CallableAlwaysReturnsTrueHigherPrecision cat | this = le | + call = le.getExpressionBody() and + cat.getACall() = call + ) + ) + } +} + +/** + * Property Write for the `IssuerValidator` property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` + */ +class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator extends PropertyWrite { + TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator() { + exists(Property p, Class c | + c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") + | + p.getAnAccess() = this and + c.getAProperty() = p and + p.getName() in ["IssuerValidator"] + ) + } +} + +/** + * A callable that returns a `string` and has a `string` as 1st argument + */ +private class CallableReturnsStringAndArg0IsString extends Callable { + CallableReturnsStringAndArg0IsString() { + this.getReturnType().toString() = "String" and + this.getParameter(0).getType().toString() = "String" + } +} + +/** + * A Callable that always retrun the 1st argument, both of `string` type + */ +class CallableAlwatsReturnsParameter0 extends CallableReturnsStringAndArg0IsString { + CallableAlwatsReturnsParameter0() { + forall(ReturnStmt rs | rs.getEnclosingCallable() = this | + rs.getChild(0) = this.getParameter(0).getAnAccess() + ) and + exists(ReturnStmt rs | rs.getEnclosingCallable() = this) + or + exists(LambdaExpr le, Call call, CallableAlwatsReturnsParameter0 cat | this = le | + call = le.getExpressionBody() and + cat.getACall() = call + ) + or + this.getBody() = this.getParameter(0).getAnAccess() + } +} + +/** + * A Callable that always retrun the 1st argument, both of `string` type. Higher precision + */ +class CallableAlwatsReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString { + CallableAlwatsReturnsParameter0MayThrowExceptions() { + callableOnlyThrowsArgumentNullException(this) and + forall(ReturnStmt rs | rs.getEnclosingCallable() = this | + rs.getChild(0) = this.getParameter(0).getAnAccess() + ) and + exists(ReturnStmt rs | rs.getEnclosingCallable() = this) + or + exists(LambdaExpr le, Call call, CallableAlwatsReturnsParameter0MayThrowExceptions cat | + this = le + | + call = le.getExpressionBody() and + cat.getACall() = call and + callableOnlyThrowsArgumentNullException(le) and + callableOnlyThrowsArgumentNullException(cat) + ) + or + this.getBody() = this.getParameter(0).getAnAccess() + } +} diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs new file mode 100644 index 00000000000..2eda6821019 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs @@ -0,0 +1,10 @@ +using System; +using Microsoft.IdentityModel.Tokens; +class TestClass +{ + public void TestMethod() + { + TokenValidationParameters parameters = new TokenValidationParameters(); + parameters.AudienceValidator = (audiences, token, tvp) => { return true; }; + } +} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs new file mode 100644 index 00000000000..28ba1d6f94e --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.IdentityModel.Tokens; +class TestClass +{ + public void TestMethod() + { + TokenValidationParameters parameters = new TokenValidationParameters(); + parameters.AudienceValidator = (audiences, token, tvp) => + { + // Implement your own custom audience validation + if (PerformCustomAudienceValidation(audiences, token)) + return true; + else + return false; + }; + } +} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp new file mode 100644 index 00000000000..8c4f8dff229 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp @@ -0,0 +1,28 @@ + + + +

By setting critical TokenValidationParameter validation delegates to always return true, important authentication safeguards are disabled. Disabling safeguards can lead to incorrect validation of tokens from any issuer or expired tokens.

+ +
+ +

Improve the logic of the delegate so not all code paths return true, which effectively disables that type of validation; or throw SecurityTokenInvalidAudienceException or SecurityTokenInvalidLifetimeException in failure cases when you want to fail validation and have other cases pass by returning true. +

+
+ + +

This example delegates AudienceValidator to a callable that always returns true.

+ + +

To fix it, use a callable that performs a validation, and fails when appropriate.

+ + +
+ + + +
  • azure-activedirectory-identitymodel-extensions-for-dotnet ValidatingTokens wiki
  • + +
    +
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql new file mode 100644 index 00000000000..a9df54378f3 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -0,0 +1,24 @@ +/** + * @name Delegated security sensitive validations for JsonWebTokenHandler always return true, medium precision + * @description Security sensitive validations for `JsonWebTokenHandler` are being delegated to a function that seems to always return true. + * Higher precision version checks for exception throws, so less false positives are expected. + * @kind problem + * @tags security + * JsonWebTokenHandler + * manual-verification-required + * @id cs/JsonWebTokenHandler/delegated-security-validations-always-return-true + * @problem.severity warning + * @precision high + */ + +import csharp +import DataFlow +import JsonWebTokenHandlerLib + +from + TokenValidationParametersPropertyWriteToValidationDelegated tv, Assignment a, + CallableAlwaysReturnsTrueHigherPrecision e +where a.getLValue() = tv and a.getRValue().getAChild*() = e +select tv, + "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", + tv, tv.getTarget().toString(), e, "a callable that always returns \"true\"" diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs new file mode 100644 index 00000000000..81df44fea9a --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs @@ -0,0 +1,13 @@ +using System; +using Microsoft.IdentityModel.Tokens; +class TestClass +{ + public void TestMethod() + { + TokenValidationParameters parameters = new TokenValidationParameters(); + parameters.RequireExpirationTime = false; + parameters.ValidateAudience = false; + parameters.ValidateIssuer = false; + parameters.ValidateLifetime = false; + } +} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs new file mode 100644 index 00000000000..e2f74c0653d --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs @@ -0,0 +1,13 @@ +using System; +using Microsoft.IdentityModel.Tokens; +class TestClass +{ + public void TestMethod() + { + TokenValidationParameters parameters = new TokenValidationParameters(); + parameters.RequireExpirationTime = true; + parameters.ValidateAudience = true; + parameters.ValidateIssuer = true; + parameters.ValidateLifetime = true; + } +} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp new file mode 100644 index 00000000000..5c027ac3148 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp @@ -0,0 +1,27 @@ + + + +

    Token validation checks ensure that while validating tokens, all aspects are analyzed and verified. Turning off validation can lead to security holes by allowing untrusted tokens to make it through validation.

    + +
    + +

    Set Microsoft.IdentityModel.Tokens.TokenValidationParameters properties RequireExpirationTime, ValidateAudience, ValidateIssuer, or ValidateLifetime to true. Or, remove the assignment to false because the default value is true.

    +
    + + +

    This example disabled the validation.

    + + +

    To fix it, do not disable the validations or use the default value.

    + + +
    + + + +
  • azure-activedirectory-identitymodel-extensions-for-dotnet ValidatingTokens wiki
  • + +
    +
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql new file mode 100644 index 00000000000..4b558730bab --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -0,0 +1,24 @@ +/** + * @name Security sensitive JsonWebTokenHandler validations are disabled + * @description Check if secruity sensitive token validations for `JsonWebTokenHandler` are being disabled. + * @kind problem + * @tags security + * JsonWebTokenHandler + * manual-verification-required + * @id cs/JsonWebTokenHandler/security-validations-disabled + * @problem.severity warning + * @precision high + */ + +import csharp +import JsonWebTokenHandlerLib + +from + FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation config, + DataFlow::Node source, DataFlow::Node sink, + TokenValidationParametersPropertyWriteToBypassSensitiveValidation pw +where + config.hasFlow(source, sink) and + exists(Assignment a | a.getLValue() = pw | sink.asExpr() = a.getRValue()) +select sink, "The security sensitive property $@ is being disabled by the followign value: $@.", pw, + pw.getTarget().toString(), source, "false" diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected new file mode 100644 index 00000000000..9e01238de4c --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected @@ -0,0 +1,2 @@ +| delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:102:13:102:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:102:13:102:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref new file mode 100644 index 00000000000..527ea925973 --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref @@ -0,0 +1 @@ +experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs new file mode 100644 index 00000000000..fe4a5f1d6ea --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.JsonWebTokens; + +namespace WilsonTest +{ + public class Wilson_03 + { + public static object ThrowIfNull(string name, object value) + { + if (value == null) + { + throw new System.ArgumentNullException(name); + } + return value; + } + + private static bool MayThrowException(SecurityToken token) + { + if (token.Id == null) + { + throw new Exception("foobar"); + } + return true; + } + + private static void DoesNotThrowException(SecurityToken token) + { + int x = 0; + } + + private static bool ValidateLifetime_FP01( + SecurityToken token, + TokenValidationParameters validationParameters) + { + if (token == null) + { + throw new System.ArgumentNullException("token"); + } + + MayThrowException(token); + + return true; + } + + private static bool ValidateLifetime_P01( + SecurityToken token, + TokenValidationParameters validationParameters) + { + if (token == null) + { + throw new System.ArgumentNullException("token"); + } + + DoesNotThrowException(token); + + return true; + } + + + internal static bool ValidateLifetimeAlwaysTrue( + SecurityToken token, + TokenValidationParameters validationParameters) + { + if (token is null) + { + return true; + } + return true; + } + + internal static bool ValidateLifetime( + string token, + TokenValidationParameters validationParameters) + { + if (token is null) + { + return false; + } + return true; + } + + public void TestCase01() + { + TokenValidationParameters tokenValidationParamsBaseline = new TokenValidationParameters + { + ClockSkew = TimeSpan.FromMinutes(5), + ValidateActor = true, + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + RequireExpirationTime = true, + ValidateTokenReplay = true, + RequireSignedTokens = true, + RequireAudience = true, + SaveSigninToken = true + }; + + tokenValidationParamsBaseline.LifetimeValidator = (notBefore, expires, securityToken, validationParameters) => ValidateLifetimeAlwaysTrue(securityToken, validationParameters); // BUG delegated-security-validations-always-return-true + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => true; // BUG delegated-security-validations-always-return-true + tokenValidationParamsBaseline.TokenReplayValidator = (DateTime? expirationTime, string securityToken, TokenValidationParameters validationParameters) => // GOOD + { + if (securityToken is null) + { + return false; + } + return true; + }; + + } + + } +} \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs new file mode 100644 index 00000000000..149448ce122 --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using Microsoft.IdentityModel.Tokens; + +namespace WilsonTest +{ + public class Wilson_02 + { + public void TestCase01() + { + TokenValidationParameters tokenValidationParamsBaseline = new TokenValidationParameters + { + ClockSkew = TimeSpan.FromMinutes(5), + ValidateActor = true, + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + RequireExpirationTime = true, + ValidateTokenReplay = true, + RequireSignedTokens = true, + RequireAudience = true, + SaveSigninToken = true + }; + + TokenValidationParameters tokenValidationParams = new TokenValidationParameters + { + ClockSkew = TimeSpan.FromMinutes(5), + ValidateActor = false, + ValidateIssuerSigningKey = false, + ValidateIssuer = false, // BUG + ValidateAudience = false, // BUG + ValidateLifetime = false, // BUG + RequireExpirationTime = false, // BUG + ValidateTokenReplay = false, + RequireSignedTokens = false, + RequireAudience = false, + SaveSigninToken = false + }; + } + + } +} \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected new file mode 100644 index 00000000000..213c58643ec --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected @@ -0,0 +1,4 @@ +| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:31:17:31:30 | access to property ValidateIssuer | ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | +| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:32:17:32:32 | access to property ValidateAudience | ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | +| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:33:17:33:32 | access to property ValidateLifetime | ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | +| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:34:17:34:37 | access to property RequireExpirationTime | RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref new file mode 100644 index 00000000000..ee07957fa06 --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref @@ -0,0 +1 @@ +experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs new file mode 100644 index 00000000000..1d0e0de00a3 --- /dev/null +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.IdentityModel +{ + +} + +namespace Microsoft.IdentityModel.Tokens +{ + public abstract class SecurityToken + { + protected SecurityToken() { } + public string Id { get; } + public string Issuer { get; } + public DateTime ValidFrom { get; } + public DateTime ValidTo { get; } + } + + public abstract class TokenHandler + { + public static readonly int DefaultTokenLifetimeInMinutes; + + protected TokenHandler() { } + + public virtual int MaximumTokenSizeInBytes { get; set; } + public bool SetDefaultTimesOnTokenCreation { get; set; } + public int TokenLifetimeInMinutes { get; set; } + } + + public delegate bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters); + public delegate bool AudienceValidator(IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters); + public delegate bool TokenReplayValidator(DateTime? expirationTime, string securityToken, TokenValidationParameters validationParameters); + public delegate string IssuerValidator(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters); + + public class TokenValidationParameters + { + public const int DefaultMaximumTokenSizeInBytes = 256000; + public static readonly string DefaultAuthenticationType; + public static readonly TimeSpan DefaultClockSkew; + public TimeSpan ClockSkew { get; set; } + public bool SaveSigninToken { get; set; } + public bool ValidateIssuer { get; set; } + public bool ValidateAudience { get; set; } + public bool ValidateLifetime { get; set; } + public bool ValidateIssuerSigningKey { get; set; } + public bool ValidateTokenReplay { get; set; } + public bool ValidateActor { get; set; } + public bool RequireSignedTokens { get; set; } + public bool RequireAudience { get; set; } + public bool RequireExpirationTime { get; set; } + + // Delegation + public LifetimeValidator LifetimeValidator { get; set; } + public AudienceValidator AudienceValidator { get; set; } + public TokenReplayValidator TokenReplayValidator { get; set; } + public IssuerValidator IssuerValidator { get; set; } + + /* + public TokenValidationParameters() { } + public SignatureValidator SignatureValidator { get; set; } + public SecurityKey TokenDecryptionKey { get; set; } + public TokenDecryptionKeyResolver TokenDecryptionKeyResolver { get; set; } + public IEnumerable TokenDecryptionKeys { get; set; } + public TokenReader TokenReader { get; set; } + public ITokenReplayCache TokenReplayCache { get; set; } + public Func RoleClaimTypeRetriever { get; set; } + public string ValidAudience { get; set; } + public IEnumerable ValidAudiences { get; set; } + public string ValidIssuer { get; set; } + public IEnumerable ValidIssuers { get; set; } + public TokenValidationParameters ActorValidationParameters { get; set; } + public AudienceValidator AudienceValidator { get; set; } + public string AuthenticationType { get; set; } + public CryptoProviderFactory CryptoProviderFactory { get; set; } + public IssuerSigningKeyValidator IssuerSigningKeyValidator { get; set; } + public SecurityKey IssuerSigningKey { get; set; } + public IEnumerable IssuerSigningKeys { get; set; } + public IssuerValidator IssuerValidator { get; set; } + public string NameClaimType { get; set; } + public string RoleClaimType { get; set; } + public Func NameClaimTypeRetriever { get; set; } + public IDictionary PropertyBag { get; set; } + public IssuerSigningKeyResolver IssuerSigningKeyResolver { get; set; } + public IEnumerable ValidTypes { get; set; } + public virtual TokenValidationParameters Clone(); + public virtual string CreateClaimsIdentity(SecurityToken securityToken, string issuer); + */ + } + +} + +namespace Microsoft.IdentityModel.JsonWebTokens +{ + public class JsonWebTokenHandler : Microsoft.IdentityModel.Tokens.TokenHandler + { + public virtual TokenValidationResult ValidateToken(string token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters) + { + return new TokenValidationResult() { IsValid = true, Exception = null, Issuer = "test" }; + } + } + + public class TokenValidationResult + { + public TokenValidationResult() { } + + public Exception Exception { get; set; } + public string Issuer { get; set; } + public bool IsValid { get; set; } + public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { get; set; } + public string ClaimsIdentity { get; set; } + } + + +} From 13464e80154da357f7033668bc08da8cdaa92a62 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 23 Jun 2022 09:07:28 -0700 Subject: [PATCH 002/203] Changing @Severity tag to `error` --- .../delegated-security-validations-always-return-true.ql | 2 +- .../JsonWebTokenHandler/security-validation-disabled.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index a9df54378f3..5caa5591e06 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -7,7 +7,7 @@ * JsonWebTokenHandler * manual-verification-required * @id cs/JsonWebTokenHandler/delegated-security-validations-always-return-true - * @problem.severity warning + * @problem.severity error * @precision high */ diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql index 4b558730bab..2e728700223 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -6,7 +6,7 @@ * JsonWebTokenHandler * manual-verification-required * @id cs/JsonWebTokenHandler/security-validations-disabled - * @problem.severity warning + * @problem.severity error * @precision high */ From 62c28571c650d6e2cbb7a9f11c544f43f7a5f95c Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 1 Jul 2022 17:35:02 -0700 Subject: [PATCH 003/203] making changes based on feedback during PR --- .../JsonWebTokenHandlerLib.qll | 44 ++++++++++--------- .../JsonWebTokenHandler/delegation-test.cs | 4 +- .../security-validation-disabled-test.cs | 4 +- .../security-validation-disabled.expected | 1 + 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index b2f3a2fab16..3247a2e4fb6 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -2,7 +2,7 @@ import csharp import DataFlow /** - * Abstract PropertyWrite for `TokenValidationParameters`. + * An abstract PropertyWrite for `TokenValidationParameters`. * Not really necessary anymore, but keeping it in case we want to extend the queries to check on other properties. */ abstract class TokenValidationParametersPropertyWrite extends PropertyWrite { } @@ -18,14 +18,14 @@ class TokenValidationParametersPropertyWriteToBypassSensitiveValidation extends p.getAnAccess() = this and c.getAProperty() = p and p.getName() in [ - "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime" + "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", "RequireAudience" ] ) } } /** - * Dataflow from a `false` value to an to a write sensitive property for `TokenValidationParameters`. + * A dataflow from a `false` value to a write sensitive property for `TokenValidationParameters`. */ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation extends TaintTracking::Configuration { FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation() { @@ -33,12 +33,14 @@ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation } override predicate isSource(DataFlow::Node source) { - source.asExpr().(BoolLiteral).getValue() = "false" + source.asExpr().getValue() = "false" and + source.asExpr().getType() instanceof BoolType } override predicate isSink(DataFlow::Node sink) { - exists(TokenValidationParametersPropertyWrite pw, Assignment a | a.getLValue() = pw | + exists(Assignment a | sink.asExpr() = a.getRValue() + and a.getLValue() instanceof TokenValidationParametersPropertyWrite ) } } @@ -55,7 +57,7 @@ predicate isAssemblyOlderVersion(string assemblyName, string ver) { } /** - * Method `ValidateToken` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler` or other Token handler that shares the same behavior characteristics + * A method `ValidateToken` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler` or other Token handler that shares the same behavior characteristics */ class JsonWebTokenHandlerValidateTokenMethod extends Method { JsonWebTokenHandlerValidateTokenMethod() { @@ -78,7 +80,7 @@ class JsonWebTokenHandlerValidateTokenCall extends MethodCall { } /** - * Read access for properties `IsValid` or `Exception` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` + * A read access for properties `IsValid` or `Exception` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` */ class TokenValidationResultIsValidCall extends PropertyRead { TokenValidationResultIsValidCall() { @@ -116,7 +118,7 @@ predicate hasAFlowToTokenValidationResultIsValidCall(JsonWebTokenHandlerValidate } /** - * Property write for security-sensitive properties for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` + * A property write for security-sensitive properties for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` */ class TokenValidationParametersPropertyWriteToValidationDelegated extends PropertyWrite { TokenValidationParametersPropertyWriteToValidationDelegated() { @@ -136,7 +138,7 @@ class TokenValidationParametersPropertyWriteToValidationDelegated extends Proper /** * Holds if the callable has a return statement and it always returns true for all such statements */ -predicate callableHasARetrunStmtAndAlwaysReturnsTrue(Callable c) { +predicate callableHasAReturnStmtAndAlwaysReturnsTrue(Callable c) { c.getReturnType().toString() = "Boolean" and forall(ReturnStmt rs | rs.getEnclosingCallable() = c | rs.getChildExpr(0).(BoolLiteral).getBoolValue() = true @@ -153,7 +155,7 @@ predicate lambdaExprReturnsOnlyLiteralTrue(LambdaExpr le) { class CallableAlwaysReturnsTrue extends Callable { CallableAlwaysReturnsTrue() { - callableHasARetrunStmtAndAlwaysReturnsTrue(this) + callableHasAReturnStmtAndAlwaysReturnsTrue(this) or lambdaExprReturnsOnlyLiteralTrue(this) or @@ -195,7 +197,7 @@ class CallableAlwaysReturnsTrueHigherPrecision extends CallableAlwaysReturnsTrue } /** - * Property Write for the `IssuerValidator` property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` + * A property Write for the `IssuerValidator` property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` */ class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator extends PropertyWrite { TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator() { @@ -204,7 +206,7 @@ class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator | p.getAnAccess() = this and c.getAProperty() = p and - p.getName() in ["IssuerValidator"] + p.hasName("IssuerValidator") ) } } @@ -214,22 +216,22 @@ class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator */ private class CallableReturnsStringAndArg0IsString extends Callable { CallableReturnsStringAndArg0IsString() { - this.getReturnType().toString() = "String" and + this.getReturnType() instanceof StringType and this.getParameter(0).getType().toString() = "String" } } /** - * A Callable that always retrun the 1st argument, both of `string` type + * A Callable that always return the 1st argument, both of `string` type */ -class CallableAlwatsReturnsParameter0 extends CallableReturnsStringAndArg0IsString { - CallableAlwatsReturnsParameter0() { +class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsString { + CallableAlwaysReturnsParameter0() { forall(ReturnStmt rs | rs.getEnclosingCallable() = this | rs.getChild(0) = this.getParameter(0).getAnAccess() ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = this) or - exists(LambdaExpr le, Call call, CallableAlwatsReturnsParameter0 cat | this = le | + exists(LambdaExpr le, Call call, CallableAlwaysReturnsParameter0 cat | this = le | call = le.getExpressionBody() and cat.getACall() = call ) @@ -239,17 +241,17 @@ class CallableAlwatsReturnsParameter0 extends CallableReturnsStringAndArg0IsStri } /** - * A Callable that always retrun the 1st argument, both of `string` type. Higher precision + * A Callable that always return the 1st argument, both of `string` type. Higher precision */ -class CallableAlwatsReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString { - CallableAlwatsReturnsParameter0MayThrowExceptions() { +class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString { + CallableAlwaysReturnsParameter0MayThrowExceptions() { callableOnlyThrowsArgumentNullException(this) and forall(ReturnStmt rs | rs.getEnclosingCallable() = this | rs.getChild(0) = this.getParameter(0).getAnAccess() ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = this) or - exists(LambdaExpr le, Call call, CallableAlwatsReturnsParameter0MayThrowExceptions cat | + exists(LambdaExpr le, Call call, CallableAlwaysReturnsParameter0MayThrowExceptions cat | this = le | call = le.getExpressionBody() and diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs index fe4a5f1d6ea..452cb1dc648 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.JsonWebTokens; -namespace WilsonTest +namespace JsonWebTokenHandlerTest { - public class Wilson_03 + public class JsonWebTokenHandler_00 { public static object ThrowIfNull(string name, object value) { diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs index 149448ce122..e3caddfd227 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using Microsoft.IdentityModel.Tokens; -namespace WilsonTest +namespace JsonWebTokenHandlerTest { - public class Wilson_02 + public class JsonWebTokenHandler_class01 { public void TestCase01() { diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected index 213c58643ec..071cc2ea2f8 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected @@ -2,3 +2,4 @@ | security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:32:17:32:32 | access to property ValidateAudience | ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | | security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:33:17:33:32 | access to property ValidateLifetime | ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | | security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:34:17:34:37 | access to property RequireExpirationTime | RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | +| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:37:17:37:31 | access to property RequireAudience | RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | From 97d9fd9846851997d2da65a141f1fe10161728bc Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 5 Jul 2022 15:18:56 -0700 Subject: [PATCH 004/203] Update security-validation-disabled.ql --- .../JsonWebTokenHandler/security-validation-disabled.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql index 2e728700223..5d0491e826e 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -20,5 +20,5 @@ from where config.hasFlow(source, sink) and exists(Assignment a | a.getLValue() = pw | sink.asExpr() = a.getRValue()) -select sink, "The security sensitive property $@ is being disabled by the followign value: $@.", pw, +select sink, "The security sensitive property $@ is being disabled by the following value: $@.", pw, pw.getTarget().toString(), source, "false" From 7f725137e50e88e6cc9ad5eabe3c9182e597b4d8 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 20 Jul 2022 10:56:44 -0700 Subject: [PATCH 005/203] Addressing some of the feedback. Work pending. --- .../JsonWebTokenHandler/security-validation-disabled-test.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs index e3caddfd227..505aba41416 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs @@ -34,7 +34,7 @@ namespace JsonWebTokenHandlerTest RequireExpirationTime = false, // BUG ValidateTokenReplay = false, RequireSignedTokens = false, - RequireAudience = false, + RequireAudience = false, // BUG SaveSigninToken = false }; } From 9b79668ed29446c5c2aa7e85e07072695056bfda Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 20 Jul 2022 10:58:01 -0700 Subject: [PATCH 006/203] Addressing some of the feedback. Work still pending --- .../JsonWebTokenHandler/JsonWebTokenHandlerLib.qll | 6 +++--- .../security-validation-disabled.expected | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 3247a2e4fb6..3c79d7174f3 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -189,7 +189,7 @@ class CallableAlwaysReturnsTrueHigherPrecision extends CallableAlwaysReturnsTrue ) or exists(LambdaExpr le, Call call, CallableAlwaysReturnsTrueHigherPrecision cat | this = le | - call = le.getExpressionBody() and + le.canReturn(call) and cat.getACall() = call ) ) @@ -217,7 +217,7 @@ class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator private class CallableReturnsStringAndArg0IsString extends Callable { CallableReturnsStringAndArg0IsString() { this.getReturnType() instanceof StringType and - this.getParameter(0).getType().toString() = "String" + this.getParameter(0).getType() instanceof StringType } } @@ -227,7 +227,7 @@ private class CallableReturnsStringAndArg0IsString extends Callable { class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsString { CallableAlwaysReturnsParameter0() { forall(ReturnStmt rs | rs.getEnclosingCallable() = this | - rs.getChild(0) = this.getParameter(0).getAnAccess() + rs.getExpr() = this.getParameter(0).getAnAccess() ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = this) or diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected index 071cc2ea2f8..7cb0db1fe5f 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected @@ -1,5 +1,5 @@ -| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:31:17:31:30 | access to property ValidateIssuer | ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | -| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:32:17:32:32 | access to property ValidateAudience | ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | -| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:33:17:33:32 | access to property ValidateLifetime | ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | -| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:34:17:34:37 | access to property RequireExpirationTime | RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | -| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the followign value: $@. | security-validation-disabled-test.cs:37:17:37:31 | access to property RequireAudience | RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | +| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:31:17:31:30 | access to property ValidateIssuer | ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | +| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:32:17:32:32 | access to property ValidateAudience | ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | +| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:33:17:33:32 | access to property ValidateLifetime | ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | +| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:34:17:34:37 | access to property RequireExpirationTime | RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | +| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:37:17:37:31 | access to property RequireAudience | RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | From 5a7b6532a9b4e9150baaa1780f355ceda554eba4 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 29 Jul 2022 13:47:53 -0700 Subject: [PATCH 007/203] Updated to handle lambda statements (previously false negatives) + a couple of bug fixes. --- .../JsonWebTokenHandlerLib.qll | 74 ++++++++++++++++--- ...security-validations-always-return-true.ql | 5 +- ...ty-validations-always-return-true.expected | 5 ++ .../JsonWebTokenHandler/delegation-test.cs | 22 ++++++ 4 files changed, 91 insertions(+), 15 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 3c79d7174f3..3f568d4d16b 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -18,7 +18,8 @@ class TokenValidationParametersPropertyWriteToBypassSensitiveValidation extends p.getAnAccess() = this and c.getAProperty() = p and p.getName() in [ - "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", "RequireAudience" + "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", + "RequireAudience" ] ) } @@ -38,9 +39,9 @@ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation } override predicate isSink(DataFlow::Node sink) { - exists(Assignment a | - sink.asExpr() = a.getRValue() - and a.getLValue() instanceof TokenValidationParametersPropertyWrite + exists(Assignment a | + sink.asExpr() = a.getRValue() and + a.getLValue() instanceof TokenValidationParametersPropertyWrite ) } } @@ -139,9 +140,11 @@ class TokenValidationParametersPropertyWriteToValidationDelegated extends Proper * Holds if the callable has a return statement and it always returns true for all such statements */ predicate callableHasAReturnStmtAndAlwaysReturnsTrue(Callable c) { - c.getReturnType().toString() = "Boolean" and + c.getReturnType() instanceof BoolType and + not callableMayThrowException(c) and forall(ReturnStmt rs | rs.getEnclosingCallable() = c | - rs.getChildExpr(0).(BoolLiteral).getBoolValue() = true + rs.getNumberOfChildren() = 1 and + isExpressionAlwaysTrue(rs.getChildExpr(0)) ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = c) } @@ -149,8 +152,16 @@ predicate callableHasAReturnStmtAndAlwaysReturnsTrue(Callable c) { /** * Holds if the lambda expression `le` always returns true */ -predicate lambdaExprReturnsOnlyLiteralTrue(LambdaExpr le) { +predicate lambdaExprReturnsOnlyLiteralTrue(AnonymousFunctionExpr le) { le.getExpressionBody().(BoolLiteral).getBoolValue() = true + or + // special scenarios where the expression is not a `BoolLiteral`, but it will evaluatue to `true` + exists(Expr e | le.getExpressionBody() = e | + not e instanceof Call and + not e instanceof Literal and + e.getType() instanceof BoolType and + e.getValue() = "true" + ) } class CallableAlwaysReturnsTrue extends Callable { @@ -159,9 +170,12 @@ class CallableAlwaysReturnsTrue extends Callable { or lambdaExprReturnsOnlyLiteralTrue(this) or - exists(LambdaExpr le, Call call, CallableAlwaysReturnsTrue cat | this = le | + exists(AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsTrue cat, Callable callable | + this = le + | + callable.getACall() = call and call = le.getExpressionBody() and - cat.getACall() = call + callableHasAReturnStmtAndAlwaysReturnsTrue(callable) ) } } @@ -188,10 +202,16 @@ class CallableAlwaysReturnsTrueHigherPrecision extends CallableAlwaysReturnsTrue callable instanceof CallableAlwaysReturnsTrueHigherPrecision ) or - exists(LambdaExpr le, Call call, CallableAlwaysReturnsTrueHigherPrecision cat | this = le | + exists(AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsTrueHigherPrecision cat | + this = le + | le.canReturn(call) and cat.getACall() = call ) + or + exists(LambdaExpr le | le = this | + le.getBody() instanceof CallableAlwaysReturnsTrueHigherPrecision + ) ) } } @@ -231,7 +251,7 @@ class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsStri ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = this) or - exists(LambdaExpr le, Call call, CallableAlwaysReturnsParameter0 cat | this = le | + exists(AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsParameter0 cat | this = le | call = le.getExpressionBody() and cat.getACall() = call ) @@ -251,7 +271,9 @@ class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsS ) and exists(ReturnStmt rs | rs.getEnclosingCallable() = this) or - exists(LambdaExpr le, Call call, CallableAlwaysReturnsParameter0MayThrowExceptions cat | + exists( + AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsParameter0MayThrowExceptions cat + | this = le | call = le.getExpressionBody() and @@ -263,3 +285,31 @@ class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsS this.getBody() = this.getParameter(0).getAnAccess() } } + +/** + * Hold if the `Expr` e is a `BoolLiteral` with value true, + * the expression has a predictable value == `true`, + * or if it is a `ConditionalExpr` where the `then` and `else` expressions meet `isExpressionAlwaysTrue` criteria + */ +predicate isExpressionAlwaysTrue(Expr e) { + e.(BoolLiteral).getBoolValue() = true + or + e.(Expr).getValue() = "true" + or + e instanceof ConditionalExpr and + isExpressionAlwaysTrue(e.(ConditionalExpr).getThen()) and + isExpressionAlwaysTrue(e.(ConditionalExpr).getElse()) + or + exists(Callable callable | + callableHasAReturnStmtAndAlwaysReturnsTrue(callable) and + callable.getACall() = e + ) +} + +/** + * Holds if the `Callable` c throws any exception other than `ThrowsArgumentNullException` + */ +predicate callableMayThrowException(Callable c) { + exists(ThrowStmt thre | c = thre.getEnclosingCallable()) and + not callableOnlyThrowsArgumentNullException(c) +} diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 5caa5591e06..10f016bc5b3 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -19,6 +19,5 @@ from TokenValidationParametersPropertyWriteToValidationDelegated tv, Assignment a, CallableAlwaysReturnsTrueHigherPrecision e where a.getLValue() = tv and a.getRValue().getAChild*() = e -select tv, - "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", - tv, tv.getTarget().toString(), e, "a callable that always returns \"true\"" +select tv, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", tv, + tv.getTarget().toString(), e, "a callable that always returns \"true\"" diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected index 9e01238de4c..e6c576dad45 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected @@ -1,2 +1,7 @@ | delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | | delegation-test.cs:102:13:102:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:102:13:102:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:115:13:115:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:115:13:115:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:116:13:116:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:116:13:116:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:117:13:117:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:117:13:117:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:118:13:118:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:118:13:118:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:119:13:119:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:119:13:119:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs index 452cb1dc648..01af41c4b0c 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs @@ -109,7 +109,29 @@ namespace JsonWebTokenHandlerTest return true; }; + tokenValidationParamsBaseline.LifetimeValidator = (notBefore, expires, securityToken, validationParameters) => ValidateLifetime02(securityToken, validationParameters); // GOOD + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => {return securityToken is null?false:true; }; // GOOD + + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return true; }; // BUG + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => !false ; // BUG + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return securityToken is null?true:true; }; // BUG + tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return ValidateLifetimeAlwaysTrue(securityToken, validationParameters);}; //BUG + tokenValidationParamsBaseline.AudienceValidator = (audiences, securityToken, validationParameters) => ValidateLifetimeAlwaysTrue(securityToken, validationParameters); //BUG + } + internal static bool ValidateLifetime02( + SecurityToken token, + TokenValidationParameters validationParameters) + { + return token is null?false:true; + } + + internal static bool ValidateLifetimeAlwaysTrue02( + SecurityToken token, + TokenValidationParameters validationParameters) + { + return !false; + } } } \ No newline at end of file From 6070e4f3128de0eca868e6a4b03d4d164c8a6ea5 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Thu, 11 Aug 2022 17:31:12 -0700 Subject: [PATCH 008/203] Update csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll Co-authored-by: Tom Hvitved --- .../JsonWebTokenHandler/JsonWebTokenHandlerLib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 3f568d4d16b..911e93cd032 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -76,7 +76,7 @@ class JsonWebTokenHandlerValidateTokenMethod extends Method { */ class JsonWebTokenHandlerValidateTokenCall extends MethodCall { JsonWebTokenHandlerValidateTokenCall() { - exists(JsonWebTokenHandlerValidateTokenMethod m | m.getACall() = this) + this.getTarget() instanceof JsonWebTokenHandlerValidateTokenMethod } } From 0805b4991440fd465fcf3d5f4d9be6324822bd16 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Thu, 11 Aug 2022 17:35:10 -0700 Subject: [PATCH 009/203] Update csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll Co-authored-by: Tom Hvitved --- .../JsonWebTokenHandlerLib.qll | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 911e93cd032..194b92d0905 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -246,17 +246,14 @@ private class CallableReturnsStringAndArg0IsString extends Callable { */ class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsString { CallableAlwaysReturnsParameter0() { - forall(ReturnStmt rs | rs.getEnclosingCallable() = this | - rs.getExpr() = this.getParameter(0).getAnAccess() - ) and - exists(ReturnStmt rs | rs.getEnclosingCallable() = this) - or - exists(AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsParameter0 cat | this = le | - call = le.getExpressionBody() and - cat.getACall() = call + forex(Expr ret | this.canReturn(ret) | + ret = this.getParameter(0).getAnAccess() + or + exists(CallableAlwaysReturnsParameter0 c | + ret = c.getACall() and + ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() + ) ) - or - this.getBody() = this.getParameter(0).getAnAccess() } } From 39e53a2932b2107d0dc8d65ee9ba27cd66e428fc Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 11 Aug 2022 17:59:57 -0700 Subject: [PATCH 010/203] Updates based on PR feedback. 1 pending change --- .../JsonWebTokenHandlerLib.qll | 58 +++++-------------- ...security-validations-always-return-true.ql | 9 ++- .../security-validation-disabled.ql | 6 +- ...ty-validations-always-return-true.expected | 14 ++--- .../security-validation-disabled.expected | 10 ++-- 5 files changed, 32 insertions(+), 65 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 194b92d0905..7da1ee65d9f 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -2,20 +2,14 @@ import csharp import DataFlow /** - * An abstract PropertyWrite for `TokenValidationParameters`. - * Not really necessary anymore, but keeping it in case we want to extend the queries to check on other properties. + * A sensitive property for `TokenValidationParameters` that updates the underlying value. */ -abstract class TokenValidationParametersPropertyWrite extends PropertyWrite { } - -/** - * An access to a sensitive property for `TokenValidationParameters` that updates the underlying value. - */ -class TokenValidationParametersPropertyWriteToBypassSensitiveValidation extends TokenValidationParametersPropertyWrite { - TokenValidationParametersPropertyWriteToBypassSensitiveValidation() { +class TokenValidationParametersPropertySensitiveValidation extends Property { + TokenValidationParametersPropertySensitiveValidation() { exists(Property p, Class c | c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") | - p.getAnAccess() = this and + p = this and c.getAProperty() = p and p.getName() in [ "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", @@ -28,7 +22,7 @@ class TokenValidationParametersPropertyWriteToBypassSensitiveValidation extends /** * A dataflow from a `false` value to a write sensitive property for `TokenValidationParameters`. */ -class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation extends TaintTracking::Configuration { +class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation extends DataFlow::Configuration { FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation() { this = "FlowsToTokenValidationResultIsValidCall" } @@ -41,7 +35,7 @@ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation override predicate isSink(DataFlow::Node sink) { exists(Assignment a | sink.asExpr() = a.getRValue() and - a.getLValue() instanceof TokenValidationParametersPropertyWrite + a.getLValue().(PropertyAccess).getProperty() instanceof TokenValidationParametersPropertySensitiveValidation ) } } @@ -83,7 +77,7 @@ class JsonWebTokenHandlerValidateTokenCall extends MethodCall { /** * A read access for properties `IsValid` or `Exception` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` */ -class TokenValidationResultIsValidCall extends PropertyRead { +private class TokenValidationResultIsValidCall extends PropertyRead { TokenValidationResultIsValidCall() { exists(Property p | p.getAnAccess().(PropertyRead) = this | p.hasName("IsValid") or @@ -95,7 +89,7 @@ class TokenValidationResultIsValidCall extends PropertyRead { /** * Dataflow from the output of `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` call to access the `IsValid` or `Exception` property */ -private class FlowsToTokenValidationResultIsValidCall extends TaintTracking::Configuration { +private class FlowsToTokenValidationResultIsValidCall extends DataFlow::Configuration { FlowsToTokenValidationResultIsValidCall() { this = "FlowsToTokenValidationResultIsValidCall" } override predicate isSource(DataFlow::Node source) { @@ -108,25 +102,14 @@ private class FlowsToTokenValidationResultIsValidCall extends TaintTracking::Con } /** - * Holds if the call to `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` flows to any `IsValid` or `Exception` property access + * A security-sensitive property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` */ -predicate hasAFlowToTokenValidationResultIsValidCall(JsonWebTokenHandlerValidateTokenCall call) { - exists(FlowsToTokenValidationResultIsValidCall config, DataFlow::Node source | - call = source.asExpr() - | - config.hasFlow(source, _) - ) -} - -/** - * A property write for security-sensitive properties for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` - */ -class TokenValidationParametersPropertyWriteToValidationDelegated extends PropertyWrite { - TokenValidationParametersPropertyWriteToValidationDelegated() { +class TokenValidationParametersProperty extends Property { + TokenValidationParametersProperty() { exists(Property p, Class c | c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") | - p.getAnAccess() = this and + p = this and c.getAProperty() = p and p.getName() in [ "SignatureValidator", "TokenReplayValidator", "AlgorithmValidator", "AudienceValidator", @@ -170,7 +153,7 @@ class CallableAlwaysReturnsTrue extends Callable { or lambdaExprReturnsOnlyLiteralTrue(this) or - exists(AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsTrue cat, Callable callable | + exists(AnonymousFunctionExpr le, Call call, Callable callable | this = le | callable.getACall() = call and @@ -216,21 +199,6 @@ class CallableAlwaysReturnsTrueHigherPrecision extends CallableAlwaysReturnsTrue } } -/** - * A property Write for the `IssuerValidator` property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` - */ -class TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator extends PropertyWrite { - TokenValidationParametersPropertyWriteToValidationDelegatedIssuerValidator() { - exists(Property p, Class c | - c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") - | - p.getAnAccess() = this and - c.getAProperty() = p and - p.hasName("IssuerValidator") - ) - } -} - /** * A callable that returns a `string` and has a `string` as 1st argument */ diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 10f016bc5b3..39220e3cddf 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -16,8 +16,7 @@ import DataFlow import JsonWebTokenHandlerLib from - TokenValidationParametersPropertyWriteToValidationDelegated tv, Assignment a, - CallableAlwaysReturnsTrueHigherPrecision e -where a.getLValue() = tv and a.getRValue().getAChild*() = e -select tv, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", tv, - tv.getTarget().toString(), e, "a callable that always returns \"true\"" + TokenValidationParametersProperty p , CallableAlwaysReturnsTrueHigherPrecision e +where e = p.getAnAssignedValue() +select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", p, + p.getQualifiedName().toString(), e, "a callable that always returns \"true\"" diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql index 5d0491e826e..15a8813171d 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -16,9 +16,9 @@ import JsonWebTokenHandlerLib from FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation config, DataFlow::Node source, DataFlow::Node sink, - TokenValidationParametersPropertyWriteToBypassSensitiveValidation pw + TokenValidationParametersPropertySensitiveValidation pw where config.hasFlow(source, sink) and - exists(Assignment a | a.getLValue() = pw | sink.asExpr() = a.getRValue()) + sink.asExpr() = pw.getAnAssignedValue() select sink, "The security sensitive property $@ is being disabled by the following value: $@.", pw, - pw.getTarget().toString(), source, "false" + pw.getQualifiedName().toString(), source, "false" diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected index e6c576dad45..dc224c9586e 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected @@ -1,7 +1,7 @@ -| delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:101:13:101:59 | access to property LifetimeValidator | LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:102:13:102:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:102:13:102:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:115:13:115:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:115:13:115:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:116:13:116:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:116:13:116:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:117:13:117:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:117:13:117:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:118:13:118:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:118:13:118:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | -| delegation-test.cs:119:13:119:59 | access to property AudienceValidator | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | delegation-test.cs:119:13:119:59 | access to property AudienceValidator | AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | delegation-test.cs:101:63:101:186 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:102:63:102:178 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:115:63:115:190 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:116:63:116:180 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:117:63:117:217 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:118:63:118:248 | (...) => ... | a callable that always returns "true" | +| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to $@. | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | delegation-test.cs:119:63:119:177 | (...) => ... | a callable that always returns "true" | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected index 7cb0db1fe5f..4a0a5afce6f 100644 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected +++ b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected @@ -1,5 +1,5 @@ -| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:31:17:31:30 | access to property ValidateIssuer | ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | -| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:32:17:32:32 | access to property ValidateAudience | ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | -| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:33:17:33:32 | access to property ValidateLifetime | ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | -| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:34:17:34:37 | access to property RequireExpirationTime | RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | -| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the following value: $@. | security-validation-disabled-test.cs:37:17:37:31 | access to property RequireAudience | RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | +| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:43:21:43:34 | ValidateIssuer | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | +| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:44:21:44:36 | ValidateAudience | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | +| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:45:21:45:36 | ValidateLifetime | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | +| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:51:21:51:41 | RequireExpirationTime | Microsoft.IdentityModel.Tokens.TokenValidationParameters.RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | +| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:50:21:50:35 | RequireAudience | Microsoft.IdentityModel.Tokens.TokenValidationParameters.RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | From e5f5d461f4d8462dbca2c6d155714a02edc53b67 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 12 Aug 2022 10:16:10 -0700 Subject: [PATCH 011/203] addressing feedback from PR review --- .../JsonWebTokenHandlerLib.qll | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 7da1ee65d9f..f976556534e 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -230,24 +230,14 @@ class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsStri */ class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString { CallableAlwaysReturnsParameter0MayThrowExceptions() { - callableOnlyThrowsArgumentNullException(this) and - forall(ReturnStmt rs | rs.getEnclosingCallable() = this | - rs.getChild(0) = this.getParameter(0).getAnAccess() - ) and - exists(ReturnStmt rs | rs.getEnclosingCallable() = this) + forex(Expr ret | this.canReturn(ret) | + ret = this.getParameter(0).getAnAccess() or - exists( - AnonymousFunctionExpr le, Call call, CallableAlwaysReturnsParameter0MayThrowExceptions cat - | - this = le - | - call = le.getExpressionBody() and - cat.getACall() = call and - callableOnlyThrowsArgumentNullException(le) and - callableOnlyThrowsArgumentNullException(cat) + exists(CallableAlwaysReturnsParameter0MayThrowExceptions c | + ret = c.getACall() and + ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() ) - or - this.getBody() = this.getParameter(0).getAnAccess() + ) } } From dac64eeca76767a725630d3703aab972a18ddcfe Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 12:23:34 -0400 Subject: [PATCH 012/203] Query test files --- java/ql/src/Security/CWE/CWE-312/AllowBackupFalse.xml | 8 ++++++++ java/ql/src/Security/CWE/CWE-312/AllowBackupTrue.xml | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-312/AllowBackupFalse.xml create mode 100644 java/ql/src/Security/CWE/CWE-312/AllowBackupTrue.xml diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupFalse.xml b/java/ql/src/Security/CWE/CWE-312/AllowBackupFalse.xml new file mode 100644 index 00000000000..cf0a90bb60c --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupFalse.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupTrue.xml b/java/ql/src/Security/CWE/CWE-312/AllowBackupTrue.xml new file mode 100644 index 00000000000..bdec443a6c5 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupTrue.xml @@ -0,0 +1,8 @@ + + + + + + + From 7d15af6caa1d96eca28d298a8d678503110af99c Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 12:25:02 -0400 Subject: [PATCH 013/203] Add allowBackup check to AndroidManifest --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index b5c79efa853..5a0bba3a65b 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -72,6 +72,17 @@ class AndroidApplicationXmlElement extends XmlElement { * Holds if this application element has explicitly set a value for its `android:permission` attribute. */ predicate requiresPermissions() { this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull() } + + /** + * Holds if this application element has the attribute `android:allowBackup` set to `true`. + */ + predicate allowsBackup() { + exists(AndroidXmlAttribute attr | + this.getAnAttribute() = attr and + attr.getName() = "allowBackup" and + attr.getValue() = "true" + ) + } } /** From 44b0a2b8af9b6db4544cc0d4729e87157badc946 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 12:26:08 -0400 Subject: [PATCH 014/203] Android allowBackup query --- .../CWE-312/AllowBackupAttributeEnabled.ql | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql new file mode 100644 index 00000000000..6941aaa46bf --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -0,0 +1,20 @@ +/** + * @name Android allowBackup attribute enabled + * @description + * @kind problem + * @problem.severity recommendation + * @security-severity 7.5 + * @id java/android/allowBackup-attribute-enabled + * @tags security + * external/cwe/cwe-312 + * @precision very-high + */ + +import java +import semmle.code.xml.AndroidManifest + +from AndroidApplicationXmlElement androidAppElem +where + androidAppElem.allowsBackup() and + androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() +select androidAppElem.getAttribute("allowBackup"), "The 'android:allowBackup' attribute is enabled." From 6509426fb383ba28bfc4f12f4b27f835bd392ed3 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 22:03:51 -0400 Subject: [PATCH 015/203] `android:allowBackup` query documentation --- .../CWE-312/AllowBackupAttributeEnabled.qhelp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp new file mode 100644 index 00000000000..8945f40172f --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp @@ -0,0 +1,51 @@ + + + +

    The Android manifest file defines configuration settings for Android +applications. In this file, the android:allowBackup attribute of +the application element can be used to define whether or not the +application can have automatic backups.

    + +

    Enabling backups may allow an attacker to extract sensitive data. Therefore, +it is advised to set android:allowBackup to false if +your application uses any sensitive data.

    +
    + + +

    For Android applications which process sensitive data, set the +android:allowBackup setting to false in the manifest +file.

    + +

    Note: Since Android 6.0 (Marshmallow), applications default to participating +in automatic backups. Therefore, it is necessary to explicitly disable backups. +

    +
    + + + +

    In the two examples below, the android:allowBackup setting is enabled:

    + + + + + +

    A corrected version explicity sets android:allowBackup to false:

    + + + +
    + +
  • + Android Documentation: + Back up user data with Auto Backup +
  • +
  • + OWASP Mobile Security Testing Guide: + + Android Backups + +
  • +
    +
    \ No newline at end of file From dad4a403dbacb1c281419ee7f7d9b3b70d3fd27c Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 22:04:38 -0400 Subject: [PATCH 016/203] Add support for android:allowBackup default value The default value of `android:allowBackup` is `true`. Added support for detecting if the default value is used. --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 10 +++++++--- .../CWE/CWE-312/AllowBackupAttributeEnabled.ql | 2 +- java/ql/src/Security/CWE/CWE-312/AllowBackupEmpty.xml | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 java/ql/src/Security/CWE/CWE-312/AllowBackupEmpty.xml diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index 5a0bba3a65b..bb67ea04827 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -74,13 +74,17 @@ class AndroidApplicationXmlElement extends XmlElement { predicate requiresPermissions() { this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull() } /** - * Holds if this application element has the attribute `android:allowBackup` set to `true`. + * Holds if this application element enables the `android:allowBackup` attribute. + * + * https://developer.android.com/guide/topics/data/autobackup */ predicate allowsBackup() { - exists(AndroidXmlAttribute attr | + // The default value for the attribute `android:allowBackup` is `true`. + // Therefore we also check if it is not present. + not exists(AndroidXmlAttribute attr | this.getAnAttribute() = attr and attr.getName() = "allowBackup" and - attr.getValue() = "true" + attr.getValue() = "false" ) } } diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 6941aaa46bf..88fdeb2a890 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -17,4 +17,4 @@ from AndroidApplicationXmlElement androidAppElem where androidAppElem.allowsBackup() and androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() -select androidAppElem.getAttribute("allowBackup"), "The 'android:allowBackup' attribute is enabled." +select androidAppElem, "The 'android:allowBackup' attribute is enabled." diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupEmpty.xml b/java/ql/src/Security/CWE/CWE-312/AllowBackupEmpty.xml new file mode 100644 index 00000000000..e3e9159b726 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupEmpty.xml @@ -0,0 +1,7 @@ + + + + + + + From a036639ecd0688f88d52bd955c0b180e191f7971 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 18 Aug 2022 22:15:30 -0400 Subject: [PATCH 017/203] Added change notes --- .../2022-08-18-android-manifest-backup-predicate.md | 4 ++++ .../src/change-notes/2022-08-18-android-allowbackup-query.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-08-18-android-manifest-backup-predicate.md create mode 100644 java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md diff --git a/java/ql/lib/change-notes/2022-08-18-android-manifest-backup-predicate.md b/java/ql/lib/change-notes/2022-08-18-android-manifest-backup-predicate.md new file mode 100644 index 00000000000..5346dc58b91 --- /dev/null +++ b/java/ql/lib/change-notes/2022-08-18-android-manifest-backup-predicate.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added a new predicate, `allowsBackup`, in the `AndroidApplicationXmlElement` class. This predicate detects if the application element has its `android:allowBackup` attribute enabled. diff --git a/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md b/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md new file mode 100644 index 00000000000..b7bfd85ac8c --- /dev/null +++ b/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `java/android/allowBackup-attribute-enabled`, to detect if the `android:allowBackup` attribute is enabled in the Android manifest. From de36372d1c1117f1530018c24aa4287d6f5873a9 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Mon, 22 Aug 2022 12:02:27 -0400 Subject: [PATCH 018/203] Refactor android:backupAllowed query Refactor the query to check for the nonexistence of the `android:allowBackup` attribute being set to false. The default value is true, so we need to check for it being explicitly marked false. --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index bb67ea04827..7911b1a8518 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -79,8 +79,6 @@ class AndroidApplicationXmlElement extends XmlElement { * https://developer.android.com/guide/topics/data/autobackup */ predicate allowsBackup() { - // The default value for the attribute `android:allowBackup` is `true`. - // Therefore we also check if it is not present. not exists(AndroidXmlAttribute attr | this.getAnAttribute() = attr and attr.getName() = "allowBackup" and From e6a1b1fab9400eca1722709116fecf19cc8de7ee Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Mon, 22 Aug 2022 12:06:30 -0400 Subject: [PATCH 019/203] Rename allowBackup query id Co-authored-by: Tony Torralba --- java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 88fdeb2a890..6e015c7a237 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -4,7 +4,7 @@ * @kind problem * @problem.severity recommendation * @security-severity 7.5 - * @id java/android/allowBackup-attribute-enabled + * @id java/android/allowbackup-enabled * @tags security * external/cwe/cwe-312 * @precision very-high From 59773eb74354ec7efb99d6b9b76d71f03302b031 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 24 Aug 2022 13:27:53 +0200 Subject: [PATCH 020/203] Ruby: update tree-sitter grammar --- ruby/Cargo.lock | Bin 17026 -> 17026 bytes ruby/extractor/Cargo.toml | 2 +- ruby/generator/Cargo.toml | 2 +- ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll | 32 +- .../lib/codeql/ruby/ast/internal/Method.qll | 2 +- .../codeql/ruby/ast/internal/TreeSitter.qll | 86 +- .../lib/codeql/ruby/ast/internal/Variable.qll | 18 +- ruby/ql/lib/ruby.dbscheme | 128 +- .../library-tests/ast/TreeSitter.expected | 1990 +++++++++-------- 9 files changed, 1188 insertions(+), 1072 deletions(-) diff --git a/ruby/Cargo.lock b/ruby/Cargo.lock index 2e2f205ce02d55c258997a789cd3d05da974ffdf..ed1b9e2bd3b787571a9a2a0d6b7bc7122cec0fce 100644 GIT binary patch delta 100 zcmZo_Wo&9?+_1_vFfql@z{J?d!Z^t=%`zo1%_K1~#n{3y$t=;rFwM{+(KOM>JT28c SRhd|YlM^LGHw)Mmu>b%9EFGQz delta 99 zcmZo_Wo&9?+_1_vAl2M7#lXbGz$Do+CB@t@F~!Wn!qgzeG}+ADD9OmkEX6d{%+e&y SSeZzLlM^JwHVfDlu>b&`R~x(l diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index c1a7c4424b9..a5c753b6398 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -11,7 +11,7 @@ flate2 = "1.0" node-types = { path = "../node-types" } tree-sitter = "0.19" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "1a538da253d73f896b9f6c0c7d79cda58791ac5c" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "e75d04404c9dd71ad68850d5c672b226d5e694f3" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "ad1043283b1f9daf4aad381b6a81f18a5a27fe7e" } clap = "3.0" tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } diff --git a/ruby/generator/Cargo.toml b/ruby/generator/Cargo.toml index 5a70c43d7b3..493557e03d4 100644 --- a/ruby/generator/Cargo.toml +++ b/ruby/generator/Cargo.toml @@ -12,4 +12,4 @@ node-types = { path = "../node-types" } tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "1a538da253d73f896b9f6c0c7d79cda58791ac5c" } -tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "e75d04404c9dd71ad68850d5c672b226d5e694f3" } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "ad1043283b1f9daf4aad381b6a81f18a5a27fe7e" } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll index 167f5f90d1e..93cb8961f81 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll @@ -51,25 +51,35 @@ class Ensure extends StmtSequence, TEnsure { // Not defined by dispatch, as it should not be exposed Ruby::AstNode getBodyStmtChild(TBodyStmt b, int i) { - result = any(Ruby::Method g | b = TMethod(g)).getChild(i) - or - result = any(Ruby::SingletonMethod g | b = TSingletonMethod(g)).getChild(i) - or - exists(Ruby::Lambda g | b = TLambda(g) | - result = g.getBody().(Ruby::DoBlock).getChild(i) or - result = g.getBody().(Ruby::Block).getChild(i) + exists(Ruby::Method g, Ruby::AstNode body | b = TMethod(g) and body = g.getBody() | + result = body.(Ruby::BodyStatement).getChild(i) + or + i = 0 and result = body and not body instanceof Ruby::BodyStatement ) or - result = any(Ruby::DoBlock g | b = TDoBlock(g)).getChild(i) + exists(Ruby::SingletonMethod g, Ruby::AstNode body | + b = TSingletonMethod(g) and body = g.getBody() + | + result = body.(Ruby::BodyStatement).getChild(i) + or + i = 0 and result = body and not body instanceof Ruby::BodyStatement + ) + or + exists(Ruby::Lambda g | b = TLambda(g) | + result = g.getBody().(Ruby::DoBlock).getBody().getChild(i) or + result = g.getBody().(Ruby::Block).getBody().getChild(i) + ) + or + result = any(Ruby::DoBlock g | b = TDoBlock(g)).getBody().getChild(i) or result = any(Ruby::Program g | b = TToplevel(g)).getChild(i) and not result instanceof Ruby::BeginBlock or - result = any(Ruby::Class g | b = TClassDeclaration(g)).getChild(i) + result = any(Ruby::Class g | b = TClassDeclaration(g)).getBody().getChild(i) or - result = any(Ruby::SingletonClass g | b = TSingletonClass(g)).getChild(i) + result = any(Ruby::SingletonClass g | b = TSingletonClass(g)).getBody().getChild(i) or - result = any(Ruby::Module g | b = TModuleDeclaration(g)).getChild(i) + result = any(Ruby::Module g | b = TModuleDeclaration(g)).getBody().getChild(i) or result = any(Ruby::Begin g | b = TBeginExpr(g)).getChild(i) } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll index 0b923056441..075ac5fb8fa 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Method.qll @@ -15,7 +15,7 @@ class BraceBlockReal extends BraceBlock, TBraceBlockReal { toGenerated(result) = g.getParameters().getChild(n) } - final override Stmt getStmt(int i) { toGenerated(result) = g.getChild(i) } + final override Stmt getStmt(int i) { toGenerated(result) = g.getBody().getChild(i) } } /** diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll b/ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll index 7a3b6ef43ef..7d76c3d701a 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll @@ -311,15 +311,15 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Block" } + /** Gets the node corresponding to the field `body`. */ + final BlockBody getBody() { ruby_block_body(this, result) } + /** Gets the node corresponding to the field `parameters`. */ final BlockParameters getParameters() { ruby_block_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_block_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - ruby_block_parameters(this, result) or ruby_block_child(this, _, result) + ruby_block_body(this, result) or ruby_block_parameters(this, result) } } @@ -335,6 +335,18 @@ module Ruby { final override AstNode getAFieldOrChild() { ruby_block_argument_child(this, result) } } + /** A class representing `block_body` nodes. */ + class BlockBody extends @ruby_block_body, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "BlockBody" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { ruby_block_body_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { ruby_block_body_child(this, _, result) } + } + /** A class representing `block_parameter` nodes. */ class BlockParameter extends @ruby_block_parameter, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -364,6 +376,18 @@ module Ruby { } } + /** A class representing `body_statement` nodes. */ + class BodyStatement extends @ruby_body_statement, AstNode { + /** Gets the name of the primary QL class for this element. */ + final override string getAPrimaryQlClass() { result = "BodyStatement" } + + /** Gets the `i`th child of this node. */ + final AstNode getChild(int i) { ruby_body_statement_child(this, i, result) } + + /** Gets a field or child node of this node. */ + final override AstNode getAFieldOrChild() { ruby_body_statement_child(this, _, result) } + } + /** A class representing `break` nodes. */ class Break extends @ruby_break, AstNode { /** Gets the name of the primary QL class for this element. */ @@ -468,20 +492,20 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Class" } + /** Gets the node corresponding to the field `body`. */ + final BodyStatement getBody() { ruby_class_body(this, result) } + /** Gets the node corresponding to the field `name`. */ final AstNode getName() { ruby_class_def(this, result) } /** Gets the node corresponding to the field `superclass`. */ final Superclass getSuperclass() { ruby_class_superclass(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_class_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + ruby_class_body(this, result) or ruby_class_def(this, result) or - ruby_class_superclass(this, result) or - ruby_class_child(this, _, result) + ruby_class_superclass(this, result) } } @@ -592,15 +616,15 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "DoBlock" } + /** Gets the node corresponding to the field `body`. */ + final BodyStatement getBody() { ruby_do_block_body(this, result) } + /** Gets the node corresponding to the field `parameters`. */ final BlockParameters getParameters() { ruby_do_block_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_do_block_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - ruby_do_block_parameters(this, result) or ruby_do_block_child(this, _, result) + ruby_do_block_body(this, result) or ruby_do_block_parameters(this, result) } } @@ -1106,20 +1130,20 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Method" } + /** Gets the node corresponding to the field `body`. */ + final AstNode getBody() { ruby_method_body(this, result) } + /** Gets the node corresponding to the field `name`. */ final UnderscoreMethodName getName() { ruby_method_def(this, result) } /** Gets the node corresponding to the field `parameters`. */ final MethodParameters getParameters() { ruby_method_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_method_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + ruby_method_body(this, result) or ruby_method_def(this, result) or - ruby_method_parameters(this, result) or - ruby_method_child(this, _, result) + ruby_method_parameters(this, result) } } @@ -1140,15 +1164,15 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "Module" } + /** Gets the node corresponding to the field `body`. */ + final BodyStatement getBody() { ruby_module_body(this, result) } + /** Gets the node corresponding to the field `name`. */ final AstNode getName() { ruby_module_def(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_module_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - ruby_module_def(this, result) or ruby_module_child(this, _, result) + ruby_module_body(this, result) or ruby_module_def(this, result) } } @@ -1504,15 +1528,15 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SingletonClass" } + /** Gets the node corresponding to the field `body`. */ + final BodyStatement getBody() { ruby_singleton_class_body(this, result) } + /** Gets the node corresponding to the field `value`. */ final UnderscoreArg getValue() { ruby_singleton_class_def(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_singleton_class_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { - ruby_singleton_class_def(this, result) or ruby_singleton_class_child(this, _, result) + ruby_singleton_class_body(this, result) or ruby_singleton_class_def(this, result) } } @@ -1521,6 +1545,9 @@ module Ruby { /** Gets the name of the primary QL class for this element. */ final override string getAPrimaryQlClass() { result = "SingletonMethod" } + /** Gets the node corresponding to the field `body`. */ + final AstNode getBody() { ruby_singleton_method_body(this, result) } + /** Gets the node corresponding to the field `name`. */ final UnderscoreMethodName getName() { ruby_singleton_method_def(this, result, _) } @@ -1530,15 +1557,12 @@ module Ruby { /** Gets the node corresponding to the field `parameters`. */ final MethodParameters getParameters() { ruby_singleton_method_parameters(this, result) } - /** Gets the `i`th child of this node. */ - final AstNode getChild(int i) { ruby_singleton_method_child(this, i, result) } - /** Gets a field or child node of this node. */ final override AstNode getAFieldOrChild() { + ruby_singleton_method_body(this, result) or ruby_singleton_method_def(this, result, _) or ruby_singleton_method_def(this, _, result) or - ruby_singleton_method_parameters(this, result) or - ruby_singleton_method_child(this, _, result) + ruby_singleton_method_parameters(this, result) } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll index 64fcdbd669a..9e1e2c38de9 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Variable.qll @@ -200,18 +200,18 @@ private module Cached { or i = any(Ruby::Binary x).getRight() or - i = any(Ruby::Block x).getChild(_) - or i = any(Ruby::BlockArgument x).getChild() or + i = any(Ruby::BlockBody x).getChild(_) + or + i = any(Ruby::BodyStatement x).getChild(_) + or i = any(Ruby::Call x).getReceiver() or i = any(Ruby::Case x).getValue() or i = any(Ruby::CaseMatch x).getValue() or - i = any(Ruby::Class x).getChild(_) - or i = any(Ruby::Conditional x).getCondition() or i = any(Ruby::Conditional x).getConsequence() @@ -220,8 +220,6 @@ private module Cached { or i = any(Ruby::Do x).getChild(_) or - i = any(Ruby::DoBlock x).getChild(_) - or i = any(Ruby::ElementReference x).getChild(_) or i = any(Ruby::ElementReference x).getObject() @@ -250,9 +248,7 @@ private module Cached { or i = any(Ruby::KeywordParameter x).getValue() or - i = any(Ruby::Method x).getChild(_) - or - i = any(Ruby::Module x).getChild(_) + i = any(Ruby::Method x).getBody() or i = any(Ruby::OperatorAssignment x).getRight() or @@ -282,9 +278,7 @@ private module Cached { or i = any(Ruby::SingletonClass x).getValue() or - i = any(Ruby::SingletonClass x).getChild(_) - or - i = any(Ruby::SingletonMethod x).getChild(_) + i = any(Ruby::SingletonMethod x).getBody() or i = any(Ruby::SingletonMethod x).getObject() or diff --git a/ruby/ql/lib/ruby.dbscheme b/ruby/ql/lib/ruby.dbscheme index 4ba51641799..3595c826de6 100644 --- a/ruby/ql/lib/ruby.dbscheme +++ b/ruby/ql/lib/ruby.dbscheme @@ -247,20 +247,16 @@ ruby_binary_def( int right: @ruby_underscore_expression ref ); +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + ruby_block_parameters( unique int ruby_block: @ruby_block ref, unique int parameters: @ruby_block_parameters ref ); -@ruby_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement - -#keyset[ruby_block, index] -ruby_block_child( - int ruby_block: @ruby_block ref, - int index: int ref, - unique int child: @ruby_block_child_type ref -); - ruby_block_def( unique int id: @ruby_block ); @@ -274,6 +270,19 @@ ruby_block_argument_def( unique int id: @ruby_block_argument ); +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + ruby_block_parameter_name( unique int ruby_block_parameter: @ruby_block_parameter ref, unique int name: @ruby_token_identifier ref @@ -303,6 +312,19 @@ ruby_block_parameters_def( unique int id: @ruby_block_parameters ); +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + ruby_break_child( unique int ruby_break: @ruby_break ref, unique int child: @ruby_argument_list ref @@ -391,6 +413,11 @@ ruby_chained_string_def( unique int id: @ruby_chained_string ); +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + @ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant ruby_class_superclass( @@ -398,15 +425,6 @@ ruby_class_superclass( unique int superclass: @ruby_superclass ref ); -@ruby_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement - -#keyset[ruby_class, index] -ruby_class_child( - int ruby_class: @ruby_class ref, - int index: int ref, - unique int child: @ruby_class_child_type ref -); - ruby_class_def( unique int id: @ruby_class, int name: @ruby_class_name_type ref @@ -478,20 +496,16 @@ ruby_do_def( unique int id: @ruby_do ); +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + ruby_do_block_parameters( unique int ruby_do_block: @ruby_do_block ref, unique int parameters: @ruby_block_parameters ref ); -@ruby_do_block_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement - -#keyset[ruby_do_block, index] -ruby_do_block_child( - int ruby_do_block: @ruby_do_block ref, - int index: int ref, - unique int child: @ruby_do_block_child_type ref -); - ruby_do_block_def( unique int id: @ruby_do_block ); @@ -724,7 +738,7 @@ ruby_in_clause_def( int pattern: @ruby_underscore_pattern_top_expr_body ref ); -@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_statement +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement #keyset[ruby_interpolation, index] ruby_interpolation_child( @@ -797,20 +811,18 @@ ruby_left_assignment_list_def( unique int id: @ruby_left_assignment_list ); +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + ruby_method_parameters( unique int ruby_method: @ruby_method ref, unique int parameters: @ruby_method_parameters ref ); -@ruby_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement - -#keyset[ruby_method, index] -ruby_method_child( - int ruby_method: @ruby_method ref, - int index: int ref, - unique int child: @ruby_method_child_type ref -); - ruby_method_def( unique int id: @ruby_method, int name: @ruby_underscore_method_name ref @@ -829,17 +841,13 @@ ruby_method_parameters_def( unique int id: @ruby_method_parameters ); -@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant - -@ruby_module_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement - -#keyset[ruby_module, index] -ruby_module_child( - int ruby_module: @ruby_module ref, - int index: int ref, - unique int child: @ruby_module_child_type ref +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref ); +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + ruby_module_def( unique int id: @ruby_module, int name: @ruby_module_name_type ref @@ -1074,13 +1082,9 @@ ruby_setter_def( int name: @ruby_token_identifier ref ); -@ruby_singleton_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement - -#keyset[ruby_singleton_class, index] -ruby_singleton_class_child( - int ruby_singleton_class: @ruby_singleton_class ref, - int index: int ref, - unique int child: @ruby_singleton_class_child_type ref +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref ); ruby_singleton_class_def( @@ -1088,6 +1092,13 @@ ruby_singleton_class_def( int value: @ruby_underscore_arg ref ); +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + @ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable ruby_singleton_method_parameters( @@ -1095,15 +1106,6 @@ ruby_singleton_method_parameters( unique int parameters: @ruby_method_parameters ref ); -@ruby_singleton_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement - -#keyset[ruby_singleton_method, index] -ruby_singleton_method_child( - int ruby_singleton_method: @ruby_singleton_method ref, - int index: int ref, - unique int child: @ruby_singleton_method_child_type ref -); - ruby_singleton_method_def( unique int id: @ruby_singleton_method, int name: @ruby_underscore_method_name ref, @@ -1344,7 +1346,7 @@ case @ruby_token.kind of ; -@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_parameter | @ruby_block_parameters | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield @ruby_ast_node_parent = @file | @ruby_ast_node diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index cb5a17ebebb..bca7b42046c 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -37,10 +37,11 @@ calls/calls.rb: # 17| 0: [ReservedWord] | # 17| 1: [Identifier] x # 17| 2: [ReservedWord] | -# 17| 2: [Binary] Binary -# 17| 0: [Identifier] x -# 17| 1: [ReservedWord] + -# 17| 2: [Integer] 1 +# 17| 2: [BlockBody] BlockBody +# 17| 0: [Binary] Binary +# 17| 0: [Identifier] x +# 17| 1: [ReservedWord] + +# 17| 2: [Integer] 1 # 17| 3: [ReservedWord] } # 20| 6: [Call] Call # 20| 0: [Identifier] foo @@ -50,10 +51,11 @@ calls/calls.rb: # 20| 0: [ReservedWord] | # 20| 1: [Identifier] x # 20| 2: [ReservedWord] | -# 21| 2: [Binary] Binary -# 21| 0: [Identifier] x -# 21| 1: [ReservedWord] + -# 21| 2: [Integer] 1 +# 21| 2: [BodyStatement] BodyStatement +# 21| 0: [Binary] Binary +# 21| 0: [Identifier] x +# 21| 1: [ReservedWord] + +# 21| 2: [Integer] 1 # 22| 3: [ReservedWord] end # 25| 7: [Call] Call # 25| 0: [Integer] 123 @@ -72,26 +74,29 @@ calls/calls.rb: # 25| 0: [ReservedWord] | # 25| 1: [Identifier] x # 25| 2: [ReservedWord] | -# 26| 2: [Binary] Binary -# 26| 0: [Identifier] x -# 26| 1: [ReservedWord] + -# 26| 2: [Integer] 1 +# 26| 2: [BodyStatement] BodyStatement +# 26| 0: [Binary] Binary +# 26| 0: [Identifier] x +# 26| 1: [ReservedWord] + +# 26| 2: [Integer] 1 # 27| 3: [ReservedWord] end # 30| 8: [Method] Method # 30| 0: [ReservedWord] def # 30| 1: [Identifier] method_that_yields -# 31| 2: [Yield] Yield -# 31| 0: [ReservedWord] yield +# 31| 2: [BodyStatement] BodyStatement +# 31| 0: [Yield] Yield +# 31| 0: [ReservedWord] yield # 32| 3: [ReservedWord] end # 35| 9: [Method] Method # 35| 0: [ReservedWord] def # 35| 1: [Identifier] another_method_that_yields -# 36| 2: [Yield] Yield -# 36| 0: [ReservedWord] yield -# 36| 1: [ArgumentList] ArgumentList -# 36| 0: [Integer] 100 -# 36| 1: [ReservedWord] , -# 36| 2: [Integer] 200 +# 36| 2: [BodyStatement] BodyStatement +# 36| 0: [Yield] Yield +# 36| 0: [ReservedWord] yield +# 36| 1: [ArgumentList] ArgumentList +# 36| 0: [Integer] 100 +# 36| 1: [ReservedWord] , +# 36| 2: [Integer] 200 # 37| 3: [ReservedWord] end # 46| 10: [Identifier] foo # 47| 11: [Call] Call @@ -218,13 +223,14 @@ calls/calls.rb: # 92| 1: [ReservedWord] ) # 92| 2: [Block] Block # 92| 0: [ReservedWord] { -# 92| 1: [Identifier] bar -# 92| 2: [ReservedWord] ; -# 92| 3: [Call] Call -# 92| 0: [Constant] X -# 92| 1: [ReservedWord] :: -# 92| 2: [Identifier] baz -# 92| 4: [ReservedWord] } +# 92| 1: [BlockBody] BlockBody +# 92| 0: [Identifier] bar +# 92| 1: [ReservedWord] ; +# 92| 2: [Call] Call +# 92| 0: [Constant] X +# 92| 1: [ReservedWord] :: +# 92| 2: [Identifier] baz +# 92| 2: [ReservedWord] } # 95| 30: [Call] Call # 95| 0: [Identifier] foo # 95| 1: [ArgumentList] ArgumentList @@ -232,12 +238,13 @@ calls/calls.rb: # 95| 1: [ReservedWord] ) # 95| 2: [DoBlock] DoBlock # 95| 0: [ReservedWord] do -# 96| 1: [Identifier] bar -# 97| 2: [Call] Call -# 97| 0: [Constant] X -# 97| 1: [ReservedWord] :: -# 97| 2: [Identifier] baz -# 98| 3: [ReservedWord] end +# 96| 1: [BodyStatement] BodyStatement +# 96| 0: [Identifier] bar +# 97| 1: [Call] Call +# 97| 0: [Constant] X +# 97| 1: [ReservedWord] :: +# 97| 2: [Identifier] baz +# 98| 2: [ReservedWord] end # 101| 31: [Call] Call # 101| 0: [Identifier] foo # 101| 1: [ReservedWord] . @@ -284,12 +291,13 @@ calls/calls.rb: # 116| 35: [Class] Class # 116| 0: [ReservedWord] class # 116| 1: [Constant] MyClass -# 117| 2: [Identifier] foo -# 118| 3: [Call] Call -# 118| 0: [Constant] X -# 118| 1: [ReservedWord] :: -# 118| 2: [Identifier] bar -# 119| 4: [ReservedWord] end +# 117| 2: [BodyStatement] BodyStatement +# 117| 0: [Identifier] foo +# 118| 1: [Call] Call +# 118| 0: [Constant] X +# 118| 1: [ReservedWord] :: +# 118| 2: [Identifier] bar +# 119| 3: [ReservedWord] end # 122| 36: [Class] Class # 122| 0: [ReservedWord] class # 122| 1: [Constant] MyClass @@ -311,7 +319,8 @@ calls/calls.rb: # 128| 0: [ReservedWord] class # 128| 1: [ReservedWord] << # 128| 2: [Identifier] foo -# 129| 3: [Identifier] bar +# 129| 3: [BodyStatement] BodyStatement +# 129| 0: [Identifier] bar # 130| 4: [ReservedWord] end # 131| 39: [SingletonClass] SingletonClass # 131| 0: [ReservedWord] class @@ -320,31 +329,34 @@ calls/calls.rb: # 131| 0: [Constant] X # 131| 1: [ReservedWord] :: # 131| 2: [Identifier] foo -# 132| 3: [Call] Call -# 132| 0: [Constant] X -# 132| 1: [ReservedWord] :: -# 132| 2: [Identifier] bar +# 132| 3: [BodyStatement] BodyStatement +# 132| 0: [Call] Call +# 132| 0: [Constant] X +# 132| 1: [ReservedWord] :: +# 132| 2: [Identifier] bar # 133| 4: [ReservedWord] end # 136| 40: [Method] Method # 136| 0: [ReservedWord] def # 136| 1: [Identifier] some_method -# 137| 2: [Identifier] foo -# 138| 3: [Call] Call -# 138| 0: [Constant] X -# 138| 1: [ReservedWord] :: -# 138| 2: [Identifier] bar -# 139| 4: [ReservedWord] end +# 137| 2: [BodyStatement] BodyStatement +# 137| 0: [Identifier] foo +# 138| 1: [Call] Call +# 138| 0: [Constant] X +# 138| 1: [ReservedWord] :: +# 138| 2: [Identifier] bar +# 139| 3: [ReservedWord] end # 142| 41: [SingletonMethod] SingletonMethod # 142| 0: [ReservedWord] def # 142| 1: [Identifier] foo # 142| 2: [ReservedWord] . # 142| 3: [Identifier] some_method -# 143| 4: [Identifier] bar -# 144| 5: [Call] Call -# 144| 0: [Constant] X -# 144| 1: [ReservedWord] :: -# 144| 2: [Identifier] baz -# 145| 6: [ReservedWord] end +# 143| 4: [BodyStatement] BodyStatement +# 143| 0: [Identifier] bar +# 144| 1: [Call] Call +# 144| 0: [Constant] X +# 144| 1: [ReservedWord] :: +# 144| 2: [Identifier] baz +# 145| 5: [ReservedWord] end # 148| 42: [Method] Method # 148| 0: [ReservedWord] def # 148| 1: [Identifier] method_with_keyword_param @@ -398,12 +410,13 @@ calls/calls.rb: # 160| 46: [Module] Module # 160| 0: [ReservedWord] module # 160| 1: [Constant] SomeModule -# 161| 2: [Identifier] foo -# 162| 3: [Call] Call -# 162| 0: [Constant] X -# 162| 1: [ReservedWord] :: -# 162| 2: [Identifier] bar -# 163| 4: [ReservedWord] end +# 161| 2: [BodyStatement] BodyStatement +# 161| 0: [Identifier] foo +# 162| 1: [Call] Call +# 162| 0: [Constant] X +# 162| 1: [ReservedWord] :: +# 162| 2: [Identifier] bar +# 163| 3: [ReservedWord] end # 166| 47: [Conditional] Conditional # 166| 0: [Identifier] foo # 166| 1: [ReservedWord] ? @@ -809,111 +822,119 @@ calls/calls.rb: # 284| 88: [Class] Class # 284| 0: [ReservedWord] class # 284| 1: [Constant] MyClass -# 285| 2: [Method] Method -# 285| 0: [ReservedWord] def -# 285| 1: [Identifier] my_method -# 286| 2: [Super] super -# 287| 3: [Call] Call -# 287| 0: [Super] super -# 287| 1: [ArgumentList] ArgumentList -# 287| 0: [ReservedWord] ( -# 287| 1: [ReservedWord] ) -# 288| 4: [Call] Call -# 288| 0: [Super] super -# 288| 1: [ArgumentList] ArgumentList -# 288| 0: [String] String -# 288| 0: [ReservedWord] ' -# 288| 1: [StringContent] blah -# 288| 2: [ReservedWord] ' -# 289| 5: [Call] Call -# 289| 0: [Super] super -# 289| 1: [ArgumentList] ArgumentList -# 289| 0: [Integer] 1 -# 289| 1: [ReservedWord] , -# 289| 2: [Integer] 2 -# 289| 3: [ReservedWord] , -# 289| 4: [Integer] 3 -# 290| 6: [Call] Call -# 290| 0: [Super] super -# 290| 1: [Block] Block -# 290| 0: [ReservedWord] { -# 290| 1: [BlockParameters] BlockParameters -# 290| 0: [ReservedWord] | -# 290| 1: [Identifier] x -# 290| 2: [ReservedWord] | -# 290| 2: [Binary] Binary -# 290| 0: [Identifier] x -# 290| 1: [ReservedWord] + -# 290| 2: [Integer] 1 -# 290| 3: [ReservedWord] } -# 291| 7: [Call] Call -# 291| 0: [Super] super -# 291| 1: [DoBlock] DoBlock -# 291| 0: [ReservedWord] do -# 291| 1: [BlockParameters] BlockParameters -# 291| 0: [ReservedWord] | -# 291| 1: [Identifier] x -# 291| 2: [ReservedWord] | -# 291| 2: [Binary] Binary -# 291| 0: [Identifier] x -# 291| 1: [ReservedWord] * -# 291| 2: [Integer] 2 -# 291| 3: [ReservedWord] end -# 292| 8: [Call] Call -# 292| 0: [Super] super -# 292| 1: [ArgumentList] ArgumentList -# 292| 0: [Integer] 4 -# 292| 1: [ReservedWord] , -# 292| 2: [Integer] 5 -# 292| 2: [Block] Block -# 292| 0: [ReservedWord] { -# 292| 1: [BlockParameters] BlockParameters -# 292| 0: [ReservedWord] | -# 292| 1: [Identifier] x -# 292| 2: [ReservedWord] | -# 292| 2: [Binary] Binary -# 292| 0: [Identifier] x -# 292| 1: [ReservedWord] + -# 292| 2: [Integer] 100 -# 292| 3: [ReservedWord] } -# 293| 9: [Call] Call -# 293| 0: [Super] super -# 293| 1: [ArgumentList] ArgumentList -# 293| 0: [Integer] 6 -# 293| 1: [ReservedWord] , -# 293| 2: [Integer] 7 -# 293| 2: [DoBlock] DoBlock -# 293| 0: [ReservedWord] do -# 293| 1: [BlockParameters] BlockParameters -# 293| 0: [ReservedWord] | -# 293| 1: [Identifier] x -# 293| 2: [ReservedWord] | -# 293| 2: [Binary] Binary -# 293| 0: [Identifier] x -# 293| 1: [ReservedWord] + -# 293| 2: [Integer] 200 -# 293| 3: [ReservedWord] end -# 294| 10: [ReservedWord] end +# 285| 2: [BodyStatement] BodyStatement +# 285| 0: [Method] Method +# 285| 0: [ReservedWord] def +# 285| 1: [Identifier] my_method +# 286| 2: [BodyStatement] BodyStatement +# 286| 0: [Super] super +# 287| 1: [Call] Call +# 287| 0: [Super] super +# 287| 1: [ArgumentList] ArgumentList +# 287| 0: [ReservedWord] ( +# 287| 1: [ReservedWord] ) +# 288| 2: [Call] Call +# 288| 0: [Super] super +# 288| 1: [ArgumentList] ArgumentList +# 288| 0: [String] String +# 288| 0: [ReservedWord] ' +# 288| 1: [StringContent] blah +# 288| 2: [ReservedWord] ' +# 289| 3: [Call] Call +# 289| 0: [Super] super +# 289| 1: [ArgumentList] ArgumentList +# 289| 0: [Integer] 1 +# 289| 1: [ReservedWord] , +# 289| 2: [Integer] 2 +# 289| 3: [ReservedWord] , +# 289| 4: [Integer] 3 +# 290| 4: [Call] Call +# 290| 0: [Super] super +# 290| 1: [Block] Block +# 290| 0: [ReservedWord] { +# 290| 1: [BlockParameters] BlockParameters +# 290| 0: [ReservedWord] | +# 290| 1: [Identifier] x +# 290| 2: [ReservedWord] | +# 290| 2: [BlockBody] BlockBody +# 290| 0: [Binary] Binary +# 290| 0: [Identifier] x +# 290| 1: [ReservedWord] + +# 290| 2: [Integer] 1 +# 290| 3: [ReservedWord] } +# 291| 5: [Call] Call +# 291| 0: [Super] super +# 291| 1: [DoBlock] DoBlock +# 291| 0: [ReservedWord] do +# 291| 1: [BlockParameters] BlockParameters +# 291| 0: [ReservedWord] | +# 291| 1: [Identifier] x +# 291| 2: [ReservedWord] | +# 291| 2: [BodyStatement] BodyStatement +# 291| 0: [Binary] Binary +# 291| 0: [Identifier] x +# 291| 1: [ReservedWord] * +# 291| 2: [Integer] 2 +# 291| 3: [ReservedWord] end +# 292| 6: [Call] Call +# 292| 0: [Super] super +# 292| 1: [ArgumentList] ArgumentList +# 292| 0: [Integer] 4 +# 292| 1: [ReservedWord] , +# 292| 2: [Integer] 5 +# 292| 2: [Block] Block +# 292| 0: [ReservedWord] { +# 292| 1: [BlockParameters] BlockParameters +# 292| 0: [ReservedWord] | +# 292| 1: [Identifier] x +# 292| 2: [ReservedWord] | +# 292| 2: [BlockBody] BlockBody +# 292| 0: [Binary] Binary +# 292| 0: [Identifier] x +# 292| 1: [ReservedWord] + +# 292| 2: [Integer] 100 +# 292| 3: [ReservedWord] } +# 293| 7: [Call] Call +# 293| 0: [Super] super +# 293| 1: [ArgumentList] ArgumentList +# 293| 0: [Integer] 6 +# 293| 1: [ReservedWord] , +# 293| 2: [Integer] 7 +# 293| 2: [DoBlock] DoBlock +# 293| 0: [ReservedWord] do +# 293| 1: [BlockParameters] BlockParameters +# 293| 0: [ReservedWord] | +# 293| 1: [Identifier] x +# 293| 2: [ReservedWord] | +# 293| 2: [BodyStatement] BodyStatement +# 293| 0: [Binary] Binary +# 293| 0: [Identifier] x +# 293| 1: [ReservedWord] + +# 293| 2: [Integer] 200 +# 293| 3: [ReservedWord] end +# 294| 3: [ReservedWord] end # 295| 3: [ReservedWord] end # 301| 89: [Class] Class # 301| 0: [ReservedWord] class # 301| 1: [Constant] AnotherClass -# 302| 2: [Method] Method -# 302| 0: [ReservedWord] def -# 302| 1: [Identifier] another_method -# 303| 2: [Call] Call -# 303| 0: [Identifier] foo -# 303| 1: [ReservedWord] . -# 303| 2: [Identifier] super -# 304| 3: [Call] Call -# 304| 0: [Self] self -# 304| 1: [ReservedWord] . -# 304| 2: [Identifier] super -# 305| 4: [Call] Call -# 305| 0: [Super] super -# 305| 1: [ReservedWord] . -# 305| 2: [Identifier] super -# 306| 5: [ReservedWord] end +# 302| 2: [BodyStatement] BodyStatement +# 302| 0: [Method] Method +# 302| 0: [ReservedWord] def +# 302| 1: [Identifier] another_method +# 303| 2: [BodyStatement] BodyStatement +# 303| 0: [Call] Call +# 303| 0: [Identifier] foo +# 303| 1: [ReservedWord] . +# 303| 2: [Identifier] super +# 304| 1: [Call] Call +# 304| 0: [Self] self +# 304| 1: [ReservedWord] . +# 304| 2: [Identifier] super +# 305| 2: [Call] Call +# 305| 0: [Super] super +# 305| 1: [ReservedWord] . +# 305| 2: [Identifier] super +# 306| 3: [ReservedWord] end # 307| 3: [ReservedWord] end # 310| 90: [Call] Call # 310| 0: [Identifier] foo @@ -1100,13 +1121,14 @@ calls/calls.rb: # 331| 1: [ForwardParameter] ... # 331| 0: [ReservedWord] ... # 331| 2: [ReservedWord] ) -# 332| 3: [Call] Call -# 332| 0: [Super] super -# 332| 1: [ArgumentList] ArgumentList -# 332| 0: [ReservedWord] ( -# 332| 1: [ForwardArgument] ... -# 332| 0: [ReservedWord] ... -# 332| 2: [ReservedWord] ) +# 332| 3: [BodyStatement] BodyStatement +# 332| 0: [Call] Call +# 332| 0: [Super] super +# 332| 1: [ArgumentList] ArgumentList +# 332| 0: [ReservedWord] ( +# 332| 1: [ForwardArgument] ... +# 332| 0: [ReservedWord] ... +# 332| 2: [ReservedWord] ) # 333| 4: [ReservedWord] end # 335| 106: [Method] Method # 335| 0: [ReservedWord] def @@ -1120,15 +1142,16 @@ calls/calls.rb: # 335| 5: [ForwardParameter] ... # 335| 0: [ReservedWord] ... # 335| 6: [ReservedWord] ) -# 336| 3: [Call] Call -# 336| 0: [Identifier] bar -# 336| 1: [ArgumentList] ArgumentList -# 336| 0: [ReservedWord] ( -# 336| 1: [Identifier] b -# 336| 2: [ReservedWord] , -# 336| 3: [ForwardArgument] ... -# 336| 0: [ReservedWord] ... -# 336| 4: [ReservedWord] ) +# 336| 3: [BodyStatement] BodyStatement +# 336| 0: [Call] Call +# 336| 0: [Identifier] bar +# 336| 1: [ArgumentList] ArgumentList +# 336| 0: [ReservedWord] ( +# 336| 1: [Identifier] b +# 336| 2: [ReservedWord] , +# 336| 3: [ForwardArgument] ... +# 336| 0: [ReservedWord] ... +# 336| 4: [ReservedWord] ) # 337| 4: [ReservedWord] end # 340| 107: [For] For # 340| 0: [ReservedWord] for @@ -1223,7 +1246,8 @@ calls/calls.rb: # 351| 2: [ReservedWord] ) # 351| 2: [Block] Block # 351| 0: [ReservedWord] { -# 351| 1: [Identifier] y +# 351| 1: [BlockBody] BlockBody +# 351| 0: [Identifier] y # 351| 2: [ReservedWord] } # 352| 114: [Assignment] Assignment # 352| 0: [Identifier] f @@ -1236,10 +1260,11 @@ calls/calls.rb: # 352| 2: [ReservedWord] ) # 352| 2: [Block] Block # 352| 0: [ReservedWord] { -# 352| 1: [Call] Call -# 352| 0: [Identifier] foo -# 352| 1: [ArgumentList] ArgumentList -# 352| 0: [Identifier] x +# 352| 1: [BlockBody] BlockBody +# 352| 0: [Call] Call +# 352| 0: [Identifier] foo +# 352| 1: [ArgumentList] ArgumentList +# 352| 0: [Identifier] x # 352| 2: [ReservedWord] } # 353| 115: [Assignment] Assignment # 353| 0: [Identifier] g @@ -1252,7 +1277,8 @@ calls/calls.rb: # 353| 2: [ReservedWord] ) # 353| 2: [Block] Block # 353| 0: [ReservedWord] { -# 353| 1: [Identifier] unknown_call +# 353| 1: [BlockBody] BlockBody +# 353| 0: [Identifier] unknown_call # 353| 2: [ReservedWord] } # 354| 116: [Assignment] Assignment # 354| 0: [Identifier] h @@ -1265,10 +1291,11 @@ calls/calls.rb: # 354| 2: [ReservedWord] ) # 354| 2: [DoBlock] DoBlock # 354| 0: [ReservedWord] do -# 355| 1: [Identifier] x -# 356| 2: [Identifier] y -# 357| 3: [Identifier] unknown_call -# 358| 4: [ReservedWord] end +# 355| 1: [BodyStatement] BodyStatement +# 355| 0: [Identifier] x +# 356| 1: [Identifier] y +# 357| 2: [Identifier] unknown_call +# 358| 2: [ReservedWord] end # 361| 117: [Call] Call # 361| 0: [Identifier] list # 361| 1: [ReservedWord] . @@ -1297,7 +1324,8 @@ calls/calls.rb: # 364| 0: [ReservedWord] | # 364| 1: [Identifier] x # 364| 2: [ReservedWord] | -# 364| 2: [Identifier] x +# 364| 2: [BlockBody] BlockBody +# 364| 0: [Identifier] x # 364| 3: [ReservedWord] } # 1| [Comment] # call with no receiver, arguments, or block # 4| [Comment] # call whose name is a scope resolution @@ -1378,49 +1406,52 @@ constants/constants.rb: # 1| 0: [Module] Module # 1| 0: [ReservedWord] module # 1| 1: [Constant] ModuleA -# 2| 2: [Class] Class -# 2| 0: [ReservedWord] class -# 2| 1: [Constant] ClassA -# 3| 2: [Assignment] Assignment -# 3| 0: [Constant] CONST_A -# 3| 1: [ReservedWord] = -# 3| 2: [String] String -# 3| 0: [ReservedWord] " -# 3| 1: [StringContent] const_a -# 3| 2: [ReservedWord] " -# 4| 3: [ReservedWord] end -# 6| 3: [Assignment] Assignment -# 6| 0: [Constant] CONST_B -# 6| 1: [ReservedWord] = -# 6| 2: [String] String -# 6| 0: [ReservedWord] " -# 6| 1: [StringContent] const_b -# 6| 2: [ReservedWord] " -# 8| 4: [Module] Module -# 8| 0: [ReservedWord] module -# 8| 1: [Constant] ModuleB -# 9| 2: [Class] Class -# 9| 0: [ReservedWord] class -# 9| 1: [Constant] ClassB -# 9| 2: [Superclass] Superclass -# 9| 0: [ReservedWord] < -# 9| 1: [Constant] Base -# 10| 3: [ReservedWord] end -# 12| 3: [Class] Class -# 12| 0: [ReservedWord] class -# 12| 1: [Constant] ClassC -# 12| 2: [Superclass] Superclass -# 12| 0: [ReservedWord] < -# 12| 1: [ScopeResolution] ScopeResolution -# 12| 0: [ScopeResolution] ScopeResolution -# 12| 0: [Constant] X -# 12| 1: [ReservedWord] :: -# 12| 2: [Constant] Y -# 12| 1: [ReservedWord] :: -# 12| 2: [Constant] Z -# 13| 3: [ReservedWord] end -# 14| 4: [ReservedWord] end -# 15| 5: [ReservedWord] end +# 2| 2: [BodyStatement] BodyStatement +# 2| 0: [Class] Class +# 2| 0: [ReservedWord] class +# 2| 1: [Constant] ClassA +# 3| 2: [BodyStatement] BodyStatement +# 3| 0: [Assignment] Assignment +# 3| 0: [Constant] CONST_A +# 3| 1: [ReservedWord] = +# 3| 2: [String] String +# 3| 0: [ReservedWord] " +# 3| 1: [StringContent] const_a +# 3| 2: [ReservedWord] " +# 4| 3: [ReservedWord] end +# 6| 1: [Assignment] Assignment +# 6| 0: [Constant] CONST_B +# 6| 1: [ReservedWord] = +# 6| 2: [String] String +# 6| 0: [ReservedWord] " +# 6| 1: [StringContent] const_b +# 6| 2: [ReservedWord] " +# 8| 2: [Module] Module +# 8| 0: [ReservedWord] module +# 8| 1: [Constant] ModuleB +# 9| 2: [BodyStatement] BodyStatement +# 9| 0: [Class] Class +# 9| 0: [ReservedWord] class +# 9| 1: [Constant] ClassB +# 9| 2: [Superclass] Superclass +# 9| 0: [ReservedWord] < +# 9| 1: [Constant] Base +# 10| 3: [ReservedWord] end +# 12| 1: [Class] Class +# 12| 0: [ReservedWord] class +# 12| 1: [Constant] ClassC +# 12| 2: [Superclass] Superclass +# 12| 0: [ReservedWord] < +# 12| 1: [ScopeResolution] ScopeResolution +# 12| 0: [ScopeResolution] ScopeResolution +# 12| 0: [Constant] X +# 12| 1: [ReservedWord] :: +# 12| 2: [Constant] Y +# 12| 1: [ReservedWord] :: +# 12| 2: [Constant] Z +# 13| 3: [ReservedWord] end +# 14| 3: [ReservedWord] end +# 15| 3: [ReservedWord] end # 17| 1: [Assignment] Assignment # 17| 0: [Constant] GREETING # 17| 1: [ReservedWord] = @@ -1446,62 +1477,64 @@ constants/constants.rb: # 19| 2: [Method] Method # 19| 0: [ReservedWord] def # 19| 1: [Identifier] foo -# 20| 2: [Assignment] Assignment -# 20| 0: [Constant] Names -# 20| 1: [ReservedWord] = -# 20| 2: [Array] Array -# 20| 0: [ReservedWord] [ -# 20| 1: [String] String -# 20| 0: [ReservedWord] ' -# 20| 1: [StringContent] Vera -# 20| 2: [ReservedWord] ' -# 20| 2: [ReservedWord] , -# 20| 3: [String] String -# 20| 0: [ReservedWord] ' -# 20| 1: [StringContent] Chuck -# 20| 2: [ReservedWord] ' -# 20| 4: [ReservedWord] , -# 20| 5: [String] String -# 20| 0: [ReservedWord] ' -# 20| 1: [StringContent] Dave -# 20| 2: [ReservedWord] ' -# 20| 6: [ReservedWord] ] -# 22| 3: [Call] Call -# 22| 0: [Constant] Names -# 22| 1: [ReservedWord] . -# 22| 2: [Identifier] each -# 22| 3: [DoBlock] DoBlock -# 22| 0: [ReservedWord] do -# 22| 1: [BlockParameters] BlockParameters -# 22| 0: [ReservedWord] | -# 22| 1: [Identifier] name -# 22| 2: [ReservedWord] | -# 23| 2: [Call] Call -# 23| 0: [Identifier] puts -# 23| 1: [ArgumentList] ArgumentList -# 23| 0: [String] String -# 23| 0: [ReservedWord] " -# 23| 1: [Interpolation] Interpolation -# 23| 0: [ReservedWord] #{ -# 23| 1: [Constant] GREETING -# 23| 2: [ReservedWord] } -# 23| 2: [StringContent] -# 23| 3: [Interpolation] Interpolation -# 23| 0: [ReservedWord] #{ -# 23| 1: [Identifier] name -# 23| 2: [ReservedWord] } -# 23| 4: [ReservedWord] " -# 24| 3: [ReservedWord] end -# 28| 4: [Call] Call -# 28| 0: [Constant] Array -# 28| 1: [ArgumentList] ArgumentList -# 28| 0: [ReservedWord] ( -# 28| 1: [String] String -# 28| 0: [ReservedWord] ' -# 28| 1: [StringContent] foo -# 28| 2: [ReservedWord] ' -# 28| 2: [ReservedWord] ) -# 29| 5: [ReservedWord] end +# 20| 2: [BodyStatement] BodyStatement +# 20| 0: [Assignment] Assignment +# 20| 0: [Constant] Names +# 20| 1: [ReservedWord] = +# 20| 2: [Array] Array +# 20| 0: [ReservedWord] [ +# 20| 1: [String] String +# 20| 0: [ReservedWord] ' +# 20| 1: [StringContent] Vera +# 20| 2: [ReservedWord] ' +# 20| 2: [ReservedWord] , +# 20| 3: [String] String +# 20| 0: [ReservedWord] ' +# 20| 1: [StringContent] Chuck +# 20| 2: [ReservedWord] ' +# 20| 4: [ReservedWord] , +# 20| 5: [String] String +# 20| 0: [ReservedWord] ' +# 20| 1: [StringContent] Dave +# 20| 2: [ReservedWord] ' +# 20| 6: [ReservedWord] ] +# 22| 1: [Call] Call +# 22| 0: [Constant] Names +# 22| 1: [ReservedWord] . +# 22| 2: [Identifier] each +# 22| 3: [DoBlock] DoBlock +# 22| 0: [ReservedWord] do +# 22| 1: [BlockParameters] BlockParameters +# 22| 0: [ReservedWord] | +# 22| 1: [Identifier] name +# 22| 2: [ReservedWord] | +# 23| 2: [BodyStatement] BodyStatement +# 23| 0: [Call] Call +# 23| 0: [Identifier] puts +# 23| 1: [ArgumentList] ArgumentList +# 23| 0: [String] String +# 23| 0: [ReservedWord] " +# 23| 1: [Interpolation] Interpolation +# 23| 0: [ReservedWord] #{ +# 23| 1: [Constant] GREETING +# 23| 2: [ReservedWord] } +# 23| 2: [StringContent] +# 23| 3: [Interpolation] Interpolation +# 23| 0: [ReservedWord] #{ +# 23| 1: [Identifier] name +# 23| 2: [ReservedWord] } +# 23| 4: [ReservedWord] " +# 24| 3: [ReservedWord] end +# 28| 2: [Call] Call +# 28| 0: [Constant] Array +# 28| 1: [ArgumentList] ArgumentList +# 28| 0: [ReservedWord] ( +# 28| 1: [String] String +# 28| 0: [ReservedWord] ' +# 28| 1: [StringContent] foo +# 28| 2: [ReservedWord] ' +# 28| 2: [ReservedWord] ) +# 29| 3: [ReservedWord] end # 31| 3: [Class] Class # 31| 0: [ReservedWord] class # 31| 1: [ScopeResolution] ScopeResolution @@ -1514,10 +1547,11 @@ constants/constants.rb: # 31| 0: [Constant] ModuleA # 31| 1: [ReservedWord] :: # 31| 2: [Constant] ClassA -# 32| 3: [Assignment] Assignment -# 32| 0: [Constant] FOURTY_TWO -# 32| 1: [ReservedWord] = -# 32| 2: [Integer] 42 +# 32| 3: [BodyStatement] BodyStatement +# 32| 0: [Assignment] Assignment +# 32| 0: [Constant] FOURTY_TWO +# 32| 1: [ReservedWord] = +# 32| 2: [Integer] 42 # 33| 4: [ReservedWord] end # 35| 4: [Module] Module # 35| 0: [ReservedWord] module @@ -1525,10 +1559,11 @@ constants/constants.rb: # 35| 0: [Constant] ModuleA # 35| 1: [ReservedWord] :: # 35| 2: [Constant] ModuleC -# 36| 2: [Assignment] Assignment -# 36| 0: [Constant] FOURTY_THREE -# 36| 1: [ReservedWord] = -# 36| 2: [Integer] 43 +# 36| 2: [BodyStatement] BodyStatement +# 36| 0: [Assignment] Assignment +# 36| 0: [Constant] FOURTY_THREE +# 36| 1: [ReservedWord] = +# 36| 2: [Integer] 43 # 37| 3: [ReservedWord] end # 39| 5: [Assignment] Assignment # 39| 0: [ScopeResolution] ScopeResolution @@ -1566,96 +1601,104 @@ constants/constants.rb: # 46| 0: [Constant] ModuleA # 46| 1: [ReservedWord] :: # 46| 2: [Constant] ModuleB -# 47| 2: [Class] Class -# 47| 0: [ReservedWord] class -# 47| 1: [Constant] ClassB -# 47| 2: [Superclass] Superclass -# 47| 0: [ReservedWord] < -# 47| 1: [Constant] Base -# 48| 3: [Assignment] Assignment -# 48| 0: [Constant] FOURTY_ONE -# 48| 1: [ReservedWord] = -# 48| 2: [Integer] 41 -# 49| 4: [ReservedWord] end +# 47| 2: [BodyStatement] BodyStatement +# 47| 0: [Class] Class +# 47| 0: [ReservedWord] class +# 47| 1: [Constant] ClassB +# 47| 2: [Superclass] Superclass +# 47| 0: [ReservedWord] < +# 47| 1: [Constant] Base +# 48| 3: [BodyStatement] BodyStatement +# 48| 0: [Assignment] Assignment +# 48| 0: [Constant] FOURTY_ONE +# 48| 1: [ReservedWord] = +# 48| 2: [Integer] 41 +# 49| 4: [ReservedWord] end # 50| 3: [ReservedWord] end # 52| 10: [Module] Module # 52| 0: [ReservedWord] module # 52| 1: [Constant] ModuleA -# 53| 2: [Assignment] Assignment -# 53| 0: [Constant] FOURTY_FOUR -# 53| 1: [ReservedWord] = -# 53| 2: [String] String -# 53| 0: [ReservedWord] " -# 53| 1: [StringContent] fourty-four -# 53| 2: [ReservedWord] " -# 54| 3: [Class] Class -# 54| 0: [ReservedWord] class -# 54| 1: [ScopeResolution] ScopeResolution -# 54| 0: [Constant] ModuleB -# 54| 1: [ReservedWord] :: -# 54| 2: [Constant] ClassB -# 54| 2: [Superclass] Superclass -# 54| 0: [ReservedWord] < -# 54| 1: [Constant] Base -# 55| 3: [Assignment] Assignment -# 55| 0: [ClassVariable] @@fourty_four -# 55| 1: [ReservedWord] = -# 55| 2: [Constant] FOURTY_FOUR -# 56| 4: [Assignment] Assignment -# 56| 0: [Constant] FOURTY_FOUR -# 56| 1: [ReservedWord] = -# 56| 2: [Integer] 44 -# 57| 5: [Assignment] Assignment -# 57| 0: [ClassVariable] @@fourty_four -# 57| 1: [ReservedWord] = -# 57| 2: [Constant] FOURTY_FOUR -# 58| 6: [ReservedWord] end -# 59| 4: [ReservedWord] end +# 53| 2: [BodyStatement] BodyStatement +# 53| 0: [Assignment] Assignment +# 53| 0: [Constant] FOURTY_FOUR +# 53| 1: [ReservedWord] = +# 53| 2: [String] String +# 53| 0: [ReservedWord] " +# 53| 1: [StringContent] fourty-four +# 53| 2: [ReservedWord] " +# 54| 1: [Class] Class +# 54| 0: [ReservedWord] class +# 54| 1: [ScopeResolution] ScopeResolution +# 54| 0: [Constant] ModuleB +# 54| 1: [ReservedWord] :: +# 54| 2: [Constant] ClassB +# 54| 2: [Superclass] Superclass +# 54| 0: [ReservedWord] < +# 54| 1: [Constant] Base +# 55| 3: [BodyStatement] BodyStatement +# 55| 0: [Assignment] Assignment +# 55| 0: [ClassVariable] @@fourty_four +# 55| 1: [ReservedWord] = +# 55| 2: [Constant] FOURTY_FOUR +# 56| 1: [Assignment] Assignment +# 56| 0: [Constant] FOURTY_FOUR +# 56| 1: [ReservedWord] = +# 56| 2: [Integer] 44 +# 57| 2: [Assignment] Assignment +# 57| 0: [ClassVariable] @@fourty_four +# 57| 1: [ReservedWord] = +# 57| 2: [Constant] FOURTY_FOUR +# 58| 4: [ReservedWord] end +# 59| 3: [ReservedWord] end # 61| 11: [Module] Module # 61| 0: [ReservedWord] module # 61| 1: [Constant] Mod1 -# 62| 2: [Module] Module -# 62| 0: [ReservedWord] module -# 62| 1: [Constant] Mod3 -# 63| 2: [Assignment] Assignment -# 63| 0: [Constant] FOURTY_FIVE -# 63| 1: [ReservedWord] = -# 63| 2: [Integer] 45 -# 64| 3: [ReservedWord] end -# 65| 3: [Assignment] Assignment -# 65| 0: [ClassVariable] @@fourty_five -# 65| 1: [ReservedWord] = -# 65| 2: [ScopeResolution] ScopeResolution -# 65| 0: [Constant] Mod3 -# 65| 1: [ReservedWord] :: -# 65| 2: [Constant] FOURTY_FIVE -# 66| 4: [ReservedWord] end +# 62| 2: [BodyStatement] BodyStatement +# 62| 0: [Module] Module +# 62| 0: [ReservedWord] module +# 62| 1: [Constant] Mod3 +# 63| 2: [BodyStatement] BodyStatement +# 63| 0: [Assignment] Assignment +# 63| 0: [Constant] FOURTY_FIVE +# 63| 1: [ReservedWord] = +# 63| 2: [Integer] 45 +# 64| 3: [ReservedWord] end +# 65| 1: [Assignment] Assignment +# 65| 0: [ClassVariable] @@fourty_five +# 65| 1: [ReservedWord] = +# 65| 2: [ScopeResolution] ScopeResolution +# 65| 0: [Constant] Mod3 +# 65| 1: [ReservedWord] :: +# 65| 2: [Constant] FOURTY_FIVE +# 66| 3: [ReservedWord] end # 68| 12: [Module] Module # 68| 0: [ReservedWord] module # 68| 1: [Constant] Mod4 -# 69| 2: [Call] Call -# 69| 0: [Identifier] include -# 69| 1: [ArgumentList] ArgumentList -# 69| 0: [Constant] Mod1 -# 70| 3: [Module] Module -# 70| 0: [ReservedWord] module -# 70| 1: [ScopeResolution] ScopeResolution -# 70| 0: [Constant] Mod3 -# 70| 1: [ReservedWord] :: -# 70| 2: [Constant] Mod5 -# 71| 2: [Assignment] Assignment -# 71| 0: [Constant] FOURTY_SIX -# 71| 1: [ReservedWord] = -# 71| 2: [Integer] 46 -# 72| 3: [ReservedWord] end -# 73| 4: [Assignment] Assignment -# 73| 0: [ClassVariable] @@fourty_six -# 73| 1: [ReservedWord] = -# 73| 2: [ScopeResolution] ScopeResolution -# 73| 0: [Constant] Mod3 -# 73| 1: [ReservedWord] :: -# 73| 2: [Constant] FOURTY_SIX -# 74| 5: [ReservedWord] end +# 69| 2: [BodyStatement] BodyStatement +# 69| 0: [Call] Call +# 69| 0: [Identifier] include +# 69| 1: [ArgumentList] ArgumentList +# 69| 0: [Constant] Mod1 +# 70| 1: [Module] Module +# 70| 0: [ReservedWord] module +# 70| 1: [ScopeResolution] ScopeResolution +# 70| 0: [Constant] Mod3 +# 70| 1: [ReservedWord] :: +# 70| 2: [Constant] Mod5 +# 71| 2: [BodyStatement] BodyStatement +# 71| 0: [Assignment] Assignment +# 71| 0: [Constant] FOURTY_SIX +# 71| 1: [ReservedWord] = +# 71| 2: [Integer] 46 +# 72| 3: [ReservedWord] end +# 73| 2: [Assignment] Assignment +# 73| 0: [ClassVariable] @@fourty_six +# 73| 1: [ReservedWord] = +# 73| 2: [ScopeResolution] ScopeResolution +# 73| 0: [Constant] Mod3 +# 73| 1: [ReservedWord] :: +# 73| 2: [Constant] FOURTY_SIX +# 74| 3: [ReservedWord] end # 78| 13: [Assignment] Assignment # 78| 0: [Identifier] a # 78| 1: [ReservedWord] = @@ -2318,10 +2361,11 @@ control/cases.rb: # 101| 0: [Identifier] x # 101| 2: [Block] Block # 101| 0: [ReservedWord] { -# 101| 1: [Binary] Binary -# 101| 0: [Identifier] x -# 101| 1: [ReservedWord] == -# 101| 2: [Integer] 10 +# 101| 1: [BlockBody] BlockBody +# 101| 0: [Binary] Binary +# 101| 0: [Identifier] x +# 101| 1: [ReservedWord] == +# 101| 2: [Integer] 10 # 101| 2: [ReservedWord] } # 102| 17: [InClause] InClause # 102| 0: [ReservedWord] in @@ -3582,49 +3626,52 @@ gems/Gemfile: # 5| 2: [ReservedWord] ' # 5| 2: [DoBlock] DoBlock # 5| 0: [ReservedWord] do -# 6| 1: [Call] Call -# 6| 0: [Identifier] gem -# 6| 1: [ArgumentList] ArgumentList -# 6| 0: [String] String -# 6| 0: [ReservedWord] ' -# 6| 1: [StringContent] my_gem -# 6| 2: [ReservedWord] ' -# 6| 1: [ReservedWord] , -# 6| 2: [String] String -# 6| 0: [ReservedWord] ' -# 6| 1: [StringContent] 1.0 -# 6| 2: [ReservedWord] ' -# 7| 2: [Call] Call -# 7| 0: [Identifier] gem -# 7| 1: [ArgumentList] ArgumentList -# 7| 0: [String] String -# 7| 0: [ReservedWord] ' -# 7| 1: [StringContent] another_gem -# 7| 2: [ReservedWord] ' -# 7| 1: [ReservedWord] , -# 7| 2: [String] String -# 7| 0: [ReservedWord] ' -# 7| 1: [StringContent] 3.1.4 -# 7| 2: [ReservedWord] ' -# 8| 3: [ReservedWord] end +# 6| 1: [BodyStatement] BodyStatement +# 6| 0: [Call] Call +# 6| 0: [Identifier] gem +# 6| 1: [ArgumentList] ArgumentList +# 6| 0: [String] String +# 6| 0: [ReservedWord] ' +# 6| 1: [StringContent] my_gem +# 6| 2: [ReservedWord] ' +# 6| 1: [ReservedWord] , +# 6| 2: [String] String +# 6| 0: [ReservedWord] ' +# 6| 1: [StringContent] 1.0 +# 6| 2: [ReservedWord] ' +# 7| 1: [Call] Call +# 7| 0: [Identifier] gem +# 7| 1: [ArgumentList] ArgumentList +# 7| 0: [String] String +# 7| 0: [ReservedWord] ' +# 7| 1: [StringContent] another_gem +# 7| 2: [ReservedWord] ' +# 7| 1: [ReservedWord] , +# 7| 2: [String] String +# 7| 0: [ReservedWord] ' +# 7| 1: [StringContent] 3.1.4 +# 7| 2: [ReservedWord] ' +# 8| 2: [ReservedWord] end gems/lib/test.rb: # 1| [Program] Program # 1| 0: [Class] Class # 1| 0: [ReservedWord] class # 1| 1: [Constant] Foo -# 2| 2: [SingletonMethod] SingletonMethod -# 2| 0: [ReservedWord] def -# 2| 1: [Self] self -# 2| 2: [ReservedWord] . -# 2| 3: [Identifier] greet -# 3| 4: [Call] Call -# 3| 0: [Identifier] puts -# 3| 1: [ArgumentList] ArgumentList -# 3| 0: [String] String -# 3| 0: [ReservedWord] " -# 3| 1: [StringContent] Hello -# 3| 2: [ReservedWord] " -# 4| 5: [ReservedWord] end +# 2| 2: [BodyStatement] BodyStatement +# 2| 0: [SingletonMethod] SingletonMethod +# 2| 0: [ReservedWord] def +# 2| 1: [Self] self +# 2| 2: [ReservedWord] . +# 2| 3: [Identifier] greet +# 3| 4: [BodyStatement] BodyStatement +# 3| 0: [Call] Call +# 3| 0: [Identifier] puts +# 3| 1: [ArgumentList] ArgumentList +# 3| 0: [String] String +# 3| 0: [ReservedWord] " +# 3| 1: [StringContent] Hello +# 3| 2: [ReservedWord] " +# 4| 5: [ReservedWord] end # 5| 3: [ReservedWord] end gems/test.gemspec: # 1| [Program] Program @@ -3641,93 +3688,94 @@ gems/test.gemspec: # 1| 0: [ReservedWord] | # 1| 1: [Identifier] s # 1| 2: [ReservedWord] | -# 2| 2: [Assignment] Assignment -# 2| 0: [Call] Call -# 2| 0: [Identifier] s -# 2| 1: [ReservedWord] . -# 2| 2: [Identifier] name -# 2| 1: [ReservedWord] = -# 2| 2: [String] String -# 2| 0: [ReservedWord] ' -# 2| 1: [StringContent] test -# 2| 2: [ReservedWord] ' -# 3| 3: [Assignment] Assignment -# 3| 0: [Call] Call -# 3| 0: [Identifier] s -# 3| 1: [ReservedWord] . -# 3| 2: [Identifier] version -# 3| 1: [ReservedWord] = -# 3| 2: [String] String -# 3| 0: [ReservedWord] ' -# 3| 1: [StringContent] 0.0.0 -# 3| 2: [ReservedWord] ' -# 4| 4: [Assignment] Assignment -# 4| 0: [Call] Call -# 4| 0: [Identifier] s -# 4| 1: [ReservedWord] . -# 4| 2: [Identifier] summary -# 4| 1: [ReservedWord] = -# 4| 2: [String] String -# 4| 0: [ReservedWord] " -# 4| 1: [StringContent] foo! -# 4| 2: [ReservedWord] " -# 5| 5: [Assignment] Assignment -# 5| 0: [Call] Call -# 5| 0: [Identifier] s -# 5| 1: [ReservedWord] . -# 5| 2: [Identifier] description -# 5| 1: [ReservedWord] = -# 5| 2: [String] String -# 5| 0: [ReservedWord] " -# 5| 1: [StringContent] A test -# 5| 2: [ReservedWord] " -# 6| 6: [Assignment] Assignment -# 6| 0: [Call] Call -# 6| 0: [Identifier] s -# 6| 1: [ReservedWord] . -# 6| 2: [Identifier] authors -# 6| 1: [ReservedWord] = -# 6| 2: [Array] Array -# 6| 0: [ReservedWord] [ -# 6| 1: [String] String -# 6| 0: [ReservedWord] " -# 6| 1: [StringContent] Mona Lisa -# 6| 2: [ReservedWord] " -# 6| 2: [ReservedWord] ] -# 7| 7: [Assignment] Assignment -# 7| 0: [Call] Call -# 7| 0: [Identifier] s -# 7| 1: [ReservedWord] . -# 7| 2: [Identifier] email -# 7| 1: [ReservedWord] = -# 7| 2: [String] String -# 7| 0: [ReservedWord] ' -# 7| 1: [StringContent] mona@example.com -# 7| 2: [ReservedWord] ' -# 8| 8: [Assignment] Assignment -# 8| 0: [Call] Call -# 8| 0: [Identifier] s -# 8| 1: [ReservedWord] . -# 8| 2: [Identifier] files -# 8| 1: [ReservedWord] = -# 8| 2: [Array] Array -# 8| 0: [ReservedWord] [ -# 8| 1: [String] String -# 8| 0: [ReservedWord] " -# 8| 1: [StringContent] lib/test.rb -# 8| 2: [ReservedWord] " -# 8| 2: [ReservedWord] ] -# 9| 9: [Assignment] Assignment -# 9| 0: [Call] Call -# 9| 0: [Identifier] s -# 9| 1: [ReservedWord] . -# 9| 2: [Identifier] homepage -# 9| 1: [ReservedWord] = -# 9| 2: [String] String -# 9| 0: [ReservedWord] ' -# 9| 1: [StringContent] https://github.com/github/codeql-ruby -# 9| 2: [ReservedWord] ' -# 10| 10: [ReservedWord] end +# 2| 2: [BodyStatement] BodyStatement +# 2| 0: [Assignment] Assignment +# 2| 0: [Call] Call +# 2| 0: [Identifier] s +# 2| 1: [ReservedWord] . +# 2| 2: [Identifier] name +# 2| 1: [ReservedWord] = +# 2| 2: [String] String +# 2| 0: [ReservedWord] ' +# 2| 1: [StringContent] test +# 2| 2: [ReservedWord] ' +# 3| 1: [Assignment] Assignment +# 3| 0: [Call] Call +# 3| 0: [Identifier] s +# 3| 1: [ReservedWord] . +# 3| 2: [Identifier] version +# 3| 1: [ReservedWord] = +# 3| 2: [String] String +# 3| 0: [ReservedWord] ' +# 3| 1: [StringContent] 0.0.0 +# 3| 2: [ReservedWord] ' +# 4| 2: [Assignment] Assignment +# 4| 0: [Call] Call +# 4| 0: [Identifier] s +# 4| 1: [ReservedWord] . +# 4| 2: [Identifier] summary +# 4| 1: [ReservedWord] = +# 4| 2: [String] String +# 4| 0: [ReservedWord] " +# 4| 1: [StringContent] foo! +# 4| 2: [ReservedWord] " +# 5| 3: [Assignment] Assignment +# 5| 0: [Call] Call +# 5| 0: [Identifier] s +# 5| 1: [ReservedWord] . +# 5| 2: [Identifier] description +# 5| 1: [ReservedWord] = +# 5| 2: [String] String +# 5| 0: [ReservedWord] " +# 5| 1: [StringContent] A test +# 5| 2: [ReservedWord] " +# 6| 4: [Assignment] Assignment +# 6| 0: [Call] Call +# 6| 0: [Identifier] s +# 6| 1: [ReservedWord] . +# 6| 2: [Identifier] authors +# 6| 1: [ReservedWord] = +# 6| 2: [Array] Array +# 6| 0: [ReservedWord] [ +# 6| 1: [String] String +# 6| 0: [ReservedWord] " +# 6| 1: [StringContent] Mona Lisa +# 6| 2: [ReservedWord] " +# 6| 2: [ReservedWord] ] +# 7| 5: [Assignment] Assignment +# 7| 0: [Call] Call +# 7| 0: [Identifier] s +# 7| 1: [ReservedWord] . +# 7| 2: [Identifier] email +# 7| 1: [ReservedWord] = +# 7| 2: [String] String +# 7| 0: [ReservedWord] ' +# 7| 1: [StringContent] mona@example.com +# 7| 2: [ReservedWord] ' +# 8| 6: [Assignment] Assignment +# 8| 0: [Call] Call +# 8| 0: [Identifier] s +# 8| 1: [ReservedWord] . +# 8| 2: [Identifier] files +# 8| 1: [ReservedWord] = +# 8| 2: [Array] Array +# 8| 0: [ReservedWord] [ +# 8| 1: [String] String +# 8| 0: [ReservedWord] " +# 8| 1: [StringContent] lib/test.rb +# 8| 2: [ReservedWord] " +# 8| 2: [ReservedWord] ] +# 9| 7: [Assignment] Assignment +# 9| 0: [Call] Call +# 9| 0: [Identifier] s +# 9| 1: [ReservedWord] . +# 9| 2: [Identifier] homepage +# 9| 1: [ReservedWord] = +# 9| 2: [String] String +# 9| 0: [ReservedWord] ' +# 9| 1: [StringContent] https://github.com/github/codeql-ruby +# 9| 2: [ReservedWord] ' +# 10| 3: [ReservedWord] end literals/literals.rb: # 1| [Program] Program # 2| 0: [Nil] nil @@ -4444,10 +4492,11 @@ literals/literals.rb: # 174| 127: [Method] Method # 174| 0: [ReservedWord] def # 174| 1: [Identifier] m -# 175| 2: [Assignment] Assignment -# 175| 0: [Identifier] query -# 175| 1: [ReservedWord] = -# 175| 2: [HeredocBeginning] <<-BLA +# 175| 2: [BodyStatement] BodyStatement +# 175| 0: [Assignment] Assignment +# 175| 0: [Identifier] query +# 175| 1: [ReservedWord] = +# 175| 2: [HeredocBeginning] <<-BLA # 178| 3: [ReservedWord] end # 180| 128: [Assignment] Assignment # 180| 0: [Identifier] query @@ -4740,46 +4789,49 @@ modules/classes.rb: # 20| 5: [Class] Class # 20| 0: [ReservedWord] class # 20| 1: [Constant] Wibble -# 21| 2: [Method] Method -# 21| 0: [ReservedWord] def -# 21| 1: [Identifier] method_a -# 22| 2: [Call] Call -# 22| 0: [Identifier] puts -# 22| 1: [ArgumentList] ArgumentList -# 22| 0: [String] String -# 22| 0: [ReservedWord] ' -# 22| 1: [StringContent] a -# 22| 2: [ReservedWord] ' -# 23| 3: [ReservedWord] end -# 25| 3: [Method] Method -# 25| 0: [ReservedWord] def -# 25| 1: [Identifier] method_b -# 26| 2: [Call] Call -# 26| 0: [Identifier] puts -# 26| 1: [ArgumentList] ArgumentList -# 26| 0: [String] String -# 26| 0: [ReservedWord] ' -# 26| 1: [StringContent] b -# 26| 2: [ReservedWord] ' -# 27| 3: [ReservedWord] end -# 29| 4: [Call] Call -# 29| 0: [Identifier] some_method_call -# 29| 1: [ArgumentList] ArgumentList -# 29| 0: [ReservedWord] ( -# 29| 1: [ReservedWord] ) -# 30| 5: [Assignment] Assignment -# 30| 0: [GlobalVariable] $global_var -# 30| 1: [ReservedWord] = -# 30| 2: [Integer] 123 -# 32| 6: [Class] Class -# 32| 0: [ReservedWord] class -# 32| 1: [Constant] ClassInWibble -# 33| 2: [ReservedWord] end -# 35| 7: [Module] Module -# 35| 0: [ReservedWord] module -# 35| 1: [Constant] ModuleInWibble -# 36| 2: [ReservedWord] end -# 37| 8: [ReservedWord] end +# 21| 2: [BodyStatement] BodyStatement +# 21| 0: [Method] Method +# 21| 0: [ReservedWord] def +# 21| 1: [Identifier] method_a +# 22| 2: [BodyStatement] BodyStatement +# 22| 0: [Call] Call +# 22| 0: [Identifier] puts +# 22| 1: [ArgumentList] ArgumentList +# 22| 0: [String] String +# 22| 0: [ReservedWord] ' +# 22| 1: [StringContent] a +# 22| 2: [ReservedWord] ' +# 23| 3: [ReservedWord] end +# 25| 1: [Method] Method +# 25| 0: [ReservedWord] def +# 25| 1: [Identifier] method_b +# 26| 2: [BodyStatement] BodyStatement +# 26| 0: [Call] Call +# 26| 0: [Identifier] puts +# 26| 1: [ArgumentList] ArgumentList +# 26| 0: [String] String +# 26| 0: [ReservedWord] ' +# 26| 1: [StringContent] b +# 26| 2: [ReservedWord] ' +# 27| 3: [ReservedWord] end +# 29| 2: [Call] Call +# 29| 0: [Identifier] some_method_call +# 29| 1: [ArgumentList] ArgumentList +# 29| 0: [ReservedWord] ( +# 29| 1: [ReservedWord] ) +# 30| 3: [Assignment] Assignment +# 30| 0: [GlobalVariable] $global_var +# 30| 1: [ReservedWord] = +# 30| 2: [Integer] 123 +# 32| 4: [Class] Class +# 32| 0: [ReservedWord] class +# 32| 1: [Constant] ClassInWibble +# 33| 2: [ReservedWord] end +# 35| 5: [Module] Module +# 35| 0: [ReservedWord] module +# 35| 1: [Constant] ModuleInWibble +# 36| 2: [ReservedWord] end +# 37| 3: [ReservedWord] end # 40| 6: [Assignment] Assignment # 40| 0: [Identifier] x # 40| 1: [ReservedWord] = @@ -4791,31 +4843,34 @@ modules/classes.rb: # 41| 0: [ReservedWord] class # 41| 1: [ReservedWord] << # 41| 2: [Identifier] x -# 42| 3: [Method] Method -# 42| 0: [ReservedWord] def -# 42| 1: [Identifier] length -# 43| 2: [Binary] Binary -# 43| 0: [Integer] 100 -# 43| 1: [ReservedWord] * -# 43| 2: [Super] super -# 44| 3: [ReservedWord] end -# 46| 4: [Method] Method -# 46| 0: [ReservedWord] def -# 46| 1: [Identifier] wibble -# 47| 2: [Call] Call -# 47| 0: [Identifier] puts -# 47| 1: [ArgumentList] ArgumentList -# 47| 0: [String] String -# 47| 0: [ReservedWord] ' -# 47| 1: [StringContent] wibble -# 47| 2: [ReservedWord] ' -# 48| 3: [ReservedWord] end -# 50| 5: [Identifier] another_method_call -# 51| 6: [Assignment] Assignment -# 51| 0: [GlobalVariable] $global_var2 -# 51| 1: [ReservedWord] = -# 51| 2: [Integer] 456 -# 52| 7: [ReservedWord] end +# 42| 3: [BodyStatement] BodyStatement +# 42| 0: [Method] Method +# 42| 0: [ReservedWord] def +# 42| 1: [Identifier] length +# 43| 2: [BodyStatement] BodyStatement +# 43| 0: [Binary] Binary +# 43| 0: [Integer] 100 +# 43| 1: [ReservedWord] * +# 43| 2: [Super] super +# 44| 3: [ReservedWord] end +# 46| 1: [Method] Method +# 46| 0: [ReservedWord] def +# 46| 1: [Identifier] wibble +# 47| 2: [BodyStatement] BodyStatement +# 47| 0: [Call] Call +# 47| 0: [Identifier] puts +# 47| 1: [ArgumentList] ArgumentList +# 47| 0: [String] String +# 47| 0: [ReservedWord] ' +# 47| 1: [StringContent] wibble +# 47| 2: [ReservedWord] ' +# 48| 3: [ReservedWord] end +# 50| 2: [Identifier] another_method_call +# 51| 3: [Assignment] Assignment +# 51| 0: [GlobalVariable] $global_var2 +# 51| 1: [ReservedWord] = +# 51| 2: [Integer] 456 +# 52| 4: [ReservedWord] end # 55| 8: [Class] Class # 55| 0: [ReservedWord] class # 55| 1: [ScopeResolution] ScopeResolution @@ -4838,121 +4893,126 @@ modules/modules.rb: # 4| 1: [Module] Module # 4| 0: [ReservedWord] module # 4| 1: [Constant] Foo -# 5| 2: [Module] Module -# 5| 0: [ReservedWord] module -# 5| 1: [Constant] Bar -# 6| 2: [Class] Class -# 6| 0: [ReservedWord] class -# 6| 1: [Constant] ClassInFooBar -# 7| 2: [ReservedWord] end -# 9| 3: [Method] Method -# 9| 0: [ReservedWord] def -# 9| 1: [Identifier] method_in_foo_bar -# 10| 2: [ReservedWord] end -# 12| 4: [Call] Call -# 12| 0: [Identifier] puts -# 12| 1: [ArgumentList] ArgumentList -# 12| 0: [String] String -# 12| 0: [ReservedWord] ' -# 12| 1: [StringContent] module Foo::Bar -# 12| 2: [ReservedWord] ' -# 13| 5: [Assignment] Assignment -# 13| 0: [GlobalVariable] $global_var -# 13| 1: [ReservedWord] = -# 13| 2: [Integer] 0 -# 14| 6: [ReservedWord] end -# 16| 3: [Method] Method -# 16| 0: [ReservedWord] def -# 16| 1: [Identifier] method_in_foo -# 17| 2: [ReservedWord] end -# 19| 4: [Class] Class -# 19| 0: [ReservedWord] class -# 19| 1: [Constant] ClassInFoo -# 20| 2: [ReservedWord] end -# 22| 5: [Call] Call -# 22| 0: [Identifier] puts -# 22| 1: [ArgumentList] ArgumentList -# 22| 0: [String] String -# 22| 0: [ReservedWord] ' -# 22| 1: [StringContent] module Foo -# 22| 2: [ReservedWord] ' -# 23| 6: [Assignment] Assignment -# 23| 0: [GlobalVariable] $global_var -# 23| 1: [ReservedWord] = -# 23| 2: [Integer] 1 -# 24| 7: [ReservedWord] end +# 5| 2: [BodyStatement] BodyStatement +# 5| 0: [Module] Module +# 5| 0: [ReservedWord] module +# 5| 1: [Constant] Bar +# 6| 2: [BodyStatement] BodyStatement +# 6| 0: [Class] Class +# 6| 0: [ReservedWord] class +# 6| 1: [Constant] ClassInFooBar +# 7| 2: [ReservedWord] end +# 9| 1: [Method] Method +# 9| 0: [ReservedWord] def +# 9| 1: [Identifier] method_in_foo_bar +# 10| 2: [ReservedWord] end +# 12| 2: [Call] Call +# 12| 0: [Identifier] puts +# 12| 1: [ArgumentList] ArgumentList +# 12| 0: [String] String +# 12| 0: [ReservedWord] ' +# 12| 1: [StringContent] module Foo::Bar +# 12| 2: [ReservedWord] ' +# 13| 3: [Assignment] Assignment +# 13| 0: [GlobalVariable] $global_var +# 13| 1: [ReservedWord] = +# 13| 2: [Integer] 0 +# 14| 3: [ReservedWord] end +# 16| 1: [Method] Method +# 16| 0: [ReservedWord] def +# 16| 1: [Identifier] method_in_foo +# 17| 2: [ReservedWord] end +# 19| 2: [Class] Class +# 19| 0: [ReservedWord] class +# 19| 1: [Constant] ClassInFoo +# 20| 2: [ReservedWord] end +# 22| 3: [Call] Call +# 22| 0: [Identifier] puts +# 22| 1: [ArgumentList] ArgumentList +# 22| 0: [String] String +# 22| 0: [ReservedWord] ' +# 22| 1: [StringContent] module Foo +# 22| 2: [ReservedWord] ' +# 23| 4: [Assignment] Assignment +# 23| 0: [GlobalVariable] $global_var +# 23| 1: [ReservedWord] = +# 23| 2: [Integer] 1 +# 24| 3: [ReservedWord] end # 26| 2: [Module] Module # 26| 0: [ReservedWord] module # 26| 1: [Constant] Foo -# 27| 2: [Method] Method -# 27| 0: [ReservedWord] def -# 27| 1: [Identifier] method_in_another_definition_of_foo -# 28| 2: [ReservedWord] end -# 30| 3: [Class] Class -# 30| 0: [ReservedWord] class -# 30| 1: [Constant] ClassInAnotherDefinitionOfFoo -# 31| 2: [ReservedWord] end -# 33| 4: [Call] Call -# 33| 0: [Identifier] puts -# 33| 1: [ArgumentList] ArgumentList -# 33| 0: [String] String -# 33| 0: [ReservedWord] ' -# 33| 1: [StringContent] module Foo again -# 33| 2: [ReservedWord] ' -# 34| 5: [Assignment] Assignment -# 34| 0: [GlobalVariable] $global_var -# 34| 1: [ReservedWord] = -# 34| 2: [Integer] 2 -# 35| 6: [ReservedWord] end +# 27| 2: [BodyStatement] BodyStatement +# 27| 0: [Method] Method +# 27| 0: [ReservedWord] def +# 27| 1: [Identifier] method_in_another_definition_of_foo +# 28| 2: [ReservedWord] end +# 30| 1: [Class] Class +# 30| 0: [ReservedWord] class +# 30| 1: [Constant] ClassInAnotherDefinitionOfFoo +# 31| 2: [ReservedWord] end +# 33| 2: [Call] Call +# 33| 0: [Identifier] puts +# 33| 1: [ArgumentList] ArgumentList +# 33| 0: [String] String +# 33| 0: [ReservedWord] ' +# 33| 1: [StringContent] module Foo again +# 33| 2: [ReservedWord] ' +# 34| 3: [Assignment] Assignment +# 34| 0: [GlobalVariable] $global_var +# 34| 1: [ReservedWord] = +# 34| 2: [Integer] 2 +# 35| 3: [ReservedWord] end # 37| 3: [Module] Module # 37| 0: [ReservedWord] module # 37| 1: [Constant] Bar -# 38| 2: [Method] Method -# 38| 0: [ReservedWord] def -# 38| 1: [Identifier] method_a -# 39| 2: [ReservedWord] end -# 41| 3: [Method] Method -# 41| 0: [ReservedWord] def -# 41| 1: [Identifier] method_b -# 42| 2: [ReservedWord] end -# 44| 4: [Call] Call -# 44| 0: [Identifier] puts -# 44| 1: [ArgumentList] ArgumentList -# 44| 0: [String] String -# 44| 0: [ReservedWord] ' -# 44| 1: [StringContent] module Bar -# 44| 2: [ReservedWord] ' -# 45| 5: [Assignment] Assignment -# 45| 0: [GlobalVariable] $global_var -# 45| 1: [ReservedWord] = -# 45| 2: [Integer] 3 -# 46| 6: [ReservedWord] end +# 38| 2: [BodyStatement] BodyStatement +# 38| 0: [Method] Method +# 38| 0: [ReservedWord] def +# 38| 1: [Identifier] method_a +# 39| 2: [ReservedWord] end +# 41| 1: [Method] Method +# 41| 0: [ReservedWord] def +# 41| 1: [Identifier] method_b +# 42| 2: [ReservedWord] end +# 44| 2: [Call] Call +# 44| 0: [Identifier] puts +# 44| 1: [ArgumentList] ArgumentList +# 44| 0: [String] String +# 44| 0: [ReservedWord] ' +# 44| 1: [StringContent] module Bar +# 44| 2: [ReservedWord] ' +# 45| 3: [Assignment] Assignment +# 45| 0: [GlobalVariable] $global_var +# 45| 1: [ReservedWord] = +# 45| 2: [Integer] 3 +# 46| 3: [ReservedWord] end # 48| 4: [Module] Module # 48| 0: [ReservedWord] module # 48| 1: [ScopeResolution] ScopeResolution # 48| 0: [Constant] Foo # 48| 1: [ReservedWord] :: # 48| 2: [Constant] Bar -# 49| 2: [Class] Class -# 49| 0: [ReservedWord] class -# 49| 1: [Constant] ClassInAnotherDefinitionOfFooBar -# 50| 2: [ReservedWord] end -# 52| 3: [Method] Method -# 52| 0: [ReservedWord] def -# 52| 1: [Identifier] method_in_another_definition_of_foo_bar -# 53| 2: [ReservedWord] end -# 55| 4: [Call] Call -# 55| 0: [Identifier] puts -# 55| 1: [ArgumentList] ArgumentList -# 55| 0: [String] String -# 55| 0: [ReservedWord] ' -# 55| 1: [StringContent] module Foo::Bar again -# 55| 2: [ReservedWord] ' -# 56| 5: [Assignment] Assignment -# 56| 0: [GlobalVariable] $global_var -# 56| 1: [ReservedWord] = -# 56| 2: [Integer] 4 -# 57| 6: [ReservedWord] end +# 49| 2: [BodyStatement] BodyStatement +# 49| 0: [Class] Class +# 49| 0: [ReservedWord] class +# 49| 1: [Constant] ClassInAnotherDefinitionOfFooBar +# 50| 2: [ReservedWord] end +# 52| 1: [Method] Method +# 52| 0: [ReservedWord] def +# 52| 1: [Identifier] method_in_another_definition_of_foo_bar +# 53| 2: [ReservedWord] end +# 55| 2: [Call] Call +# 55| 0: [Identifier] puts +# 55| 1: [ArgumentList] ArgumentList +# 55| 0: [String] String +# 55| 0: [ReservedWord] ' +# 55| 1: [StringContent] module Foo::Bar again +# 55| 2: [ReservedWord] ' +# 56| 3: [Assignment] Assignment +# 56| 0: [GlobalVariable] $global_var +# 56| 1: [ReservedWord] = +# 56| 2: [Integer] 4 +# 57| 3: [ReservedWord] end # 60| 5: [Module] Module # 60| 0: [ReservedWord] module # 60| 1: [ScopeResolution] ScopeResolution @@ -4962,126 +5022,136 @@ modules/modules.rb: # 63| 6: [Module] Module # 63| 0: [ReservedWord] module # 63| 1: [Constant] Test -# 65| 2: [Module] Module -# 65| 0: [ReservedWord] module -# 65| 1: [Constant] Foo1 -# 66| 2: [Class] Class -# 66| 0: [ReservedWord] class -# 66| 1: [ScopeResolution] ScopeResolution -# 66| 0: [Constant] Foo1 -# 66| 1: [ReservedWord] :: -# 66| 2: [Constant] Bar -# 67| 2: [ReservedWord] end -# 68| 3: [ReservedWord] end -# 70| 3: [Module] Module -# 70| 0: [ReservedWord] module -# 70| 1: [Constant] Foo2 -# 71| 2: [Module] Module -# 71| 0: [ReservedWord] module -# 71| 1: [Constant] Foo2 -# 71| 2: [ReservedWord] end -# 72| 3: [Class] Class -# 72| 0: [ReservedWord] class -# 72| 1: [ScopeResolution] ScopeResolution -# 72| 0: [Constant] Foo2 -# 72| 1: [ReservedWord] :: -# 72| 2: [Constant] Bar -# 73| 2: [ReservedWord] end -# 74| 4: [ReservedWord] end -# 76| 4: [Module] Module -# 76| 0: [ReservedWord] module -# 76| 1: [Constant] Foo3 -# 77| 2: [Assignment] Assignment -# 77| 0: [Constant] Foo3 -# 77| 1: [ReservedWord] = -# 77| 2: [Constant] Object -# 78| 3: [Class] Class -# 78| 0: [ReservedWord] class -# 78| 1: [ScopeResolution] ScopeResolution -# 78| 0: [Constant] Foo3 -# 78| 1: [ReservedWord] :: -# 78| 2: [Constant] Bar -# 79| 2: [ReservedWord] end -# 80| 4: [ReservedWord] end -# 81| 5: [ReservedWord] end +# 65| 2: [BodyStatement] BodyStatement +# 65| 0: [Module] Module +# 65| 0: [ReservedWord] module +# 65| 1: [Constant] Foo1 +# 66| 2: [BodyStatement] BodyStatement +# 66| 0: [Class] Class +# 66| 0: [ReservedWord] class +# 66| 1: [ScopeResolution] ScopeResolution +# 66| 0: [Constant] Foo1 +# 66| 1: [ReservedWord] :: +# 66| 2: [Constant] Bar +# 67| 2: [ReservedWord] end +# 68| 3: [ReservedWord] end +# 70| 1: [Module] Module +# 70| 0: [ReservedWord] module +# 70| 1: [Constant] Foo2 +# 71| 2: [BodyStatement] BodyStatement +# 71| 0: [Module] Module +# 71| 0: [ReservedWord] module +# 71| 1: [Constant] Foo2 +# 71| 2: [ReservedWord] end +# 72| 1: [Class] Class +# 72| 0: [ReservedWord] class +# 72| 1: [ScopeResolution] ScopeResolution +# 72| 0: [Constant] Foo2 +# 72| 1: [ReservedWord] :: +# 72| 2: [Constant] Bar +# 73| 2: [ReservedWord] end +# 74| 3: [ReservedWord] end +# 76| 2: [Module] Module +# 76| 0: [ReservedWord] module +# 76| 1: [Constant] Foo3 +# 77| 2: [BodyStatement] BodyStatement +# 77| 0: [Assignment] Assignment +# 77| 0: [Constant] Foo3 +# 77| 1: [ReservedWord] = +# 77| 2: [Constant] Object +# 78| 1: [Class] Class +# 78| 0: [ReservedWord] class +# 78| 1: [ScopeResolution] ScopeResolution +# 78| 0: [Constant] Foo3 +# 78| 1: [ReservedWord] :: +# 78| 2: [Constant] Bar +# 79| 2: [ReservedWord] end +# 80| 3: [ReservedWord] end +# 81| 3: [ReservedWord] end # 83| 7: [Module] Module # 83| 0: [ReservedWord] module # 83| 1: [Constant] Other -# 84| 2: [Module] Module -# 84| 0: [ReservedWord] module -# 84| 1: [Constant] Foo1 -# 85| 2: [ReservedWord] end +# 84| 2: [BodyStatement] BodyStatement +# 84| 0: [Module] Module +# 84| 0: [ReservedWord] module +# 84| 1: [Constant] Foo1 +# 85| 2: [ReservedWord] end # 86| 3: [ReservedWord] end # 88| 8: [Module] Module # 88| 0: [ReservedWord] module # 88| 1: [Constant] IncludeTest -# 89| 2: [Call] Call -# 89| 0: [Identifier] include -# 89| 1: [ArgumentList] ArgumentList -# 89| 0: [ScopeResolution] ScopeResolution -# 89| 0: [ReservedWord] :: -# 89| 1: [Constant] Test -# 90| 3: [Call] Call -# 90| 0: [Constant] Object -# 90| 1: [ReservedWord] . -# 90| 2: [Identifier] module_eval -# 90| 3: [Block] Block -# 90| 0: [ReservedWord] { -# 90| 1: [Call] Call -# 90| 0: [Identifier] prepend -# 90| 1: [ArgumentList] ArgumentList -# 90| 0: [Constant] Other -# 90| 2: [ReservedWord] } -# 91| 4: [Module] Module -# 91| 0: [ReservedWord] module -# 91| 1: [ScopeResolution] ScopeResolution -# 91| 0: [Constant] Foo1 -# 91| 1: [ReservedWord] :: -# 91| 2: [Constant] Y -# 92| 2: [ReservedWord] end -# 93| 5: [ReservedWord] end +# 89| 2: [BodyStatement] BodyStatement +# 89| 0: [Call] Call +# 89| 0: [Identifier] include +# 89| 1: [ArgumentList] ArgumentList +# 89| 0: [ScopeResolution] ScopeResolution +# 89| 0: [ReservedWord] :: +# 89| 1: [Constant] Test +# 90| 1: [Call] Call +# 90| 0: [Constant] Object +# 90| 1: [ReservedWord] . +# 90| 2: [Identifier] module_eval +# 90| 3: [Block] Block +# 90| 0: [ReservedWord] { +# 90| 1: [BlockBody] BlockBody +# 90| 0: [Call] Call +# 90| 0: [Identifier] prepend +# 90| 1: [ArgumentList] ArgumentList +# 90| 0: [Constant] Other +# 90| 2: [ReservedWord] } +# 91| 2: [Module] Module +# 91| 0: [ReservedWord] module +# 91| 1: [ScopeResolution] ScopeResolution +# 91| 0: [Constant] Foo1 +# 91| 1: [ReservedWord] :: +# 91| 2: [Constant] Y +# 92| 2: [ReservedWord] end +# 93| 3: [ReservedWord] end # 95| 9: [Module] Module # 95| 0: [ReservedWord] module # 95| 1: [Constant] IncludeTest2 -# 96| 2: [Call] Call -# 96| 0: [Identifier] include -# 96| 1: [ArgumentList] ArgumentList -# 96| 0: [Constant] Test -# 97| 3: [Module] Module -# 97| 0: [ReservedWord] module -# 97| 1: [ScopeResolution] ScopeResolution -# 97| 0: [Constant] Foo1 -# 97| 1: [ReservedWord] :: -# 97| 2: [Constant] Z -# 98| 2: [ReservedWord] end -# 99| 4: [ReservedWord] end +# 96| 2: [BodyStatement] BodyStatement +# 96| 0: [Call] Call +# 96| 0: [Identifier] include +# 96| 1: [ArgumentList] ArgumentList +# 96| 0: [Constant] Test +# 97| 1: [Module] Module +# 97| 0: [ReservedWord] module +# 97| 1: [ScopeResolution] ScopeResolution +# 97| 0: [Constant] Foo1 +# 97| 1: [ReservedWord] :: +# 97| 2: [Constant] Z +# 98| 2: [ReservedWord] end +# 99| 3: [ReservedWord] end # 101| 10: [Module] Module # 101| 0: [ReservedWord] module # 101| 1: [Constant] PrependTest -# 102| 2: [Call] Call -# 102| 0: [Identifier] prepend -# 102| 1: [ArgumentList] ArgumentList -# 102| 0: [ScopeResolution] ScopeResolution -# 102| 0: [ReservedWord] :: -# 102| 1: [Constant] Test -# 103| 3: [Module] Module -# 103| 0: [ReservedWord] module -# 103| 1: [ScopeResolution] ScopeResolution -# 103| 0: [Constant] Foo2 -# 103| 1: [ReservedWord] :: -# 103| 2: [Constant] Y -# 104| 2: [ReservedWord] end -# 105| 4: [ReservedWord] end +# 102| 2: [BodyStatement] BodyStatement +# 102| 0: [Call] Call +# 102| 0: [Identifier] prepend +# 102| 1: [ArgumentList] ArgumentList +# 102| 0: [ScopeResolution] ScopeResolution +# 102| 0: [ReservedWord] :: +# 102| 1: [Constant] Test +# 103| 1: [Module] Module +# 103| 0: [ReservedWord] module +# 103| 1: [ScopeResolution] ScopeResolution +# 103| 0: [Constant] Foo2 +# 103| 1: [ReservedWord] :: +# 103| 2: [Constant] Y +# 104| 2: [ReservedWord] end +# 105| 3: [ReservedWord] end # 107| 11: [Module] Module # 107| 0: [ReservedWord] module # 107| 1: [Constant] MM -# 108| 2: [Module] Module -# 108| 0: [ReservedWord] module -# 108| 1: [ScopeResolution] ScopeResolution -# 108| 0: [Constant] MM -# 108| 1: [ReservedWord] :: -# 108| 2: [Constant] MM -# 109| 2: [ReservedWord] end +# 108| 2: [BodyStatement] BodyStatement +# 108| 0: [Module] Module +# 108| 0: [ReservedWord] module +# 108| 1: [ScopeResolution] ScopeResolution +# 108| 0: [Constant] MM +# 108| 1: [ReservedWord] :: +# 108| 2: [Constant] MM +# 109| 2: [ReservedWord] end # 110| 3: [ReservedWord] end # 112| 12: [Class] Class # 112| 0: [ReservedWord] class @@ -5090,13 +5160,14 @@ modules/modules.rb: # 115| 13: [Module] Module # 115| 0: [ReservedWord] module # 115| 1: [Constant] XX -# 116| 2: [Class] Class -# 116| 0: [ReservedWord] class -# 116| 1: [Constant] YY -# 116| 2: [Superclass] Superclass -# 116| 0: [ReservedWord] < +# 116| 2: [BodyStatement] BodyStatement +# 116| 0: [Class] Class +# 116| 0: [ReservedWord] class # 116| 1: [Constant] YY -# 117| 3: [ReservedWord] end +# 116| 2: [Superclass] Superclass +# 116| 0: [ReservedWord] < +# 116| 1: [Constant] YY +# 117| 3: [ReservedWord] end # 118| 3: [ReservedWord] end # 120| 14: [Module] Module # 120| 0: [ReservedWord] module @@ -5239,37 +5310,38 @@ operations/operations.rb: # 29| 0: [ReservedWord] def # 29| 1: [Identifier] foo # 29| 2: [ReservedWord] ; -# 29| 3: [Return] Return -# 29| 0: [ReservedWord] return -# 29| 1: [ArgumentList] ArgumentList -# 29| 0: [Integer] 1 -# 29| 1: [ReservedWord] , -# 29| 2: [SplatArgument] SplatArgument -# 29| 0: [ReservedWord] * -# 29| 1: [Array] Array -# 29| 0: [ReservedWord] [ -# 29| 1: [Integer] 2 -# 29| 2: [ReservedWord] ] -# 29| 3: [ReservedWord] , -# 29| 4: [Pair] Pair -# 29| 0: [HashKeySymbol] a -# 29| 1: [ReservedWord] : -# 29| 2: [Integer] 3 -# 29| 5: [ReservedWord] , -# 29| 6: [HashSplatArgument] HashSplatArgument -# 29| 0: [ReservedWord] ** -# 29| 1: [Hash] Hash -# 29| 0: [ReservedWord] { -# 29| 1: [Pair] Pair -# 29| 0: [HashKeySymbol] b -# 29| 1: [ReservedWord] : -# 29| 2: [Integer] 4 -# 29| 2: [ReservedWord] , -# 29| 3: [Pair] Pair -# 29| 0: [HashKeySymbol] c -# 29| 1: [ReservedWord] : -# 29| 2: [Integer] 5 -# 29| 4: [ReservedWord] } +# 29| 3: [BodyStatement] BodyStatement +# 29| 0: [Return] Return +# 29| 0: [ReservedWord] return +# 29| 1: [ArgumentList] ArgumentList +# 29| 0: [Integer] 1 +# 29| 1: [ReservedWord] , +# 29| 2: [SplatArgument] SplatArgument +# 29| 0: [ReservedWord] * +# 29| 1: [Array] Array +# 29| 0: [ReservedWord] [ +# 29| 1: [Integer] 2 +# 29| 2: [ReservedWord] ] +# 29| 3: [ReservedWord] , +# 29| 4: [Pair] Pair +# 29| 0: [HashKeySymbol] a +# 29| 1: [ReservedWord] : +# 29| 2: [Integer] 3 +# 29| 5: [ReservedWord] , +# 29| 6: [HashSplatArgument] HashSplatArgument +# 29| 0: [ReservedWord] ** +# 29| 1: [Hash] Hash +# 29| 0: [ReservedWord] { +# 29| 1: [Pair] Pair +# 29| 0: [HashKeySymbol] b +# 29| 1: [ReservedWord] : +# 29| 2: [Integer] 4 +# 29| 2: [ReservedWord] , +# 29| 3: [Pair] Pair +# 29| 0: [HashKeySymbol] c +# 29| 1: [ReservedWord] : +# 29| 2: [Integer] 5 +# 29| 4: [ReservedWord] } # 29| 4: [ReservedWord] end # 32| 25: [Binary] Binary # 32| 0: [Identifier] w @@ -5432,23 +5504,24 @@ operations/operations.rb: # 87| 63: [Class] Class # 87| 0: [ReservedWord] class # 87| 1: [Constant] X -# 88| 2: [Assignment] Assignment -# 88| 0: [InstanceVariable] @x -# 88| 1: [ReservedWord] = -# 88| 2: [Integer] 1 -# 89| 3: [OperatorAssignment] OperatorAssignment -# 89| 0: [InstanceVariable] @x -# 89| 1: [ReservedWord] += -# 89| 2: [Integer] 2 -# 91| 4: [Assignment] Assignment -# 91| 0: [ClassVariable] @@y -# 91| 1: [ReservedWord] = -# 91| 2: [Integer] 3 -# 92| 5: [OperatorAssignment] OperatorAssignment -# 92| 0: [ClassVariable] @@y -# 92| 1: [ReservedWord] /= -# 92| 2: [Integer] 4 -# 93| 6: [ReservedWord] end +# 88| 2: [BodyStatement] BodyStatement +# 88| 0: [Assignment] Assignment +# 88| 0: [InstanceVariable] @x +# 88| 1: [ReservedWord] = +# 88| 2: [Integer] 1 +# 89| 1: [OperatorAssignment] OperatorAssignment +# 89| 0: [InstanceVariable] @x +# 89| 1: [ReservedWord] += +# 89| 2: [Integer] 2 +# 91| 2: [Assignment] Assignment +# 91| 0: [ClassVariable] @@y +# 91| 1: [ReservedWord] = +# 91| 2: [Integer] 3 +# 92| 3: [OperatorAssignment] OperatorAssignment +# 92| 0: [ClassVariable] @@y +# 92| 1: [ReservedWord] /= +# 92| 2: [Integer] 4 +# 93| 3: [ReservedWord] end # 95| 64: [Assignment] Assignment # 95| 0: [GlobalVariable] $global_var # 95| 1: [ReservedWord] = @@ -5501,21 +5574,22 @@ params/params.rb: # 9| 2: [ReservedWord] , # 9| 3: [Identifier] value # 9| 4: [ReservedWord] | -# 10| 2: [Call] Call -# 10| 0: [Identifier] puts -# 10| 1: [ArgumentList] ArgumentList -# 10| 0: [String] String -# 10| 0: [ReservedWord] " -# 10| 1: [Interpolation] Interpolation -# 10| 0: [ReservedWord] #{ -# 10| 1: [Identifier] key -# 10| 2: [ReservedWord] } -# 10| 2: [StringContent] -> -# 10| 3: [Interpolation] Interpolation -# 10| 0: [ReservedWord] #{ -# 10| 1: [Identifier] value -# 10| 2: [ReservedWord] } -# 10| 4: [ReservedWord] " +# 10| 2: [BodyStatement] BodyStatement +# 10| 0: [Call] Call +# 10| 0: [Identifier] puts +# 10| 1: [ArgumentList] ArgumentList +# 10| 0: [String] String +# 10| 0: [ReservedWord] " +# 10| 1: [Interpolation] Interpolation +# 10| 0: [ReservedWord] #{ +# 10| 1: [Identifier] key +# 10| 2: [ReservedWord] } +# 10| 2: [StringContent] -> +# 10| 3: [Interpolation] Interpolation +# 10| 0: [ReservedWord] #{ +# 10| 1: [Identifier] value +# 10| 2: [ReservedWord] } +# 10| 4: [ReservedWord] " # 11| 3: [ReservedWord] end # 14| 3: [Assignment] Assignment # 14| 0: [Identifier] sum @@ -5530,10 +5604,11 @@ params/params.rb: # 14| 4: [ReservedWord] ) # 14| 2: [Block] Block # 14| 0: [ReservedWord] { -# 14| 1: [Binary] Binary -# 14| 0: [Identifier] foo -# 14| 1: [ReservedWord] + -# 14| 2: [Identifier] bar +# 14| 1: [BlockBody] BlockBody +# 14| 0: [Binary] Binary +# 14| 0: [Identifier] foo +# 14| 1: [ReservedWord] + +# 14| 2: [Identifier] bar # 14| 2: [ReservedWord] } # 17| 4: [Method] Method # 17| 0: [ReservedWord] def @@ -5571,13 +5646,14 @@ params/params.rb: # 22| 3: [Identifier] b # 22| 4: [ReservedWord] ) # 22| 2: [ReservedWord] | -# 22| 2: [Call] Call -# 22| 0: [Identifier] puts -# 22| 1: [ArgumentList] ArgumentList -# 22| 0: [Binary] Binary -# 22| 0: [Identifier] a -# 22| 1: [ReservedWord] + -# 22| 2: [Identifier] b +# 22| 2: [BlockBody] BlockBody +# 22| 0: [Call] Call +# 22| 0: [Identifier] puts +# 22| 1: [ArgumentList] ArgumentList +# 22| 0: [Binary] Binary +# 22| 0: [Identifier] a +# 22| 1: [ReservedWord] + +# 22| 2: [Identifier] b # 22| 3: [ReservedWord] } # 25| 7: [Assignment] Assignment # 25| 0: [Identifier] sum_four_values @@ -5602,16 +5678,17 @@ params/params.rb: # 25| 4: [ReservedWord] ) # 25| 2: [Block] Block # 25| 0: [ReservedWord] { -# 26| 1: [Binary] Binary +# 26| 1: [BlockBody] BlockBody # 26| 0: [Binary] Binary # 26| 0: [Binary] Binary -# 26| 0: [Identifier] first +# 26| 0: [Binary] Binary +# 26| 0: [Identifier] first +# 26| 1: [ReservedWord] + +# 26| 2: [Identifier] second # 26| 1: [ReservedWord] + -# 26| 2: [Identifier] second +# 26| 2: [Identifier] third # 26| 1: [ReservedWord] + -# 26| 2: [Identifier] third -# 26| 1: [ReservedWord] + -# 26| 2: [Identifier] fourth +# 26| 2: [Identifier] fourth # 27| 2: [ReservedWord] } # 30| 8: [Method] Method # 30| 0: [ReservedWord] def @@ -5684,13 +5761,14 @@ params/params.rb: # 41| 1: [ReservedWord] : # 41| 2: [Integer] 7 # 41| 6: [ReservedWord] ) -# 42| 3: [Binary] Binary +# 42| 3: [BodyStatement] BodyStatement # 42| 0: [Binary] Binary -# 42| 0: [Identifier] x +# 42| 0: [Binary] Binary +# 42| 0: [Identifier] x +# 42| 1: [ReservedWord] + +# 42| 2: [Identifier] foo # 42| 1: [ReservedWord] + -# 42| 2: [Identifier] foo -# 42| 1: [ReservedWord] + -# 42| 2: [Identifier] bar +# 42| 2: [Identifier] bar # 43| 4: [ReservedWord] end # 46| 12: [Method] Method # 46| 0: [ReservedWord] def @@ -5701,25 +5779,26 @@ params/params.rb: # 46| 0: [ReservedWord] & # 46| 1: [Identifier] block # 46| 2: [ReservedWord] ) -# 47| 3: [Call] Call -# 47| 0: [Identifier] puts -# 47| 1: [ArgumentList] ArgumentList -# 47| 0: [ReservedWord] ( -# 47| 1: [Call] Call -# 47| 0: [Identifier] block -# 47| 1: [ReservedWord] . -# 47| 2: [Identifier] call -# 47| 3: [ArgumentList] ArgumentList -# 47| 0: [Pair] Pair -# 47| 0: [HashKeySymbol] bar -# 47| 1: [ReservedWord] : -# 47| 2: [Integer] 2 -# 47| 1: [ReservedWord] , -# 47| 2: [Pair] Pair -# 47| 0: [HashKeySymbol] foo -# 47| 1: [ReservedWord] : -# 47| 2: [Integer] 3 -# 47| 2: [ReservedWord] ) +# 47| 3: [BodyStatement] BodyStatement +# 47| 0: [Call] Call +# 47| 0: [Identifier] puts +# 47| 1: [ArgumentList] ArgumentList +# 47| 0: [ReservedWord] ( +# 47| 1: [Call] Call +# 47| 0: [Identifier] block +# 47| 1: [ReservedWord] . +# 47| 2: [Identifier] call +# 47| 3: [ArgumentList] ArgumentList +# 47| 0: [Pair] Pair +# 47| 0: [HashKeySymbol] bar +# 47| 1: [ReservedWord] : +# 47| 2: [Integer] 2 +# 47| 1: [ReservedWord] , +# 47| 2: [Pair] Pair +# 47| 0: [HashKeySymbol] foo +# 47| 1: [ReservedWord] : +# 47| 2: [Integer] 3 +# 47| 2: [ReservedWord] ) # 48| 4: [ReservedWord] end # 49| 13: [Call] Call # 49| 0: [Identifier] use_block_with_keyword @@ -5736,10 +5815,11 @@ params/params.rb: # 49| 1: [ReservedWord] : # 49| 2: [Integer] 100 # 49| 4: [ReservedWord] | -# 50| 2: [Binary] Binary -# 50| 0: [Identifier] xx -# 50| 1: [ReservedWord] + -# 50| 2: [Identifier] yy +# 50| 2: [BodyStatement] BodyStatement +# 50| 0: [Binary] Binary +# 50| 0: [Identifier] xx +# 50| 1: [ReservedWord] + +# 50| 2: [Identifier] yy # 51| 3: [ReservedWord] end # 53| 14: [Assignment] Assignment # 53| 0: [Identifier] lambda_with_keyword_params @@ -5761,13 +5841,14 @@ params/params.rb: # 53| 6: [ReservedWord] ) # 53| 2: [Block] Block # 53| 0: [ReservedWord] { -# 54| 1: [Binary] Binary +# 54| 1: [BlockBody] BlockBody # 54| 0: [Binary] Binary -# 54| 0: [Identifier] x +# 54| 0: [Binary] Binary +# 54| 0: [Identifier] x +# 54| 1: [ReservedWord] + +# 54| 2: [Identifier] y # 54| 1: [ReservedWord] + -# 54| 2: [Identifier] y -# 54| 1: [ReservedWord] + -# 54| 2: [Identifier] z +# 54| 2: [Identifier] z # 55| 2: [ReservedWord] } # 58| 15: [Method] Method # 58| 0: [ReservedWord] def @@ -5796,15 +5877,16 @@ params/params.rb: # 62| 0: [ReservedWord] & # 62| 1: [Identifier] block # 62| 2: [ReservedWord] ) -# 63| 3: [Call] Call -# 63| 0: [Identifier] block -# 63| 1: [ReservedWord] . -# 63| 2: [Identifier] call -# 63| 3: [ArgumentList] ArgumentList -# 63| 0: [String] String -# 63| 0: [ReservedWord] ' -# 63| 1: [StringContent] Zeus -# 63| 2: [ReservedWord] ' +# 63| 3: [BodyStatement] BodyStatement +# 63| 0: [Call] Call +# 63| 0: [Identifier] block +# 63| 1: [ReservedWord] . +# 63| 2: [Identifier] call +# 63| 3: [ArgumentList] ArgumentList +# 63| 0: [String] String +# 63| 0: [ReservedWord] ' +# 63| 1: [StringContent] Zeus +# 63| 2: [ReservedWord] ' # 64| 4: [ReservedWord] end # 65| 17: [Call] Call # 65| 0: [Identifier] use_block_with_optional @@ -5819,22 +5901,23 @@ params/params.rb: # 65| 1: [ReservedWord] = # 65| 2: [Integer] 99 # 65| 4: [ReservedWord] | -# 66| 2: [Call] Call -# 66| 0: [Identifier] puts -# 66| 1: [ArgumentList] ArgumentList -# 66| 0: [String] String -# 66| 0: [ReservedWord] " -# 66| 1: [Interpolation] Interpolation -# 66| 0: [ReservedWord] #{ -# 66| 1: [Identifier] name -# 66| 2: [ReservedWord] } -# 66| 2: [StringContent] is -# 66| 3: [Interpolation] Interpolation -# 66| 0: [ReservedWord] #{ -# 66| 1: [Identifier] age -# 66| 2: [ReservedWord] } -# 66| 4: [StringContent] years old -# 66| 5: [ReservedWord] " +# 66| 2: [BodyStatement] BodyStatement +# 66| 0: [Call] Call +# 66| 0: [Identifier] puts +# 66| 1: [ArgumentList] ArgumentList +# 66| 0: [String] String +# 66| 0: [ReservedWord] " +# 66| 1: [Interpolation] Interpolation +# 66| 0: [ReservedWord] #{ +# 66| 1: [Identifier] name +# 66| 2: [ReservedWord] } +# 66| 2: [StringContent] is +# 66| 3: [Interpolation] Interpolation +# 66| 0: [ReservedWord] #{ +# 66| 1: [Identifier] age +# 66| 2: [ReservedWord] } +# 66| 4: [StringContent] years old +# 66| 5: [ReservedWord] " # 67| 3: [ReservedWord] end # 70| 18: [Assignment] Assignment # 70| 0: [Identifier] lambda_with_optional_params @@ -5857,13 +5940,14 @@ params/params.rb: # 70| 6: [ReservedWord] ) # 70| 2: [Block] Block # 70| 0: [ReservedWord] { -# 70| 1: [Binary] Binary +# 70| 1: [BlockBody] BlockBody # 70| 0: [Binary] Binary -# 70| 0: [Identifier] a +# 70| 0: [Binary] Binary +# 70| 0: [Identifier] a +# 70| 1: [ReservedWord] + +# 70| 2: [Identifier] b # 70| 1: [ReservedWord] + -# 70| 2: [Identifier] b -# 70| 1: [ReservedWord] + -# 70| 2: [Identifier] c +# 70| 2: [Identifier] c # 70| 2: [ReservedWord] } # 73| 19: [Method] Method # 73| 0: [ReservedWord] def @@ -5902,23 +5986,24 @@ params/params.rb: # 81| 3: [BlockParameter] BlockParameter # 81| 0: [ReservedWord] & # 81| 4: [ReservedWord] ) -# 82| 3: [Call] Call -# 82| 0: [Identifier] proc -# 82| 1: [ArgumentList] ArgumentList -# 82| 0: [ReservedWord] ( -# 82| 1: [BlockArgument] BlockArgument -# 82| 0: [ReservedWord] & -# 82| 2: [ReservedWord] ) -# 83| 4: [Call] Call -# 83| 0: [Identifier] array -# 83| 1: [ReservedWord] . -# 83| 2: [Identifier] each -# 83| 3: [ArgumentList] ArgumentList -# 83| 0: [ReservedWord] ( -# 83| 1: [BlockArgument] BlockArgument -# 83| 0: [ReservedWord] & -# 83| 2: [ReservedWord] ) -# 84| 5: [ReservedWord] end +# 82| 3: [BodyStatement] BodyStatement +# 82| 0: [Call] Call +# 82| 0: [Identifier] proc +# 82| 1: [ArgumentList] ArgumentList +# 82| 0: [ReservedWord] ( +# 82| 1: [BlockArgument] BlockArgument +# 82| 0: [ReservedWord] & +# 82| 2: [ReservedWord] ) +# 83| 1: [Call] Call +# 83| 0: [Identifier] array +# 83| 1: [ReservedWord] . +# 83| 2: [Identifier] each +# 83| 3: [ArgumentList] ArgumentList +# 83| 0: [ReservedWord] ( +# 83| 1: [BlockArgument] BlockArgument +# 83| 0: [ReservedWord] & +# 83| 2: [ReservedWord] ) +# 84| 4: [ReservedWord] end # 86| 22: [Call] Call # 86| 0: [Identifier] run_block # 86| 1: [Block] Block @@ -5931,10 +6016,11 @@ params/params.rb: # 86| 4: [ReservedWord] , # 86| 5: [Identifier] z # 86| 6: [ReservedWord] | -# 86| 2: [Call] Call -# 86| 0: [Identifier] puts -# 86| 1: [ArgumentList] ArgumentList -# 86| 0: [Identifier] x +# 86| 2: [BlockBody] BlockBody +# 86| 0: [Call] Call +# 86| 0: [Identifier] puts +# 86| 1: [ArgumentList] ArgumentList +# 86| 0: [Identifier] x # 86| 3: [ReservedWord] } # 1| [Comment] # Tests for the different kinds and contexts of parameters. # 3| [Comment] # Method containing identifier parameters From ed005077fa88e44c5454a4c76055bc16c55cefa7 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 24 Aug 2022 17:52:04 +0200 Subject: [PATCH 021/203] Ruby: upgrade/downgrade scripts --- .../old.dbscheme | 1435 +++++++++++++++++ .../ruby.dbscheme | 1433 ++++++++++++++++ .../ruby_ast_node_info.ql | 28 + .../ruby_block_child.ql | 7 + .../ruby_class_child.ql | 7 + .../ruby_do_block_child.ql | 8 + .../ruby_method_child.ql | 14 + .../ruby_module_child.ql | 8 + .../ruby_singleton_class_child.ql | 8 + .../ruby_singleton_method_child.ql | 15 + .../upgrade.properties | 30 + .../locations_default.ql | 68 + .../old.dbscheme | 1433 ++++++++++++++++ .../ruby.dbscheme | 1435 +++++++++++++++++ .../ruby_ast_node_info.ql | 76 + .../ruby_block_body.ql | 11 + .../ruby_block_body_child.ql | 11 + .../ruby_block_body_def.ql | 18 + .../ruby_body_statement_child.ql | 36 + .../ruby_body_statement_def.ql | 43 + .../ruby_class_body.ql | 11 + .../ruby_do_block_body.ql | 11 + .../ruby_method_body.ql | 20 + .../ruby_module_body.ql | 11 + .../ruby_singleton_class_body.ql | 11 + .../ruby_singleton_method_body.ql | 17 + .../ruby_tokeninfo.ql | 46 + .../upgrade.properties | 33 + 28 files changed, 6284 insertions(+) create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/old.dbscheme create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby.dbscheme create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_ast_node_info.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_block_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_class_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_do_block_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_method_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_module_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_class_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_method_child.ql create mode 100644 ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/upgrade.properties create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/locations_default.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/old.dbscheme create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby.dbscheme create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_ast_node_info.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_child.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_def.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_child.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_def.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_class_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_do_block_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_method_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_module_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_class_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_method_body.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_tokeninfo.ql create mode 100644 ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/upgrade.properties diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/old.dbscheme b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/old.dbscheme new file mode 100644 index 00000000000..3595c826de6 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/old.dbscheme @@ -0,0 +1,1435 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +@location = @location_default + +locations_default( + unique int id: @location_default, + int file: @file ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +sourceLocationPrefix( + string prefix: string ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + + +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +@ruby_ast_node_parent = @file | @ruby_ast_node + +#keyset[parent, parent_index] +ruby_ast_node_info( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +@erb_ast_node_parent = @erb_ast_node | @file + +#keyset[parent, parent_index] +erb_ast_node_info( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby.dbscheme b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby.dbscheme new file mode 100644 index 00000000000..4ba51641799 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby.dbscheme @@ -0,0 +1,1433 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +@location = @location_default + +locations_default( + unique int id: @location_default, + int file: @file ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +sourceLocationPrefix( + string prefix: string ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + + +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +@ruby_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block, index] +ruby_block_child( + int ruby_block: @ruby_block ref, + int index: int ref, + unique int child: @ruby_block_child_type ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +@ruby_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_class, index] +ruby_class_child( + int ruby_class: @ruby_class ref, + int index: int ref, + unique int child: @ruby_class_child_type ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +@ruby_do_block_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do_block, index] +ruby_do_block_child( + int ruby_do_block: @ruby_do_block ref, + int index: int ref, + unique int child: @ruby_do_block_child_type ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +@ruby_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement + +#keyset[ruby_method, index] +ruby_method_child( + int ruby_method: @ruby_method ref, + int index: int ref, + unique int child: @ruby_method_child_type ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +@ruby_module_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_module, index] +ruby_module_child( + int ruby_module: @ruby_module ref, + int index: int ref, + unique int child: @ruby_module_child_type ref +); + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +@ruby_singleton_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_singleton_class, index] +ruby_singleton_class_child( + int ruby_singleton_class: @ruby_singleton_class ref, + int index: int ref, + unique int child: @ruby_singleton_class_child_type ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +@ruby_singleton_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement + +#keyset[ruby_singleton_method, index] +ruby_singleton_method_child( + int ruby_singleton_method: @ruby_singleton_method ref, + int index: int ref, + unique int child: @ruby_singleton_method_child_type ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_parameter | @ruby_block_parameters | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +@ruby_ast_node_parent = @file | @ruby_ast_node + +#keyset[parent, parent_index] +ruby_ast_node_info( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +@erb_ast_node_parent = @erb_ast_node | @file + +#keyset[parent, parent_index] +erb_ast_node_info( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_ast_node_info.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_ast_node_info.ql new file mode 100644 index 00000000000..c418da98507 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_ast_node_info.ql @@ -0,0 +1,28 @@ +class AstNode extends @ruby_ast_node_parent { + string toString() { none() } +} + +class Location extends @location { + string toString() { none() } +} + +class Wrapper = @ruby_body_statement or @ruby_block_body; + +predicate astNodeInfo(AstNode child, AstNode parent, int primaryIndex, int secondaryIndex) { + not parent instanceof Wrapper and + exists(AstNode node, Location l | + ruby_ast_node_info(node, parent, primaryIndex, _) and + ( + not node instanceof Wrapper and secondaryIndex = 0 and child = node + or + node instanceof Wrapper and ruby_ast_node_info(child, node, secondaryIndex, _) + ) + ) +} + +from AstNode node, AstNode parent, int parent_index, Location loc +where + node = + rank[parent_index + 1](AstNode n, int i, int j | astNodeInfo(n, parent, i, j) | n order by i, j) and + ruby_ast_node_info(node, _, _, loc) +select node, parent, parent_index, loc diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_block_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_block_child.ql new file mode 100644 index 00000000000..f12816e6f44 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_block_child.ql @@ -0,0 +1,7 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_block, AstNode body, int index, AstNode child +where ruby_block_body(ruby_block, body) and ruby_block_body_child(body, index, child) +select ruby_block, index, child diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_class_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_class_child.ql new file mode 100644 index 00000000000..bba0cc7ec3a --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_class_child.ql @@ -0,0 +1,7 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_class, AstNode body, int index, AstNode child +where ruby_class_body(ruby_class, body) and ruby_body_statement_child(body, index, child) +select ruby_class, index, child diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_do_block_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_do_block_child.ql new file mode 100644 index 00000000000..d08bb83a41c --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_do_block_child.ql @@ -0,0 +1,8 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_do_block, AstNode body, int index, AstNode child +where ruby_do_block_body(ruby_do_block, body) and ruby_body_statement_child(body, index, child) +select ruby_do_block, index, child + diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_method_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_method_child.ql new file mode 100644 index 00000000000..fffa33ea4c7 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_method_child.ql @@ -0,0 +1,14 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_method, int index, AstNode child +where + exists(AstNode body | + ruby_method_body(ruby_method, body) and ruby_body_statement_child(body, index, child) + ) + or + ruby_method_body(ruby_method, child) and + not child instanceof @ruby_body_statement and + index = 0 +select ruby_method, index, child diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_module_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_module_child.ql new file mode 100644 index 00000000000..c7ea0dcdadf --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_module_child.ql @@ -0,0 +1,8 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_module, AstNode body, int index, AstNode child +where ruby_module_body(ruby_module, body) and ruby_body_statement_child(body, index, child) +select ruby_module, index, child + diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_class_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_class_child.ql new file mode 100644 index 00000000000..3d2e45d0ec6 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_class_child.ql @@ -0,0 +1,8 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_singleton_class, AstNode body, int index, AstNode child +where ruby_singleton_class_body(ruby_singleton_class, body) and ruby_body_statement_child(body, index, child) +select ruby_singleton_class, index, child + diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_method_child.ql b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_method_child.ql new file mode 100644 index 00000000000..cc76fecefeb --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/ruby_singleton_method_child.ql @@ -0,0 +1,15 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_singleton_method, int index, AstNode child +where + exists(AstNode body | + ruby_singleton_method_body(ruby_singleton_method, body) and + ruby_body_statement_child(body, index, child) + ) + or + ruby_singleton_method_body(ruby_singleton_method, child) and + not child instanceof @ruby_body_statement and + index = 0 +select ruby_singleton_method, index, child diff --git a/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/upgrade.properties b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/upgrade.properties new file mode 100644 index 00000000000..6d90aac9b38 --- /dev/null +++ b/ruby/downgrades/3595c826de6db850f16b9da265a54dbf24dd3126/upgrade.properties @@ -0,0 +1,30 @@ +description: Wrap class, module, method, and block bodies in a named node +compatibility: full + +ruby_block_body.rel: delete +ruby_block_body_def.rel: delete +ruby_block_body_child.rel: delete +ruby_block_child.rel: run ruby_block_child.qlo + +ruby_body_statement_child.rel: delete +ruby_body_statement_def.rel: delete + +ruby_class_body.rel: delete +ruby_class_child.rel: run ruby_class_child.qlo + +ruby_do_block_body.rel: delete +ruby_do_block_child.rel: run ruby_do_block_child.qlo + +ruby_method_body.rel: delete +ruby_method_child.rel: run ruby_method_child.qlo + +ruby_module_body.rel: delete +ruby_module_child.rel: run ruby_module_child.qlo + +ruby_singleton_class_body.rel: delete +ruby_singleton_class_child.rel: run ruby_singleton_class_child.qlo + +ruby_singleton_method_body.rel: delete +ruby_singleton_method_child.rel: run ruby_singleton_method_child.qlo + +ruby_ast_node_info.rel: run ruby_ast_node_info.qlo \ No newline at end of file diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/locations_default.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/locations_default.ql new file mode 100644 index 00000000000..7300d50b097 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/locations_default.ql @@ -0,0 +1,68 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +class Location extends @location { + string toString() { none() } +} + +class File extends @file { + string toString() { none() } +} + +private predicate body_statement(AstNode body, int index, Location loc) { + exists(AstNode node, AstNode child | ruby_ast_node_info(child, _, _, loc) | + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, index, child) + or + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, index, child) + or + ruby_method_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, index, child) + or + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, index, child) + or + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, index, child) + or + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, index, child) + or + ruby_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(node, index, child) + ) +} + +from Location loc, File file, int start_line, int start_column, int end_line, int end_column +where + locations_default(loc, file, start_line, start_column, end_line, end_column) and + not exists(AstNode node | ruby_ast_node_info(node, _, _, loc) and body_statement(node, _, _)) + or + exists(AstNode node | + ruby_ast_node_info(node, _, _, loc) and + exists(Location first | + body_statement(node, 0, first) and + locations_default(first, file, start_line, start_column, _, _) + ) and + exists(Location last | + last = max(Location l, int i | body_statement(node, i, l) | l order by i) and + locations_default(last, file, _, _, end_line, end_column) + ) + ) +select loc, file, start_line, start_column, end_line, end_column diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/old.dbscheme b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/old.dbscheme new file mode 100644 index 00000000000..4ba51641799 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/old.dbscheme @@ -0,0 +1,1433 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +@location = @location_default + +locations_default( + unique int id: @location_default, + int file: @file ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +sourceLocationPrefix( + string prefix: string ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + + +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +@ruby_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block, index] +ruby_block_child( + int ruby_block: @ruby_block ref, + int index: int ref, + unique int child: @ruby_block_child_type ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +@ruby_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_class, index] +ruby_class_child( + int ruby_class: @ruby_class ref, + int index: int ref, + unique int child: @ruby_class_child_type ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +@ruby_do_block_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do_block, index] +ruby_do_block_child( + int ruby_do_block: @ruby_do_block ref, + int index: int ref, + unique int child: @ruby_do_block_child_type ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +@ruby_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement + +#keyset[ruby_method, index] +ruby_method_child( + int ruby_method: @ruby_method ref, + int index: int ref, + unique int child: @ruby_method_child_type ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +@ruby_module_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_module, index] +ruby_module_child( + int ruby_module: @ruby_module ref, + int index: int ref, + unique int child: @ruby_module_child_type ref +); + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +@ruby_singleton_class_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_singleton_class, index] +ruby_singleton_class_child( + int ruby_singleton_class: @ruby_singleton_class ref, + int index: int ref, + unique int child: @ruby_singleton_class_child_type ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +@ruby_singleton_method_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_arg | @ruby_underscore_statement + +#keyset[ruby_singleton_method, index] +ruby_singleton_method_child( + int ruby_singleton_method: @ruby_singleton_method ref, + int index: int ref, + unique int child: @ruby_singleton_method_child_type ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_parameter | @ruby_block_parameters | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +@ruby_ast_node_parent = @file | @ruby_ast_node + +#keyset[parent, parent_index] +ruby_ast_node_info( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +@erb_ast_node_parent = @erb_ast_node | @file + +#keyset[parent, parent_index] +erb_ast_node_info( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby.dbscheme b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby.dbscheme new file mode 100644 index 00000000000..3595c826de6 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby.dbscheme @@ -0,0 +1,1435 @@ +// CodeQL database schema for Ruby +// Automatically generated from the tree-sitter grammar; do not edit + +@location = @location_default + +locations_default( + unique int id: @location_default, + int file: @file ref, + int start_line: int ref, + int start_column: int ref, + int end_line: int ref, + int end_column: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +sourceLocationPrefix( + string prefix: string ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + + +@ruby_underscore_arg = @ruby_assignment | @ruby_binary | @ruby_conditional | @ruby_operator_assignment | @ruby_range | @ruby_unary | @ruby_underscore_primary + +@ruby_underscore_call_operator = @ruby_reserved_word + +@ruby_underscore_expression = @ruby_assignment | @ruby_binary | @ruby_break | @ruby_call | @ruby_next | @ruby_operator_assignment | @ruby_return | @ruby_unary | @ruby_underscore_arg | @ruby_yield + +@ruby_underscore_lhs = @ruby_call | @ruby_element_reference | @ruby_scope_resolution | @ruby_token_false | @ruby_token_nil | @ruby_token_true | @ruby_underscore_variable + +@ruby_underscore_method_name = @ruby_delimited_symbol | @ruby_setter | @ruby_token_constant | @ruby_token_identifier | @ruby_token_operator | @ruby_token_simple_symbol | @ruby_underscore_nonlocal_variable + +@ruby_underscore_nonlocal_variable = @ruby_token_class_variable | @ruby_token_global_variable | @ruby_token_instance_variable + +@ruby_underscore_pattern_constant = @ruby_scope_resolution | @ruby_token_constant + +@ruby_underscore_pattern_expr = @ruby_alternative_pattern | @ruby_as_pattern | @ruby_underscore_pattern_expr_basic + +@ruby_underscore_pattern_expr_basic = @ruby_array_pattern | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_parenthesized_pattern | @ruby_range | @ruby_token_identifier | @ruby_underscore_pattern_constant | @ruby_underscore_pattern_primitive | @ruby_variable_reference_pattern + +@ruby_underscore_pattern_primitive = @ruby_delimited_symbol | @ruby_lambda | @ruby_regex | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_encoding | @ruby_token_false | @ruby_token_file | @ruby_token_heredoc_beginning | @ruby_token_line | @ruby_token_nil | @ruby_token_self | @ruby_token_simple_symbol | @ruby_token_true | @ruby_unary | @ruby_underscore_simple_numeric + +@ruby_underscore_pattern_top_expr_body = @ruby_array_pattern | @ruby_find_pattern | @ruby_hash_pattern | @ruby_underscore_pattern_expr + +@ruby_underscore_primary = @ruby_array | @ruby_begin | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_delimited_symbol | @ruby_for | @ruby_hash | @ruby_if | @ruby_lambda | @ruby_method | @ruby_module | @ruby_next | @ruby_parenthesized_statements | @ruby_redo | @ruby_regex | @ruby_retry | @ruby_return | @ruby_singleton_class | @ruby_singleton_method | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_symbol_array | @ruby_token_character | @ruby_token_heredoc_beginning | @ruby_token_simple_symbol | @ruby_unary | @ruby_underscore_lhs | @ruby_underscore_simple_numeric | @ruby_unless | @ruby_until | @ruby_while | @ruby_yield + +@ruby_underscore_simple_numeric = @ruby_complex | @ruby_rational | @ruby_token_float | @ruby_token_integer + +@ruby_underscore_statement = @ruby_alias | @ruby_begin_block | @ruby_end_block | @ruby_if_modifier | @ruby_rescue_modifier | @ruby_undef | @ruby_underscore_expression | @ruby_unless_modifier | @ruby_until_modifier | @ruby_while_modifier + +@ruby_underscore_variable = @ruby_token_constant | @ruby_token_identifier | @ruby_token_self | @ruby_token_super | @ruby_underscore_nonlocal_variable + +ruby_alias_def( + unique int id: @ruby_alias, + int alias: @ruby_underscore_method_name ref, + int name: @ruby_underscore_method_name ref +); + +#keyset[ruby_alternative_pattern, index] +ruby_alternative_pattern_alternatives( + int ruby_alternative_pattern: @ruby_alternative_pattern ref, + int index: int ref, + unique int alternatives: @ruby_underscore_pattern_expr_basic ref +); + +ruby_alternative_pattern_def( + unique int id: @ruby_alternative_pattern +); + +@ruby_argument_list_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_argument_list, index] +ruby_argument_list_child( + int ruby_argument_list: @ruby_argument_list ref, + int index: int ref, + unique int child: @ruby_argument_list_child_type ref +); + +ruby_argument_list_def( + unique int id: @ruby_argument_list +); + +@ruby_array_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_array, index] +ruby_array_child( + int ruby_array: @ruby_array ref, + int index: int ref, + unique int child: @ruby_array_child_type ref +); + +ruby_array_def( + unique int id: @ruby_array +); + +ruby_array_pattern_class( + unique int ruby_array_pattern: @ruby_array_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_array_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_array_pattern, index] +ruby_array_pattern_child( + int ruby_array_pattern: @ruby_array_pattern ref, + int index: int ref, + unique int child: @ruby_array_pattern_child_type ref +); + +ruby_array_pattern_def( + unique int id: @ruby_array_pattern +); + +ruby_as_pattern_def( + unique int id: @ruby_as_pattern, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_pattern_expr ref +); + +@ruby_assignment_left_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +@ruby_assignment_right_type = @ruby_rescue_modifier | @ruby_right_assignment_list | @ruby_splat_argument | @ruby_underscore_expression + +ruby_assignment_def( + unique int id: @ruby_assignment, + int left: @ruby_assignment_left_type ref, + int right: @ruby_assignment_right_type ref +); + +@ruby_bare_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_string, index] +ruby_bare_string_child( + int ruby_bare_string: @ruby_bare_string ref, + int index: int ref, + unique int child: @ruby_bare_string_child_type ref +); + +ruby_bare_string_def( + unique int id: @ruby_bare_string +); + +@ruby_bare_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_bare_symbol, index] +ruby_bare_symbol_child( + int ruby_bare_symbol: @ruby_bare_symbol ref, + int index: int ref, + unique int child: @ruby_bare_symbol_child_type ref +); + +ruby_bare_symbol_def( + unique int id: @ruby_bare_symbol +); + +@ruby_begin_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin, index] +ruby_begin_child( + int ruby_begin: @ruby_begin ref, + int index: int ref, + unique int child: @ruby_begin_child_type ref +); + +ruby_begin_def( + unique int id: @ruby_begin +); + +@ruby_begin_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_begin_block, index] +ruby_begin_block_child( + int ruby_begin_block: @ruby_begin_block ref, + int index: int ref, + unique int child: @ruby_begin_block_child_type ref +); + +ruby_begin_block_def( + unique int id: @ruby_begin_block +); + +@ruby_binary_left_type = @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_binary.operator of + 0 = @ruby_binary_bangequal +| 1 = @ruby_binary_bangtilde +| 2 = @ruby_binary_percent +| 3 = @ruby_binary_ampersand +| 4 = @ruby_binary_ampersandampersand +| 5 = @ruby_binary_star +| 6 = @ruby_binary_starstar +| 7 = @ruby_binary_plus +| 8 = @ruby_binary_minus +| 9 = @ruby_binary_slash +| 10 = @ruby_binary_langle +| 11 = @ruby_binary_langlelangle +| 12 = @ruby_binary_langleequal +| 13 = @ruby_binary_langleequalrangle +| 14 = @ruby_binary_equalequal +| 15 = @ruby_binary_equalequalequal +| 16 = @ruby_binary_equaltilde +| 17 = @ruby_binary_rangle +| 18 = @ruby_binary_rangleequal +| 19 = @ruby_binary_ranglerangle +| 20 = @ruby_binary_caret +| 21 = @ruby_binary_and +| 22 = @ruby_binary_or +| 23 = @ruby_binary_pipe +| 24 = @ruby_binary_pipepipe +; + + +ruby_binary_def( + unique int id: @ruby_binary, + int left: @ruby_binary_left_type ref, + int operator: int ref, + int right: @ruby_underscore_expression ref +); + +ruby_block_body( + unique int ruby_block: @ruby_block ref, + unique int body: @ruby_block_body ref +); + +ruby_block_parameters( + unique int ruby_block: @ruby_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_block_def( + unique int id: @ruby_block +); + +ruby_block_argument_child( + unique int ruby_block_argument: @ruby_block_argument ref, + unique int child: @ruby_underscore_arg ref +); + +ruby_block_argument_def( + unique int id: @ruby_block_argument +); + +@ruby_block_body_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_block_body, index] +ruby_block_body_child( + int ruby_block_body: @ruby_block_body ref, + int index: int ref, + unique int child: @ruby_block_body_child_type ref +); + +ruby_block_body_def( + unique int id: @ruby_block_body +); + +ruby_block_parameter_name( + unique int ruby_block_parameter: @ruby_block_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_block_parameter_def( + unique int id: @ruby_block_parameter +); + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_locals( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int locals: @ruby_token_identifier ref +); + +@ruby_block_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_block_parameters, index] +ruby_block_parameters_child( + int ruby_block_parameters: @ruby_block_parameters ref, + int index: int ref, + unique int child: @ruby_block_parameters_child_type ref +); + +ruby_block_parameters_def( + unique int id: @ruby_block_parameters +); + +@ruby_body_statement_child_type = @ruby_else | @ruby_ensure | @ruby_rescue | @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_body_statement, index] +ruby_body_statement_child( + int ruby_body_statement: @ruby_body_statement ref, + int index: int ref, + unique int child: @ruby_body_statement_child_type ref +); + +ruby_body_statement_def( + unique int id: @ruby_body_statement +); + +ruby_break_child( + unique int ruby_break: @ruby_break ref, + unique int child: @ruby_argument_list ref +); + +ruby_break_def( + unique int id: @ruby_break +); + +ruby_call_arguments( + unique int ruby_call: @ruby_call ref, + unique int arguments: @ruby_argument_list ref +); + +@ruby_call_block_type = @ruby_block | @ruby_do_block + +ruby_call_block( + unique int ruby_call: @ruby_call ref, + unique int block: @ruby_call_block_type ref +); + +@ruby_call_method_type = @ruby_token_operator | @ruby_underscore_variable + +ruby_call_method( + unique int ruby_call: @ruby_call ref, + unique int method: @ruby_call_method_type ref +); + +ruby_call_operator( + unique int ruby_call: @ruby_call ref, + unique int operator: @ruby_underscore_call_operator ref +); + +ruby_call_receiver( + unique int ruby_call: @ruby_call ref, + unique int receiver: @ruby_underscore_primary ref +); + +ruby_call_def( + unique int id: @ruby_call +); + +ruby_case_value( + unique int ruby_case__: @ruby_case__ ref, + unique int value: @ruby_underscore_statement ref +); + +@ruby_case_child_type = @ruby_else | @ruby_when + +#keyset[ruby_case__, index] +ruby_case_child( + int ruby_case__: @ruby_case__ ref, + int index: int ref, + unique int child: @ruby_case_child_type ref +); + +ruby_case_def( + unique int id: @ruby_case__ +); + +#keyset[ruby_case_match, index] +ruby_case_match_clauses( + int ruby_case_match: @ruby_case_match ref, + int index: int ref, + unique int clauses: @ruby_in_clause ref +); + +ruby_case_match_else( + unique int ruby_case_match: @ruby_case_match ref, + unique int else: @ruby_else ref +); + +ruby_case_match_def( + unique int id: @ruby_case_match, + int value: @ruby_underscore_statement ref +); + +#keyset[ruby_chained_string, index] +ruby_chained_string_child( + int ruby_chained_string: @ruby_chained_string ref, + int index: int ref, + unique int child: @ruby_string__ ref +); + +ruby_chained_string_def( + unique int id: @ruby_chained_string +); + +ruby_class_body( + unique int ruby_class: @ruby_class ref, + unique int body: @ruby_body_statement ref +); + +@ruby_class_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_class_superclass( + unique int ruby_class: @ruby_class ref, + unique int superclass: @ruby_superclass ref +); + +ruby_class_def( + unique int id: @ruby_class, + int name: @ruby_class_name_type ref +); + +@ruby_complex_child_type = @ruby_rational | @ruby_token_float | @ruby_token_integer + +ruby_complex_def( + unique int id: @ruby_complex, + int child: @ruby_complex_child_type ref +); + +ruby_conditional_def( + unique int id: @ruby_conditional, + int alternative: @ruby_underscore_arg ref, + int condition: @ruby_underscore_arg ref, + int consequence: @ruby_underscore_arg ref +); + +@ruby_delimited_symbol_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_delimited_symbol, index] +ruby_delimited_symbol_child( + int ruby_delimited_symbol: @ruby_delimited_symbol ref, + int index: int ref, + unique int child: @ruby_delimited_symbol_child_type ref +); + +ruby_delimited_symbol_def( + unique int id: @ruby_delimited_symbol +); + +@ruby_destructured_left_assignment_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_destructured_left_assignment, index] +ruby_destructured_left_assignment_child( + int ruby_destructured_left_assignment: @ruby_destructured_left_assignment ref, + int index: int ref, + unique int child: @ruby_destructured_left_assignment_child_type ref +); + +ruby_destructured_left_assignment_def( + unique int id: @ruby_destructured_left_assignment +); + +@ruby_destructured_parameter_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_destructured_parameter, index] +ruby_destructured_parameter_child( + int ruby_destructured_parameter: @ruby_destructured_parameter ref, + int index: int ref, + unique int child: @ruby_destructured_parameter_child_type ref +); + +ruby_destructured_parameter_def( + unique int id: @ruby_destructured_parameter +); + +@ruby_do_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_do, index] +ruby_do_child( + int ruby_do: @ruby_do ref, + int index: int ref, + unique int child: @ruby_do_child_type ref +); + +ruby_do_def( + unique int id: @ruby_do +); + +ruby_do_block_body( + unique int ruby_do_block: @ruby_do_block ref, + unique int body: @ruby_body_statement ref +); + +ruby_do_block_parameters( + unique int ruby_do_block: @ruby_do_block ref, + unique int parameters: @ruby_block_parameters ref +); + +ruby_do_block_def( + unique int id: @ruby_do_block +); + +@ruby_element_reference_child_type = @ruby_block_argument | @ruby_hash_splat_argument | @ruby_pair | @ruby_splat_argument | @ruby_token_forward_argument | @ruby_underscore_expression + +#keyset[ruby_element_reference, index] +ruby_element_reference_child( + int ruby_element_reference: @ruby_element_reference ref, + int index: int ref, + unique int child: @ruby_element_reference_child_type ref +); + +ruby_element_reference_def( + unique int id: @ruby_element_reference, + int object: @ruby_underscore_primary ref +); + +@ruby_else_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_else, index] +ruby_else_child( + int ruby_else: @ruby_else ref, + int index: int ref, + unique int child: @ruby_else_child_type ref +); + +ruby_else_def( + unique int id: @ruby_else +); + +@ruby_elsif_alternative_type = @ruby_else | @ruby_elsif + +ruby_elsif_alternative( + unique int ruby_elsif: @ruby_elsif ref, + unique int alternative: @ruby_elsif_alternative_type ref +); + +ruby_elsif_consequence( + unique int ruby_elsif: @ruby_elsif ref, + unique int consequence: @ruby_then ref +); + +ruby_elsif_def( + unique int id: @ruby_elsif, + int condition: @ruby_underscore_statement ref +); + +@ruby_end_block_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_end_block, index] +ruby_end_block_child( + int ruby_end_block: @ruby_end_block ref, + int index: int ref, + unique int child: @ruby_end_block_child_type ref +); + +ruby_end_block_def( + unique int id: @ruby_end_block +); + +@ruby_ensure_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_ensure, index] +ruby_ensure_child( + int ruby_ensure: @ruby_ensure ref, + int index: int ref, + unique int child: @ruby_ensure_child_type ref +); + +ruby_ensure_def( + unique int id: @ruby_ensure +); + +ruby_exception_variable_def( + unique int id: @ruby_exception_variable, + int child: @ruby_underscore_lhs ref +); + +@ruby_exceptions_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_exceptions, index] +ruby_exceptions_child( + int ruby_exceptions: @ruby_exceptions ref, + int index: int ref, + unique int child: @ruby_exceptions_child_type ref +); + +ruby_exceptions_def( + unique int id: @ruby_exceptions +); + +ruby_expression_reference_pattern_def( + unique int id: @ruby_expression_reference_pattern, + int value: @ruby_underscore_expression ref +); + +ruby_find_pattern_class( + unique int ruby_find_pattern: @ruby_find_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_find_pattern_child_type = @ruby_splat_parameter | @ruby_underscore_pattern_expr + +#keyset[ruby_find_pattern, index] +ruby_find_pattern_child( + int ruby_find_pattern: @ruby_find_pattern ref, + int index: int ref, + unique int child: @ruby_find_pattern_child_type ref +); + +ruby_find_pattern_def( + unique int id: @ruby_find_pattern +); + +@ruby_for_pattern_type = @ruby_left_assignment_list | @ruby_underscore_lhs + +ruby_for_def( + unique int id: @ruby_for, + int body: @ruby_do ref, + int pattern: @ruby_for_pattern_type ref, + int value: @ruby_in ref +); + +@ruby_hash_child_type = @ruby_hash_splat_argument | @ruby_pair + +#keyset[ruby_hash, index] +ruby_hash_child( + int ruby_hash: @ruby_hash ref, + int index: int ref, + unique int child: @ruby_hash_child_type ref +); + +ruby_hash_def( + unique int id: @ruby_hash +); + +ruby_hash_pattern_class( + unique int ruby_hash_pattern: @ruby_hash_pattern ref, + unique int class: @ruby_underscore_pattern_constant ref +); + +@ruby_hash_pattern_child_type = @ruby_hash_splat_parameter | @ruby_keyword_pattern | @ruby_token_hash_splat_nil + +#keyset[ruby_hash_pattern, index] +ruby_hash_pattern_child( + int ruby_hash_pattern: @ruby_hash_pattern ref, + int index: int ref, + unique int child: @ruby_hash_pattern_child_type ref +); + +ruby_hash_pattern_def( + unique int id: @ruby_hash_pattern +); + +ruby_hash_splat_argument_def( + unique int id: @ruby_hash_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_hash_splat_parameter_name( + unique int ruby_hash_splat_parameter: @ruby_hash_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_hash_splat_parameter_def( + unique int id: @ruby_hash_splat_parameter +); + +@ruby_heredoc_body_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_heredoc_content | @ruby_token_heredoc_end + +#keyset[ruby_heredoc_body, index] +ruby_heredoc_body_child( + int ruby_heredoc_body: @ruby_heredoc_body ref, + int index: int ref, + unique int child: @ruby_heredoc_body_child_type ref +); + +ruby_heredoc_body_def( + unique int id: @ruby_heredoc_body +); + +@ruby_if_alternative_type = @ruby_else | @ruby_elsif + +ruby_if_alternative( + unique int ruby_if: @ruby_if ref, + unique int alternative: @ruby_if_alternative_type ref +); + +ruby_if_consequence( + unique int ruby_if: @ruby_if ref, + unique int consequence: @ruby_then ref +); + +ruby_if_def( + unique int id: @ruby_if, + int condition: @ruby_underscore_statement ref +); + +ruby_if_guard_def( + unique int id: @ruby_if_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_if_modifier_def( + unique int id: @ruby_if_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_in_def( + unique int id: @ruby_in, + int child: @ruby_underscore_arg ref +); + +ruby_in_clause_body( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int body: @ruby_then ref +); + +@ruby_in_clause_guard_type = @ruby_if_guard | @ruby_unless_guard + +ruby_in_clause_guard( + unique int ruby_in_clause: @ruby_in_clause ref, + unique int guard: @ruby_in_clause_guard_type ref +); + +ruby_in_clause_def( + unique int id: @ruby_in_clause, + int pattern: @ruby_underscore_pattern_top_expr_body ref +); + +@ruby_interpolation_child_type = @ruby_token_empty_statement | @ruby_underscore_nonlocal_variable | @ruby_underscore_statement + +#keyset[ruby_interpolation, index] +ruby_interpolation_child( + int ruby_interpolation: @ruby_interpolation ref, + int index: int ref, + unique int child: @ruby_interpolation_child_type ref +); + +ruby_interpolation_def( + unique int id: @ruby_interpolation +); + +ruby_keyword_parameter_value( + unique int ruby_keyword_parameter: @ruby_keyword_parameter ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_keyword_parameter_def( + unique int id: @ruby_keyword_parameter, + int name: @ruby_token_identifier ref +); + +@ruby_keyword_pattern_key_type = @ruby_string__ | @ruby_token_hash_key_symbol + +ruby_keyword_pattern_value( + unique int ruby_keyword_pattern: @ruby_keyword_pattern ref, + unique int value: @ruby_underscore_pattern_expr ref +); + +ruby_keyword_pattern_def( + unique int id: @ruby_keyword_pattern, + int key__: @ruby_keyword_pattern_key_type ref +); + +@ruby_lambda_body_type = @ruby_block | @ruby_do_block + +ruby_lambda_parameters( + unique int ruby_lambda: @ruby_lambda ref, + unique int parameters: @ruby_lambda_parameters ref +); + +ruby_lambda_def( + unique int id: @ruby_lambda, + int body: @ruby_lambda_body_type ref +); + +@ruby_lambda_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_lambda_parameters, index] +ruby_lambda_parameters_child( + int ruby_lambda_parameters: @ruby_lambda_parameters ref, + int index: int ref, + unique int child: @ruby_lambda_parameters_child_type ref +); + +ruby_lambda_parameters_def( + unique int id: @ruby_lambda_parameters +); + +@ruby_left_assignment_list_child_type = @ruby_destructured_left_assignment | @ruby_rest_assignment | @ruby_underscore_lhs + +#keyset[ruby_left_assignment_list, index] +ruby_left_assignment_list_child( + int ruby_left_assignment_list: @ruby_left_assignment_list ref, + int index: int ref, + unique int child: @ruby_left_assignment_list_child_type ref +); + +ruby_left_assignment_list_def( + unique int id: @ruby_left_assignment_list +); + +@ruby_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_method_body( + unique int ruby_method: @ruby_method ref, + unique int body: @ruby_method_body_type ref +); + +ruby_method_parameters( + unique int ruby_method: @ruby_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_method_def( + unique int id: @ruby_method, + int name: @ruby_underscore_method_name ref +); + +@ruby_method_parameters_child_type = @ruby_block_parameter | @ruby_destructured_parameter | @ruby_hash_splat_parameter | @ruby_keyword_parameter | @ruby_optional_parameter | @ruby_splat_parameter | @ruby_token_forward_parameter | @ruby_token_hash_splat_nil | @ruby_token_identifier + +#keyset[ruby_method_parameters, index] +ruby_method_parameters_child( + int ruby_method_parameters: @ruby_method_parameters ref, + int index: int ref, + unique int child: @ruby_method_parameters_child_type ref +); + +ruby_method_parameters_def( + unique int id: @ruby_method_parameters +); + +ruby_module_body( + unique int ruby_module: @ruby_module ref, + unique int body: @ruby_body_statement ref +); + +@ruby_module_name_type = @ruby_scope_resolution | @ruby_token_constant + +ruby_module_def( + unique int id: @ruby_module, + int name: @ruby_module_name_type ref +); + +ruby_next_child( + unique int ruby_next: @ruby_next ref, + unique int child: @ruby_argument_list ref +); + +ruby_next_def( + unique int id: @ruby_next +); + +case @ruby_operator_assignment.operator of + 0 = @ruby_operator_assignment_percentequal +| 1 = @ruby_operator_assignment_ampersandampersandequal +| 2 = @ruby_operator_assignment_ampersandequal +| 3 = @ruby_operator_assignment_starstarequal +| 4 = @ruby_operator_assignment_starequal +| 5 = @ruby_operator_assignment_plusequal +| 6 = @ruby_operator_assignment_minusequal +| 7 = @ruby_operator_assignment_slashequal +| 8 = @ruby_operator_assignment_langlelangleequal +| 9 = @ruby_operator_assignment_ranglerangleequal +| 10 = @ruby_operator_assignment_caretequal +| 11 = @ruby_operator_assignment_pipeequal +| 12 = @ruby_operator_assignment_pipepipeequal +; + + +@ruby_operator_assignment_right_type = @ruby_rescue_modifier | @ruby_underscore_expression + +ruby_operator_assignment_def( + unique int id: @ruby_operator_assignment, + int left: @ruby_underscore_lhs ref, + int operator: int ref, + int right: @ruby_operator_assignment_right_type ref +); + +ruby_optional_parameter_def( + unique int id: @ruby_optional_parameter, + int name: @ruby_token_identifier ref, + int value: @ruby_underscore_arg ref +); + +@ruby_pair_key_type = @ruby_string__ | @ruby_token_hash_key_symbol | @ruby_underscore_arg + +ruby_pair_value( + unique int ruby_pair: @ruby_pair ref, + unique int value: @ruby_underscore_arg ref +); + +ruby_pair_def( + unique int id: @ruby_pair, + int key__: @ruby_pair_key_type ref +); + +ruby_parenthesized_pattern_def( + unique int id: @ruby_parenthesized_pattern, + int child: @ruby_underscore_pattern_expr ref +); + +@ruby_parenthesized_statements_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_parenthesized_statements, index] +ruby_parenthesized_statements_child( + int ruby_parenthesized_statements: @ruby_parenthesized_statements ref, + int index: int ref, + unique int child: @ruby_parenthesized_statements_child_type ref +); + +ruby_parenthesized_statements_def( + unique int id: @ruby_parenthesized_statements +); + +@ruby_pattern_child_type = @ruby_splat_argument | @ruby_underscore_arg + +ruby_pattern_def( + unique int id: @ruby_pattern, + int child: @ruby_pattern_child_type ref +); + +@ruby_program_child_type = @ruby_token_empty_statement | @ruby_token_uninterpreted | @ruby_underscore_statement + +#keyset[ruby_program, index] +ruby_program_child( + int ruby_program: @ruby_program ref, + int index: int ref, + unique int child: @ruby_program_child_type ref +); + +ruby_program_def( + unique int id: @ruby_program +); + +@ruby_range_begin_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_begin( + unique int ruby_range: @ruby_range ref, + unique int begin: @ruby_range_begin_type ref +); + +@ruby_range_end_type = @ruby_underscore_arg | @ruby_underscore_pattern_primitive + +ruby_range_end( + unique int ruby_range: @ruby_range ref, + unique int end: @ruby_range_end_type ref +); + +case @ruby_range.operator of + 0 = @ruby_range_dotdot +| 1 = @ruby_range_dotdotdot +; + + +ruby_range_def( + unique int id: @ruby_range, + int operator: int ref +); + +@ruby_rational_child_type = @ruby_token_float | @ruby_token_integer + +ruby_rational_def( + unique int id: @ruby_rational, + int child: @ruby_rational_child_type ref +); + +ruby_redo_child( + unique int ruby_redo: @ruby_redo ref, + unique int child: @ruby_argument_list ref +); + +ruby_redo_def( + unique int id: @ruby_redo +); + +@ruby_regex_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_regex, index] +ruby_regex_child( + int ruby_regex: @ruby_regex ref, + int index: int ref, + unique int child: @ruby_regex_child_type ref +); + +ruby_regex_def( + unique int id: @ruby_regex +); + +ruby_rescue_body( + unique int ruby_rescue: @ruby_rescue ref, + unique int body: @ruby_then ref +); + +ruby_rescue_exceptions( + unique int ruby_rescue: @ruby_rescue ref, + unique int exceptions: @ruby_exceptions ref +); + +ruby_rescue_variable( + unique int ruby_rescue: @ruby_rescue ref, + unique int variable: @ruby_exception_variable ref +); + +ruby_rescue_def( + unique int id: @ruby_rescue +); + +@ruby_rescue_modifier_body_type = @ruby_underscore_arg | @ruby_underscore_statement + +ruby_rescue_modifier_def( + unique int id: @ruby_rescue_modifier, + int body: @ruby_rescue_modifier_body_type ref, + int handler: @ruby_underscore_expression ref +); + +ruby_rest_assignment_child( + unique int ruby_rest_assignment: @ruby_rest_assignment ref, + unique int child: @ruby_underscore_lhs ref +); + +ruby_rest_assignment_def( + unique int id: @ruby_rest_assignment +); + +ruby_retry_child( + unique int ruby_retry: @ruby_retry ref, + unique int child: @ruby_argument_list ref +); + +ruby_retry_def( + unique int id: @ruby_retry +); + +ruby_return_child( + unique int ruby_return: @ruby_return ref, + unique int child: @ruby_argument_list ref +); + +ruby_return_def( + unique int id: @ruby_return +); + +@ruby_right_assignment_list_child_type = @ruby_splat_argument | @ruby_underscore_arg + +#keyset[ruby_right_assignment_list, index] +ruby_right_assignment_list_child( + int ruby_right_assignment_list: @ruby_right_assignment_list ref, + int index: int ref, + unique int child: @ruby_right_assignment_list_child_type ref +); + +ruby_right_assignment_list_def( + unique int id: @ruby_right_assignment_list +); + +@ruby_scope_resolution_scope_type = @ruby_underscore_pattern_constant | @ruby_underscore_primary + +ruby_scope_resolution_scope( + unique int ruby_scope_resolution: @ruby_scope_resolution ref, + unique int scope: @ruby_scope_resolution_scope_type ref +); + +ruby_scope_resolution_def( + unique int id: @ruby_scope_resolution, + int name: @ruby_token_constant ref +); + +ruby_setter_def( + unique int id: @ruby_setter, + int name: @ruby_token_identifier ref +); + +ruby_singleton_class_body( + unique int ruby_singleton_class: @ruby_singleton_class ref, + unique int body: @ruby_body_statement ref +); + +ruby_singleton_class_def( + unique int id: @ruby_singleton_class, + int value: @ruby_underscore_arg ref +); + +@ruby_singleton_method_body_type = @ruby_body_statement | @ruby_rescue_modifier | @ruby_underscore_arg + +ruby_singleton_method_body( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int body: @ruby_singleton_method_body_type ref +); + +@ruby_singleton_method_object_type = @ruby_underscore_arg | @ruby_underscore_variable + +ruby_singleton_method_parameters( + unique int ruby_singleton_method: @ruby_singleton_method ref, + unique int parameters: @ruby_method_parameters ref +); + +ruby_singleton_method_def( + unique int id: @ruby_singleton_method, + int name: @ruby_underscore_method_name ref, + int object: @ruby_singleton_method_object_type ref +); + +ruby_splat_argument_def( + unique int id: @ruby_splat_argument, + int child: @ruby_underscore_arg ref +); + +ruby_splat_parameter_name( + unique int ruby_splat_parameter: @ruby_splat_parameter ref, + unique int name: @ruby_token_identifier ref +); + +ruby_splat_parameter_def( + unique int id: @ruby_splat_parameter +); + +@ruby_string_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_string__, index] +ruby_string_child( + int ruby_string__: @ruby_string__ ref, + int index: int ref, + unique int child: @ruby_string_child_type ref +); + +ruby_string_def( + unique int id: @ruby_string__ +); + +#keyset[ruby_string_array, index] +ruby_string_array_child( + int ruby_string_array: @ruby_string_array ref, + int index: int ref, + unique int child: @ruby_bare_string ref +); + +ruby_string_array_def( + unique int id: @ruby_string_array +); + +@ruby_subshell_child_type = @ruby_interpolation | @ruby_token_escape_sequence | @ruby_token_string_content + +#keyset[ruby_subshell, index] +ruby_subshell_child( + int ruby_subshell: @ruby_subshell ref, + int index: int ref, + unique int child: @ruby_subshell_child_type ref +); + +ruby_subshell_def( + unique int id: @ruby_subshell +); + +ruby_superclass_def( + unique int id: @ruby_superclass, + int child: @ruby_underscore_expression ref +); + +#keyset[ruby_symbol_array, index] +ruby_symbol_array_child( + int ruby_symbol_array: @ruby_symbol_array ref, + int index: int ref, + unique int child: @ruby_bare_symbol ref +); + +ruby_symbol_array_def( + unique int id: @ruby_symbol_array +); + +@ruby_then_child_type = @ruby_token_empty_statement | @ruby_underscore_statement + +#keyset[ruby_then, index] +ruby_then_child( + int ruby_then: @ruby_then ref, + int index: int ref, + unique int child: @ruby_then_child_type ref +); + +ruby_then_def( + unique int id: @ruby_then +); + +@ruby_unary_operand_type = @ruby_parenthesized_statements | @ruby_underscore_expression | @ruby_underscore_simple_numeric + +case @ruby_unary.operator of + 0 = @ruby_unary_bang +| 1 = @ruby_unary_plus +| 2 = @ruby_unary_minus +| 3 = @ruby_unary_definedquestion +| 4 = @ruby_unary_not +| 5 = @ruby_unary_tilde +; + + +ruby_unary_def( + unique int id: @ruby_unary, + int operand: @ruby_unary_operand_type ref, + int operator: int ref +); + +#keyset[ruby_undef, index] +ruby_undef_child( + int ruby_undef: @ruby_undef ref, + int index: int ref, + unique int child: @ruby_underscore_method_name ref +); + +ruby_undef_def( + unique int id: @ruby_undef +); + +@ruby_unless_alternative_type = @ruby_else | @ruby_elsif + +ruby_unless_alternative( + unique int ruby_unless: @ruby_unless ref, + unique int alternative: @ruby_unless_alternative_type ref +); + +ruby_unless_consequence( + unique int ruby_unless: @ruby_unless ref, + unique int consequence: @ruby_then ref +); + +ruby_unless_def( + unique int id: @ruby_unless, + int condition: @ruby_underscore_statement ref +); + +ruby_unless_guard_def( + unique int id: @ruby_unless_guard, + int condition: @ruby_underscore_expression ref +); + +ruby_unless_modifier_def( + unique int id: @ruby_unless_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_until_def( + unique int id: @ruby_until, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_until_modifier_def( + unique int id: @ruby_until_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +@ruby_variable_reference_pattern_name_type = @ruby_token_identifier | @ruby_underscore_nonlocal_variable + +ruby_variable_reference_pattern_def( + unique int id: @ruby_variable_reference_pattern, + int name: @ruby_variable_reference_pattern_name_type ref +); + +ruby_when_body( + unique int ruby_when: @ruby_when ref, + unique int body: @ruby_then ref +); + +#keyset[ruby_when, index] +ruby_when_pattern( + int ruby_when: @ruby_when ref, + int index: int ref, + unique int pattern: @ruby_pattern ref +); + +ruby_when_def( + unique int id: @ruby_when +); + +ruby_while_def( + unique int id: @ruby_while, + int body: @ruby_do ref, + int condition: @ruby_underscore_statement ref +); + +ruby_while_modifier_def( + unique int id: @ruby_while_modifier, + int body: @ruby_underscore_statement ref, + int condition: @ruby_underscore_expression ref +); + +ruby_yield_child( + unique int ruby_yield: @ruby_yield ref, + unique int child: @ruby_argument_list ref +); + +ruby_yield_def( + unique int id: @ruby_yield +); + +ruby_tokeninfo( + unique int id: @ruby_token, + int kind: int ref, + string value: string ref +); + +case @ruby_token.kind of + 0 = @ruby_reserved_word +| 1 = @ruby_token_character +| 2 = @ruby_token_class_variable +| 3 = @ruby_token_comment +| 4 = @ruby_token_constant +| 5 = @ruby_token_empty_statement +| 6 = @ruby_token_encoding +| 7 = @ruby_token_escape_sequence +| 8 = @ruby_token_false +| 9 = @ruby_token_file +| 10 = @ruby_token_float +| 11 = @ruby_token_forward_argument +| 12 = @ruby_token_forward_parameter +| 13 = @ruby_token_global_variable +| 14 = @ruby_token_hash_key_symbol +| 15 = @ruby_token_hash_splat_nil +| 16 = @ruby_token_heredoc_beginning +| 17 = @ruby_token_heredoc_content +| 18 = @ruby_token_heredoc_end +| 19 = @ruby_token_identifier +| 20 = @ruby_token_instance_variable +| 21 = @ruby_token_integer +| 22 = @ruby_token_line +| 23 = @ruby_token_nil +| 24 = @ruby_token_operator +| 25 = @ruby_token_self +| 26 = @ruby_token_simple_symbol +| 27 = @ruby_token_string_content +| 28 = @ruby_token_super +| 29 = @ruby_token_true +| 30 = @ruby_token_uninterpreted +; + + +@ruby_ast_node = @ruby_alias | @ruby_alternative_pattern | @ruby_argument_list | @ruby_array | @ruby_array_pattern | @ruby_as_pattern | @ruby_assignment | @ruby_bare_string | @ruby_bare_symbol | @ruby_begin | @ruby_begin_block | @ruby_binary | @ruby_block | @ruby_block_argument | @ruby_block_body | @ruby_block_parameter | @ruby_block_parameters | @ruby_body_statement | @ruby_break | @ruby_call | @ruby_case__ | @ruby_case_match | @ruby_chained_string | @ruby_class | @ruby_complex | @ruby_conditional | @ruby_delimited_symbol | @ruby_destructured_left_assignment | @ruby_destructured_parameter | @ruby_do | @ruby_do_block | @ruby_element_reference | @ruby_else | @ruby_elsif | @ruby_end_block | @ruby_ensure | @ruby_exception_variable | @ruby_exceptions | @ruby_expression_reference_pattern | @ruby_find_pattern | @ruby_for | @ruby_hash | @ruby_hash_pattern | @ruby_hash_splat_argument | @ruby_hash_splat_parameter | @ruby_heredoc_body | @ruby_if | @ruby_if_guard | @ruby_if_modifier | @ruby_in | @ruby_in_clause | @ruby_interpolation | @ruby_keyword_parameter | @ruby_keyword_pattern | @ruby_lambda | @ruby_lambda_parameters | @ruby_left_assignment_list | @ruby_method | @ruby_method_parameters | @ruby_module | @ruby_next | @ruby_operator_assignment | @ruby_optional_parameter | @ruby_pair | @ruby_parenthesized_pattern | @ruby_parenthesized_statements | @ruby_pattern | @ruby_program | @ruby_range | @ruby_rational | @ruby_redo | @ruby_regex | @ruby_rescue | @ruby_rescue_modifier | @ruby_rest_assignment | @ruby_retry | @ruby_return | @ruby_right_assignment_list | @ruby_scope_resolution | @ruby_setter | @ruby_singleton_class | @ruby_singleton_method | @ruby_splat_argument | @ruby_splat_parameter | @ruby_string__ | @ruby_string_array | @ruby_subshell | @ruby_superclass | @ruby_symbol_array | @ruby_then | @ruby_token | @ruby_unary | @ruby_undef | @ruby_unless | @ruby_unless_guard | @ruby_unless_modifier | @ruby_until | @ruby_until_modifier | @ruby_variable_reference_pattern | @ruby_when | @ruby_while | @ruby_while_modifier | @ruby_yield + +@ruby_ast_node_parent = @file | @ruby_ast_node + +#keyset[parent, parent_index] +ruby_ast_node_info( + unique int node: @ruby_ast_node ref, + int parent: @ruby_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + +erb_comment_directive_child( + unique int erb_comment_directive: @erb_comment_directive ref, + unique int child: @erb_token_comment ref +); + +erb_comment_directive_def( + unique int id: @erb_comment_directive +); + +erb_directive_child( + unique int erb_directive: @erb_directive ref, + unique int child: @erb_token_code ref +); + +erb_directive_def( + unique int id: @erb_directive +); + +erb_graphql_directive_child( + unique int erb_graphql_directive: @erb_graphql_directive ref, + unique int child: @erb_token_code ref +); + +erb_graphql_directive_def( + unique int id: @erb_graphql_directive +); + +erb_output_directive_child( + unique int erb_output_directive: @erb_output_directive ref, + unique int child: @erb_token_code ref +); + +erb_output_directive_def( + unique int id: @erb_output_directive +); + +@erb_template_child_type = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_token_content + +#keyset[erb_template, index] +erb_template_child( + int erb_template: @erb_template ref, + int index: int ref, + unique int child: @erb_template_child_type ref +); + +erb_template_def( + unique int id: @erb_template +); + +erb_tokeninfo( + unique int id: @erb_token, + int kind: int ref, + string value: string ref +); + +case @erb_token.kind of + 0 = @erb_reserved_word +| 1 = @erb_token_code +| 2 = @erb_token_comment +| 3 = @erb_token_content +; + + +@erb_ast_node = @erb_comment_directive | @erb_directive | @erb_graphql_directive | @erb_output_directive | @erb_template | @erb_token + +@erb_ast_node_parent = @erb_ast_node | @file + +#keyset[parent, parent_index] +erb_ast_node_info( + unique int node: @erb_ast_node ref, + int parent: @erb_ast_node_parent ref, + int parent_index: int ref, + int loc: @location ref +); + diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_ast_node_info.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_ast_node_info.ql new file mode 100644 index 00000000000..abc6f7bf144 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_ast_node_info.ql @@ -0,0 +1,76 @@ +class AstNode extends @ruby_ast_node_parent { + string toString() { none() } +} + +class Location extends @location { + string toString() { none() } +} + +private predicate body_statement(AstNode body, AstNode firstChild) { + exists(AstNode node | + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, 0, firstChild) + or + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, 0, firstChild) + or + ruby_method_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, 0, firstChild) + or + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, 0, firstChild) + or + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, 0, firstChild) + or + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, 0, firstChild) + or + ruby_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(node, 0, firstChild) + ) +} + +private predicate body_statement_child(AstNode body, int index, AstNode child) { + exists(AstNode parent, AstNode firstChild, int firstChildIndex | + body_statement(body, firstChild) and + ruby_ast_node_info(firstChild, parent, firstChildIndex, _) and + child = + rank[index + 1](AstNode c, int i | + ruby_ast_node_info(c, parent, i, _) and i >= firstChildIndex and c != body + | + c order by i + ) + ) +} + +private predicate astNodeInfo(AstNode node, AstNode parent, int parent_index, Location loc) { + ruby_ast_node_info(node, parent, parent_index, loc) and + not body_statement(node, _) and + not body_statement_child(_, _, node) +} + +from AstNode node, AstNode parent, int parent_index, Location loc +where + astNodeInfo(node, parent, parent_index, loc) + or + body_statement_child(parent, parent_index, node) and ruby_ast_node_info(node, _, _, loc) + or + body_statement(node, _) and + ruby_ast_node_info(node, parent, _, loc) and + parent_index = count(AstNode n | astNodeInfo(n, parent, _, _)) +select node, parent, parent_index, loc diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body.ql new file mode 100644 index 00000000000..51d629755a8 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_block, AstNode body +where + ruby_block_def(ruby_block) and + ruby_ast_node_info(body, ruby_block, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(ruby_block, _, _) +select ruby_block, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_child.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_child.ql new file mode 100644 index 00000000000..d0743a7a340 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_child.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode ruby_block, AstNode body, int index, AstNode child +where + ruby_block_def(ruby_block) and + ruby_ast_node_info(body, ruby_block, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(ruby_block, index, child) +select body, index, child diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_def.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_def.ql new file mode 100644 index 00000000000..78204867e6f --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_block_body_def.ql @@ -0,0 +1,18 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +/* + * It's not possible to generate fresh IDs for the new ruby_block_body nodes, + * therefore we re-purpose the "}"-token that closes the block and use its ID instead. + * As a result the AST will be missing the "}" tokens, but those are unlikely to be used + * for anything. + */ + +from AstNode ruby_block, AstNode body +where + ruby_block_def(ruby_block) and + ruby_ast_node_info(body, ruby_block, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(ruby_block, _, _) +select body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_child.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_child.ql new file mode 100644 index 00000000000..682c124cb49 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_child.ql @@ -0,0 +1,36 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body, int index, AstNode child +where + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, index, child) + or + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, index, child) + or + ruby_method_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, index, child) + or + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, index, child) + or + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, index, child) + or + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, index, child) +select body, index, child diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_def.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_def.ql new file mode 100644 index 00000000000..603b5d13215 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_body_statement_def.ql @@ -0,0 +1,43 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +/* + * It's not possible to generate fresh IDs for the new ruby_body_statement nodes, + * therefore we re-purpose the "end"-token that closes the block and use its ID instead. + * As a result the AST will be missing the "end" tokens, but those are unlikely to be used + * for anything. + */ + +from AstNode node, AstNode body +where + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, _, _) + or + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, _, _) + or + ruby_method_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, _, _) + or + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, _, _) + or + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, _, _) + or + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, _, _) +select body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_class_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_class_body.ql new file mode 100644 index 00000000000..0a5a7acbc4d --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_class_body.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, _, _) +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_do_block_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_do_block_body.ql new file mode 100644 index 00000000000..dee41a91532 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_do_block_body.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, _, _) +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_method_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_method_body.ql new file mode 100644 index 00000000000..88889a382a4 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_method_body.ql @@ -0,0 +1,20 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_method_def(node, _) and + ( + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, _, _) + or + ruby_method_child(node, 0, body) and + not exists(AstNode n | + ruby_ast_node_info(n, node, _, _) and + ruby_tokeninfo(n, _, "end") + ) + ) +// TODO : handle end-less methods +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_module_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_module_body.ql new file mode 100644 index 00000000000..514dffc45fb --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_module_body.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, _, _) +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_class_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_class_body.ql new file mode 100644 index 00000000000..db90c1ded79 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_class_body.ql @@ -0,0 +1,11 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, _, _) +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_method_body.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_method_body.ql new file mode 100644 index 00000000000..9d714fad0b8 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_singleton_method_body.ql @@ -0,0 +1,17 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +from AstNode node, AstNode body +where + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, _, _) + or + ruby_singleton_method_child(node, 0, body) and + not exists(AstNode n | + ruby_ast_node_info(n, node, _, _) and + ruby_tokeninfo(n, _, "end") + ) +select node, body diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_tokeninfo.ql b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_tokeninfo.ql new file mode 100644 index 00000000000..358445c4204 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/ruby_tokeninfo.ql @@ -0,0 +1,46 @@ +class AstNode extends @ruby_ast_node { + string toString() { none() } +} + +private predicate body_statement(AstNode body) { + exists(AstNode node | + ruby_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_class_child(node, _, _) + or + ruby_do_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_do_block_child(node, _, _) + or + ruby_method_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_method_child(node, _, _) + or + ruby_module_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_module_child(node, _, _) + or + ruby_singleton_class_def(node, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_class_child(node, _, _) + or + ruby_singleton_method_def(node, _, _) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "end") and + ruby_singleton_method_child(node, _, _) + or + ruby_block_def(node) and + ruby_ast_node_info(body, node, _, _) and + ruby_tokeninfo(body, _, "}") and + ruby_block_child(node, _, _) + ) +} + +from AstNode token, int kind, string value +where ruby_tokeninfo(token, kind, value) and not body_statement(token) +select token, kind, value diff --git a/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/upgrade.properties b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/upgrade.properties new file mode 100644 index 00000000000..6793ae3c109 --- /dev/null +++ b/ruby/ql/lib/upgrades/4ba51641799d2aaa315c7323931e2dd2a94c9f9d/upgrade.properties @@ -0,0 +1,33 @@ +description: Wrap class, module, method, and block bodies in a named node +compatibility: partial + +ruby_block_body.rel: run ruby_block_body.qlo +ruby_block_body_def.rel: run ruby_block_body_def.qlo +ruby_block_body_child.rel: run ruby_block_body_child.qlo +ruby_block_child.rel: delete + +ruby_body_statement_child.rel: run ruby_body_statement_child.qlo +ruby_body_statement_def.rel: run ruby_body_statement_def.qlo + +ruby_class_body.rel: run ruby_class_body.qlo +ruby_class_child.rel: delete + +ruby_do_block_body.rel: run ruby_do_block_body.qlo +ruby_do_block_child.rel: delete + +ruby_method_body.rel: run ruby_method_body.qlo +ruby_method_child.rel: delete + +ruby_module_body.rel: run ruby_module_body.qlo +ruby_module_child.rel: delete + +ruby_singleton_class_body.rel: run ruby_singleton_class_body.qlo +ruby_singleton_class_child.rel: delete + +ruby_singleton_method_body.rel: run ruby_singleton_method_body.qlo +ruby_singleton_method_child.rel: delete + +ruby_ast_node_info.rel: run ruby_ast_node_info.qlo +ruby_tokeninfo.rel: run ruby_tokeninfo.qlo + +locations_default.rel: run locations_default.qlo \ No newline at end of file From f77c2ac3d0ec45c56b6f18034a1863dc966f26de Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Tue, 2 Aug 2022 16:54:52 +0200 Subject: [PATCH 022/203] Update tests --- ruby/ql/test/library-tests/ast/Ast.expected | 19 ++++++++++----- .../library-tests/ast/TreeSitter.expected | 23 ++++++++++++------- .../test/library-tests/ast/ValueText.expected | 2 ++ .../ast/literals/literals.expected | 21 ++++++++++++----- .../library-tests/ast/literals/literals.rb | 4 +++- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index 4cb29e0f033..33229c64393 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -2260,12 +2260,8 @@ literals/literals.rb: # 189| getAnOperand/getLeftOperand: [LocalVariableAccess] query # 189| getAnOperand/getRightOperand: [HereDoc] <<'DOC' # 189| getComponent: [StringTextComponent] -# 189| text without -# 190| getComponent: [StringInterpolationComponent] #{...} -# 190| getStmt: [MethodCall] call to interpolation -# 190| getReceiver: [SelfVariableAccess] self -# 190| getComponent: [StringTextComponent] ! -# 190| +# 189| text without #{ interpolation } ! +# 189| # 193| getStmt: [AssignExpr] ... = ... # 193| getAnOperand/getLeftOperand: [LocalVariableAccess] output # 193| getAnOperand/getRightOperand: [HereDoc] <<`SCRIPT` @@ -2293,6 +2289,17 @@ literals/literals.rb: # 199| getKey: [SymbolLiteral] :Z # 199| getComponent: [StringTextComponent] Z # 199| getValue: [ConstantReadAccess] Z +# 201| getStmt: [StringLiteral] "@foo: #{...} @@bar: #{...} $_..." +# 201| getComponent: [StringTextComponent] @foo: +# 201| getComponent: [StringInterpolationComponent] #{...} +# 201| getStmt: [InstanceVariableAccess] @foo +# 201| getReceiver: [SelfVariableAccess] self +# 201| getComponent: [StringTextComponent] @@bar: +# 201| getComponent: [StringInterpolationComponent] #{...} +# 201| getStmt: [ClassVariableAccess] @@bar +# 201| getComponent: [StringTextComponent] $_: +# 201| getComponent: [StringInterpolationComponent] #{...} +# 201| getStmt: [GlobalVariableAccess] $_ control/loops.rb: # 1| [Toplevel] loops.rb # 2| getStmt: [AssignExpr] ... = ... diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index bca7b42046c..839ad55fb38 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -4539,6 +4539,18 @@ literals/literals.rb: # 199| 0: [HashKeySymbol] Z # 199| 1: [ReservedWord] : # 199| 4: [ReservedWord] } +# 201| 135: [String] String +# 201| 0: [ReservedWord] " +# 201| 1: [StringContent] @foo: +# 201| 2: [Interpolation] Interpolation +# 201| 0: [InstanceVariable] @foo +# 201| 3: [StringContent] @@bar: +# 201| 4: [Interpolation] Interpolation +# 201| 0: [ClassVariable] @@bar +# 201| 5: [StringContent] $_: +# 201| 6: [Interpolation] Interpolation +# 201| 0: [GlobalVariable] $_ +# 201| 7: [ReservedWord] " # 1| [Comment] # boolean values and nil # 9| [Comment] # decimal integers # 14| [Comment] # max value representable by QL's int type @@ -4640,14 +4652,9 @@ literals/literals.rb: # 188| [Comment] # TODO: the parser currently does not handle single quoted heredocs correctly # 189| [HeredocBody] HeredocBody # 189| 0: [HeredocContent] -# 189| text without -# 190| 1: [Interpolation] Interpolation -# 190| 0: [ReservedWord] #{ -# 190| 1: [Identifier] interpolation -# 190| 2: [ReservedWord] } -# 190| 2: [HeredocContent] ! -# 190| -# 191| 3: [HeredocEnd] DOC +# 189| text without #{ interpolation } ! +# 189| +# 191| 1: [HeredocEnd] DOC # 193| [HeredocBody] HeredocBody # 193| 0: [HeredocContent] # 193| cat file.txt diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index e66838fbe2c..1492d619e33 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -709,6 +709,7 @@ exprValue | literals/literals.rb:168:9:168:13 | < | -| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | | +| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | \n text without #{ interpolation } !\n | | literals.rb:193:10:193:19 | <<`SCRIPT` | HereDoc | \n cat file.txt\n | | literals.rb:197:5:197:6 | 42 | IntegerLiteral | 42 | | literals.rb:198:1:198:9 | {...} | HashLiteral | | @@ -237,6 +237,7 @@ allLiterals | literals.rb:199:1:199:9 | {...} | HashLiteral | | | literals.rb:199:2:199:2 | :y | SymbolLiteral | :y | | literals.rb:199:7:199:7 | :Z | SymbolLiteral | :Z | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | | stringlikeLiterals | literals.rb:59:1:59:2 | "" | | | literals.rb:60:1:60:2 | "" | | @@ -345,12 +346,13 @@ stringlikeLiterals | literals.rb:175:11:175:16 | <<-BLA | \nsome text\nand some more\n | | literals.rb:180:9:180:19 | <<~SQUIGGLY | \n indented stuff\n | | literals.rb:184:9:184:15 | <<"DOC" | | -| literals.rb:189:9:189:15 | <<'DOC' | | +| literals.rb:189:9:189:15 | <<'DOC' | \n text without #{ interpolation } !\n | | literals.rb:193:10:193:19 | <<`SCRIPT` | \n cat file.txt\n | | literals.rb:198:2:198:2 | :x | :x | | literals.rb:198:6:198:6 | :y | :y | | literals.rb:199:2:199:2 | :y | :y | | literals.rb:199:7:199:7 | :Z | :Z | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | | stringLiterals | literals.rb:59:1:59:2 | "" | | | literals.rb:60:1:60:2 | "" | | @@ -405,6 +407,7 @@ stringLiterals | literals.rb:163:1:163:34 | "abcdefghijklmnopqrstuvwxyzabcdef" | abcdefghijklmnopqrstuvwxyzabcdef | | literals.rb:164:1:164:35 | "foobarfoobarfoobarfoobarfooba..." | foobarfoobarfoobarfoobarfoobarfoo | | literals.rb:165:1:165:40 | "foobar\\\\foobar\\\\foobar\\\\fooba..." | foobar\\foobar\\foobar\\foobar\\foobar | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | | regExpLiterals | literals.rb:149:1:149:2 | // | | | | literals.rb:150:1:150:5 | /foo/ | foo | | @@ -626,14 +629,18 @@ stringComponents | literals.rb:184:9:184:15 | <<"DOC" | HereDoc | 0 | literals.rb:184:16:185:11 | \n text with | StringTextComponent | | literals.rb:184:9:184:15 | <<"DOC" | HereDoc | 1 | literals.rb:185:12:185:29 | #{...} | StringInterpolationComponent | | literals.rb:184:9:184:15 | <<"DOC" | HereDoc | 2 | literals.rb:185:30:185:32 | !\n | StringTextComponent | -| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | 0 | literals.rb:189:16:190:14 | \n text without | StringTextComponent | -| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | 1 | literals.rb:190:15:190:32 | #{...} | StringInterpolationComponent | -| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | 2 | literals.rb:190:33:190:35 | !\n | StringTextComponent | +| literals.rb:189:9:189:15 | <<'DOC' | HereDoc | 0 | literals.rb:189:16:190:35 | \n text without #{ interpolation } !\n | StringTextComponent | | literals.rb:193:10:193:19 | <<`SCRIPT` | HereDoc | 0 | literals.rb:193:20:194:14 | \n cat file.txt\n | StringTextComponent | | literals.rb:198:2:198:2 | :x | SymbolLiteral | 0 | literals.rb:198:2:198:2 | x | StringTextComponent | | literals.rb:198:6:198:6 | :y | SymbolLiteral | 0 | literals.rb:198:6:198:6 | y | StringTextComponent | | literals.rb:199:2:199:2 | :y | SymbolLiteral | 0 | literals.rb:199:2:199:2 | y | StringTextComponent | | literals.rb:199:7:199:7 | :Z | SymbolLiteral | 0 | literals.rb:199:7:199:7 | Z | StringTextComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 0 | literals.rb:201:2:201:7 | @foo: | StringTextComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 1 | literals.rb:201:8:201:12 | #{...} | StringInterpolationComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 2 | literals.rb:201:13:201:20 | @@bar: | StringTextComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 3 | literals.rb:201:21:201:26 | #{...} | StringInterpolationComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 4 | literals.rb:201:27:201:31 | $_: | StringTextComponent | +| literals.rb:201:1:201:35 | "@foo: #{...} @@bar: #{...} $_..." | StringLiteral | 5 | literals.rb:201:32:201:34 | #{...} | StringInterpolationComponent | stringInterpolations | literals.rb:71:10:71:19 | #{...} | 0 | literals.rb:71:13:71:17 | ... + ... | AddExpr | | literals.rb:72:12:72:21 | #{...} | 0 | literals.rb:72:15:72:19 | ... + ... | AddExpr | @@ -659,7 +666,9 @@ stringInterpolations | literals.rb:146:10:146:19 | #{...} | 0 | literals.rb:146:13:146:17 | ... - ... | SubExpr | | literals.rb:171:14:171:22 | #{...} | 0 | literals.rb:171:17:171:20 | call to name | MethodCall | | literals.rb:185:12:185:29 | #{...} | 0 | literals.rb:185:15:185:27 | call to interpolation | MethodCall | -| literals.rb:190:15:190:32 | #{...} | 0 | literals.rb:190:18:190:30 | call to interpolation | MethodCall | +| literals.rb:201:8:201:12 | #{...} | 0 | literals.rb:201:9:201:12 | @foo | InstanceVariableAccess | +| literals.rb:201:21:201:26 | #{...} | 0 | literals.rb:201:22:201:26 | @@bar | ClassVariableAccess | +| literals.rb:201:32:201:34 | #{...} | 0 | literals.rb:201:33:201:34 | $_ | GlobalVariableAccess | concatenatedStrings | literals.rb:75:1:75:17 | "..." "..." | foobarbaz | 0 | literals.rb:75:1:75:5 | "foo" | | literals.rb:75:1:75:17 | "..." "..." | foobarbaz | 1 | literals.rb:75:7:75:11 | "bar" | diff --git a/ruby/ql/test/library-tests/ast/literals/literals.rb b/ruby/ql/test/library-tests/ast/literals/literals.rb index 6ddfc74e88f..e3f13c6bfea 100644 --- a/ruby/ql/test/library-tests/ast/literals/literals.rb +++ b/ruby/ql/test/library-tests/ast/literals/literals.rb @@ -196,4 +196,6 @@ SCRIPT x = 42 {x:, y:5} -{y: , Z:} \ No newline at end of file +{y: , Z:} + +"@foo: #@foo @@bar: #@@bar $_: #$_" \ No newline at end of file From 24526108d35a5a1db0b15954c80859bef8cd2a17 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Thu, 25 Aug 2022 17:48:28 +0200 Subject: [PATCH 023/203] Ruby: update dbscheme stats --- ruby/ql/lib/ruby.dbscheme.stats | 8439 ++++++++++++++----------------- 1 file changed, 3765 insertions(+), 4674 deletions(-) diff --git a/ruby/ql/lib/ruby.dbscheme.stats b/ruby/ql/lib/ruby.dbscheme.stats index 782ae4db56b..4a594923a20 100644 --- a/ruby/ql/lib/ruby.dbscheme.stats +++ b/ruby/ql/lib/ruby.dbscheme.stats @@ -5,7 +5,7 @@ @diagnostic_error - 155 + 130 @diagnostic_info @@ -21,7 +21,7 @@ @erb_directive - 1414 + 1400 @erb_graphql_directive @@ -29,19 +29,19 @@ @erb_output_directive - 3806 + 3859 @erb_reserved_word - 10441 + 10520 @erb_template - 1563 + 1540 @erb_token_code - 5220 + 5260 @erb_token_comment @@ -49,23 +49,23 @@ @erb_token_content - 3761 + 5478 @file - 17168 + 17206 @folder - 4792 + 4799 @location_default - 8508604 + 8706731 - + @ruby_alias - 1244 + 1264 @ruby_alternative_pattern @@ -73,11 +73,11 @@ @ruby_argument_list - 664517 + 670202 @ruby_array - 245561 + 246221 @ruby_array_pattern @@ -89,19 +89,19 @@ @ruby_assignment - 130246 + 131940 @ruby_bare_string - 11487 + 11622 @ruby_bare_symbol - 2106 + 2085 @ruby_begin - 2523 + 2549 @ruby_begin_block @@ -109,87 +109,87 @@ @ruby_binary_ampersand - 474 + 491 @ruby_binary_ampersandampersand - 8700 + 8705 @ruby_binary_and - 1348 + 1182 @ruby_binary_bangequal - 1586 + 1584 @ruby_binary_bangtilde - 178 + 177 @ruby_binary_caret - 155 + 157 @ruby_binary_equalequal - 31159 + 31539 @ruby_binary_equalequalequal - 603 + 631 @ruby_binary_equaltilde - 1820 + 1804 @ruby_binary_langle - 1334 + 1327 @ruby_binary_langleequal - 368 + 377 @ruby_binary_langleequalrangle - 749 + 758 @ruby_binary_langlelangle - 10368 + 10536 @ruby_binary_minus - 2381 + 2409 @ruby_binary_or - 665 + 622 @ruby_binary_percent - 1009 + 1017 @ruby_binary_pipe - 968 + 969 @ruby_binary_pipepipe - 8001 + 7935 @ruby_binary_plus - 6116 + 6173 @ruby_binary_rangle - 2400 + 2374 @ruby_binary_rangleequal - 558 + 575 @ruby_binary_ranglerangle @@ -197,43 +197,51 @@ @ruby_binary_slash - 1248 + 1257 @ruby_binary_star - 3286 + 3328 @ruby_binary_starstar - 1316 + 1332 @ruby_block - 97359 + 98296 @ruby_block_argument - 6050 + 6115 + + + @ruby_block_body + 97983 @ruby_block_parameter - 2410 + 2442 @ruby_block_parameters - 23336 + 23772 + + + @ruby_body_statement + 201560 @ruby_break - 3338 + 3355 @ruby_call - 965401 + 974897 @ruby_case__ - 1219 + 1224 @ruby_case_match @@ -241,11 +249,11 @@ @ruby_chained_string - 885 + 877 @ruby_class - 16841 + 16946 @ruby_complex @@ -253,11 +261,11 @@ @ruby_conditional - 3464 + 3495 @ruby_delimited_symbol - 1257 + 1264 @ruby_destructured_left_assignment @@ -269,23 +277,23 @@ @ruby_do - 1610 + 1632 @ruby_do_block - 137435 + 138119 @ruby_element_reference - 82234 + 82869 @ruby_else - 6933 + 7138 @ruby_elsif - 1595 + 1578 @ruby_end_block @@ -293,15 +301,15 @@ @ruby_ensure - 3718 + 3803 @ruby_exception_variable - 1001 + 991 @ruby_exceptions - 1639 + 1654 @ruby_expression_reference_pattern @@ -317,7 +325,7 @@ @ruby_hash - 39413 + 39640 @ruby_hash_pattern @@ -325,19 +333,19 @@ @ruby_hash_splat_argument - 1856 + 1857 @ruby_hash_splat_parameter - 1355 + 1447 @ruby_heredoc_body - 5575 + 5789 @ruby_if - 18392 + 18341 @ruby_if_guard @@ -345,7 +353,7 @@ @ruby_if_modifier - 13620 + 13708 @ruby_in @@ -357,11 +365,11 @@ @ruby_interpolation - 38208 + 38051 @ruby_keyword_parameter - 3794 + 3939 @ruby_keyword_pattern @@ -369,31 +377,31 @@ @ruby_lambda - 7472 + 7557 @ruby_lambda_parameters - 1664 + 1665 @ruby_left_assignment_list - 2873 + 2910 @ruby_method - 98356 + 99525 @ruby_method_parameters - 28861 + 29417 @ruby_module - 21557 + 21589 @ruby_next - 2005 + 2021 @ruby_operator_assignment_ampersandampersandequal @@ -401,7 +409,7 @@ @ruby_operator_assignment_ampersandequal - 16 + 17 @ruby_operator_assignment_caretequal @@ -413,23 +421,23 @@ @ruby_operator_assignment_minusequal - 292 + 294 @ruby_operator_assignment_percentequal - 25 + 26 @ruby_operator_assignment_pipeequal - 138 + 142 @ruby_operator_assignment_pipepipeequal - 4611 + 4545 @ruby_operator_assignment_plusequal - 1759 + 1732 @ruby_operator_assignment_ranglerangleequal @@ -437,11 +445,11 @@ @ruby_operator_assignment_slashequal - 12 + 13 @ruby_operator_assignment_starequal - 49 + 50 @ruby_operator_assignment_starstarequal @@ -449,11 +457,11 @@ @ruby_optional_parameter - 6435 + 6540 @ruby_pair - 235158 + 237637 @ruby_parenthesized_pattern @@ -461,27 +469,27 @@ @ruby_parenthesized_statements - 10247 + 10510 @ruby_pattern - 3895 + 3918 @ruby_program - 17142 + 17193 @ruby_range_dotdot - 2831 + 2976 @ruby_range_dotdotdot - 1356 + 1459 @ruby_rational - 123 + 124 @ruby_redo @@ -489,99 +497,99 @@ @ruby_regex - 12854 + 13096 @ruby_rescue - 2061 + 2085 @ruby_rescue_modifier - 525 + 519 @ruby_reserved_word - 3667249 + 3700878 @ruby_rest_assignment - 398 + 399 @ruby_retry - 56 + 59 @ruby_return - 8495 + 8486 @ruby_right_assignment_list - 1288 + 1274 @ruby_scope_resolution - 80009 + 81024 @ruby_setter - 598 + 601 @ruby_singleton_class - 620 + 635 @ruby_singleton_method - 6539 + 6692 @ruby_splat_argument - 3046 + 3093 @ruby_splat_parameter - 2905 + 2978 @ruby_string__ - 473533 + 476418 @ruby_string_array - 3840 + 3913 @ruby_subshell - 403 + 393 @ruby_superclass - 13318 + 13378 @ruby_symbol_array - 463 + 460 @ruby_then - 24329 + 24194 @ruby_token_character - 437 + 439 @ruby_token_class_variable - 857 + 858 @ruby_token_comment - 180978 + 182145 @ruby_token_constant - 283898 + 285989 @ruby_token_empty_statement @@ -593,11 +601,11 @@ @ruby_token_escape_sequence - 75715 + 76101 @ruby_token_false - 16909 + 17332 @ruby_token_file @@ -605,23 +613,23 @@ @ruby_token_float - 7830 + 7894 @ruby_token_forward_argument - 72 + 71 @ruby_token_forward_parameter - 94 + 111 @ruby_token_global_variable - 7057 + 7235 @ruby_token_hash_key_symbol - 228509 + 231030 @ruby_token_hash_splat_nil @@ -629,27 +637,27 @@ @ruby_token_heredoc_beginning - 5600 + 5789 @ruby_token_heredoc_content - 12542 + 12722 @ruby_token_heredoc_end - 5575 + 5789 @ruby_token_identifier - 1483080 + 1498233 @ruby_token_instance_variable - 81049 + 84088 @ruby_token_integer - 298658 + 300415 @ruby_token_line @@ -657,31 +665,31 @@ @ruby_token_nil - 17920 + 18114 @ruby_token_operator - 781 + 803 @ruby_token_self - 12958 + 13236 @ruby_token_simple_symbol - 249119 + 252789 @ruby_token_string_content - 488016 + 491238 @ruby_token_super - 5058 + 5049 @ruby_token_true - 23298 + 23791 @ruby_token_uninterpreted @@ -689,35 +697,35 @@ @ruby_unary_bang - 5788 + 5826 @ruby_unary_definedquestion - 1312 + 1320 @ruby_unary_minus - 9122 + 9472 @ruby_unary_not - 236 + 190 @ruby_unary_plus - 1386 + 1416 @ruby_unary_tilde - 88 + 89 @ruby_undef - 180 + 181 @ruby_unless - 2578 + 2594 @ruby_unless_guard @@ -725,15 +733,15 @@ @ruby_unless_modifier - 4207 + 4163 @ruby_until - 113 + 121 @ruby_until_modifier - 206 + 223 @ruby_variable_reference_pattern @@ -741,32 +749,32 @@ @ruby_when - 3239 + 3248 @ruby_while - 1335 + 1349 @ruby_while_modifier - 179 + 190 @ruby_yield - 2385 + 2389 containerparent - 21934 + 21979 parent - 4792 + 4799 child - 21934 + 21979 @@ -780,37 +788,37 @@ 1 2 - 2142 + 2145 2 3 - 909 + 910 3 4 - 441 + 442 4 5 - 298 + 299 5 7 - 376 + 377 7 13 - 389 + 390 13 124 - 233 + 234 @@ -826,7 +834,7 @@ 1 2 - 21934 + 21979 @@ -836,31 +844,31 @@ diagnostics - 155 + 130 id - 155 + 130 severity - 12 + 13 error_tag - 12 + 13 error_message - 25 + 26 full_error_message - 129 + 104 location - 155 + 130 @@ -874,7 +882,7 @@ 1 2 - 155 + 130 @@ -890,7 +898,7 @@ 1 2 - 155 + 130 @@ -906,7 +914,7 @@ 1 2 - 155 + 130 @@ -922,7 +930,7 @@ 1 2 - 155 + 130 @@ -938,7 +946,7 @@ 1 2 - 155 + 130 @@ -952,9 +960,9 @@ 12 - 12 - 13 - 12 + 10 + 11 + 13 @@ -970,7 +978,7 @@ 1 2 - 12 + 13 @@ -986,7 +994,7 @@ 2 3 - 12 + 13 @@ -1000,9 +1008,9 @@ 12 - 10 - 11 - 12 + 8 + 9 + 13 @@ -1016,9 +1024,9 @@ 12 - 12 - 13 - 12 + 10 + 11 + 13 @@ -1032,9 +1040,9 @@ 12 - 12 - 13 - 12 + 10 + 11 + 13 @@ -1050,7 +1058,7 @@ 1 2 - 12 + 13 @@ -1066,7 +1074,7 @@ 2 3 - 12 + 13 @@ -1080,9 +1088,9 @@ 12 - 10 - 11 - 12 + 8 + 9 + 13 @@ -1096,9 +1104,9 @@ 12 - 12 - 13 - 12 + 10 + 11 + 13 @@ -1114,65 +1122,65 @@ 1 2 - 12 - - - 11 - 12 - 12 - - - - - - - error_message - severity - - - 12 - - - 1 - 2 - 25 - - - - - - - error_message - error_tag - - - 12 - - - 1 - 2 - 25 - - - - - - - error_message - full_error_message - - - 12 - - - 1 - 2 - 12 + 13 9 10 - 12 + 13 + + + + + + + error_message + severity + + + 12 + + + 1 + 2 + 26 + + + + + + + error_message + error_tag + + + 12 + + + 1 + 2 + 26 + + + + + + + error_message + full_error_message + + + 12 + + + 1 + 2 + 13 + + + 7 + 8 + 13 @@ -1188,12 +1196,12 @@ 1 2 - 12 + 13 - 11 - 12 - 12 + 9 + 10 + 13 @@ -1209,12 +1217,12 @@ 1 2 - 103 + 78 2 3 - 25 + 26 @@ -1230,7 +1238,7 @@ 1 2 - 129 + 104 @@ -1246,7 +1254,7 @@ 1 2 - 129 + 104 @@ -1262,7 +1270,7 @@ 1 2 - 129 + 104 @@ -1278,12 +1286,12 @@ 1 2 - 103 + 78 2 3 - 25 + 26 @@ -1299,7 +1307,7 @@ 1 2 - 155 + 130 @@ -1315,7 +1323,7 @@ 1 2 - 155 + 130 @@ -1331,7 +1339,7 @@ 1 2 - 155 + 130 @@ -1347,7 +1355,7 @@ 1 2 - 155 + 130 @@ -1363,7 +1371,7 @@ 1 2 - 155 + 130 @@ -1373,23 +1381,23 @@ erb_ast_node_info - 25078 + 26945 node - 25078 + 26945 parent - 6088 + 6111 parent_index - 668 + 688 loc - 25075 + 26942 @@ -1403,7 +1411,7 @@ 1 2 - 25078 + 26945 @@ -1419,7 +1427,7 @@ 1 2 - 25078 + 26945 @@ -1435,7 +1443,7 @@ 1 2 - 25078 + 26945 @@ -1451,17 +1459,17 @@ 1 3 - 460 + 446 3 4 - 5360 + 5403 4 - 226 - 267 + 237 + 262 @@ -1477,17 +1485,17 @@ 1 3 - 460 + 446 3 4 - 5360 + 5403 4 - 226 - 267 + 237 + 262 @@ -1503,17 +1511,17 @@ 1 3 - 460 + 446 3 4 - 5360 + 5403 4 - 226 - 267 + 237 + 262 @@ -1529,57 +1537,62 @@ 1 2 - 86 + 2 2 3 - 106 + 134 3 4 - 121 + 43 4 5 - 5 + 75 5 6 - 65 + 61 6 7 - 50 + 70 7 - 11 - 50 + 9 + 61 - 11 - 19 - 53 + 10 + 16 + 55 - 19 - 38 - 53 + 16 + 23 + 52 - 39 - 72 - 50 + 23 + 43 + 52 - 74 - 2050 - 23 + 45 + 71 + 52 + + + 73 + 2096 + 26 @@ -1595,57 +1608,62 @@ 1 2 - 86 + 2 2 3 - 106 + 134 3 4 - 121 + 43 4 5 - 5 + 75 5 6 - 65 + 61 6 7 - 50 + 70 7 - 11 - 50 + 9 + 61 - 11 - 19 - 53 + 10 + 16 + 55 - 19 - 38 - 53 + 16 + 23 + 52 - 39 - 72 - 50 + 23 + 43 + 52 - 74 - 2050 - 23 + 45 + 71 + 52 + + + 73 + 2096 + 26 @@ -1661,57 +1679,62 @@ 1 2 - 86 + 2 2 3 - 106 + 134 3 4 - 121 + 43 4 5 - 5 + 75 5 6 - 65 + 61 6 7 - 50 + 70 7 - 11 - 50 + 9 + 61 - 11 - 19 - 53 + 10 + 16 + 55 - 19 - 38 - 53 + 16 + 23 + 52 - 39 - 72 - 50 + 23 + 43 + 52 - 74 - 2049 - 23 + 45 + 71 + 52 + + + 73 + 2095 + 26 @@ -1727,7 +1750,7 @@ 1 2 - 25072 + 26939 2 @@ -1748,7 +1771,7 @@ 1 2 - 25072 + 26939 2 @@ -1769,7 +1792,7 @@ 1 2 - 25075 + 26942 @@ -1778,11 +1801,11 @@ - erb_comment_directive_def + erb_comment_directive_child 40 - id + erb_comment_directive 40 @@ -1792,7 +1815,7 @@ - id + erb_comment_directive child @@ -1809,7 +1832,7 @@ child - id + erb_comment_directive 12 @@ -1826,21 +1849,32 @@ - erb_directive_def - 1414 + erb_comment_directive_def + 40 id - 1414 + 40 + + + + + + erb_directive_child + 1400 + + + erb_directive + 1400 child - 1414 + 1400 - id + erb_directive child @@ -1849,7 +1883,7 @@ 1 2 - 1414 + 1400 @@ -1857,7 +1891,7 @@ child - id + erb_directive 12 @@ -1865,7 +1899,66 @@ 1 2 - 1414 + 1400 + + + + + + + + + erb_directive_def + 1400 + + + id + 1400 + + + + + + erb_graphql_directive_child + 0 + + + erb_graphql_directive + 0 + + + child + 0 + + + + + erb_graphql_directive + child + + + 12 + + + 1 + 2 + 2 + + + + + + + child + erb_graphql_directive + + + 12 + + + 1 + 2 + 2 @@ -1881,14 +1974,291 @@ id 0 + + + + + erb_output_directive_child + 3859 + + + erb_output_directive + 3859 + child - 0 + 3859 - id + erb_output_directive + child + + + 12 + + + 1 + 2 + 3859 + + + + + + + child + erb_output_directive + + + 12 + + + 1 + 2 + 3859 + + + + + + + + + erb_output_directive_def + 3859 + + + id + 3859 + + + + + + erb_template_child + 10739 + + + erb_template + 425 + + + index + 688 + + + child + 10739 + + + + + erb_template + index + + + 12 + + + 1 + 3 + 20 + + + 3 + 4 + 142 + + + 4 + 7 + 26 + + + 7 + 10 + 32 + + + 10 + 14 + 32 + + + 14 + 24 + 32 + + + 24 + 32 + 35 + + + 33 + 42 + 35 + + + 43 + 68 + 32 + + + 70 + 190 + 32 + + + 235 + 237 + 5 + + + + + + + erb_template + child + + + 12 + + + 1 + 3 + 20 + + + 3 + 4 + 142 + + + 4 + 7 + 26 + + + 7 + 10 + 32 + + + 10 + 14 + 32 + + + 14 + 24 + 32 + + + 24 + 32 + 35 + + + 33 + 42 + 35 + + + 43 + 68 + 32 + + + 70 + 190 + 32 + + + 235 + 237 + 5 + + + + + + + index + erb_template + + + 12 + + + 1 + 2 + 2 + + + 2 + 3 + 134 + + + 3 + 4 + 43 + + + 4 + 5 + 75 + + + 5 + 6 + 61 + + + 6 + 7 + 70 + + + 7 + 9 + 61 + + + 10 + 16 + 55 + + + 16 + 23 + 52 + + + 23 + 43 + 52 + + + 45 + 71 + 52 + + + 73 + 147 + 26 + + + + + + + index child @@ -1899,337 +2269,60 @@ 2 2 - - - - - - child - id - - - 12 - - - - - - - - erb_output_directive_def - 3806 - - - id - 3806 - - - child - 3806 - - - - - id - child - - - 12 - - - 1 - 2 - 3806 - - - - - - - child - id - - - 12 - - - 1 - 2 - 3806 - - - - - - - - - erb_template_child - 8982 - - - erb_template - 433 - - - index - 668 - - - child - 8982 - - - - - erb_template - index - - - 12 - - - 1 - 3 - 26 - - - 3 - 4 - 139 - - - 4 - 7 - 26 - - - 7 - 9 - 29 - - - 9 - 12 - 35 - - - 12 - 17 - 38 - - - 17 - 29 - 32 - - - 29 - 35 - 35 - - - 35 - 56 - 35 - - - 61 - 226 - 32 - - - - - - - erb_template - child - - - 12 - - - 1 - 3 - 26 - - - 3 - 4 - 139 - - - 4 - 7 - 26 - - - 7 - 9 - 29 - - - 9 - 12 - 35 - - - 12 - 17 - 38 - - - 17 - 29 - 32 - - - 29 - 35 - 35 - - - 35 - 56 - 35 - - - 61 - 226 - 32 - - - - - - - index - erb_template - - - 12 - - - 1 - 2 - 86 - 2 3 - 106 + 134 3 4 - 121 + 43 4 5 - 5 + 75 5 6 - 65 + 61 6 7 - 50 + 70 7 - 11 - 50 + 9 + 61 - 11 - 19 - 53 + 10 + 16 + 55 - 19 - 38 - 53 + 16 + 23 + 52 - 39 - 72 - 50 + 23 + 43 + 52 - 74 + 45 + 71 + 52 + + + 73 147 - 23 - - - - - - - index - child - - - 12 - - - 1 - 2 - 86 - - - 2 - 3 - 106 - - - 3 - 4 - 121 - - - 4 - 5 - 5 - - - 5 - 6 - 65 - - - 6 - 7 - 50 - - - 7 - 11 - 50 - - - 11 - 19 - 53 - - - 19 - 38 - 53 - - - 39 - 72 - 50 - - - 74 - 147 - 23 + 26 @@ -2245,7 +2338,7 @@ 1 2 - 8982 + 10739 @@ -2261,7 +2354,7 @@ 1 2 - 8982 + 10739 @@ -2271,22 +2364,22 @@ erb_template_def - 1563 + 1540 id - 1563 + 1540 erb_tokeninfo - 19423 + 21259 id - 19423 + 21259 kind @@ -2294,7 +2387,7 @@ value - 5800 + 5773 @@ -2308,7 +2401,7 @@ 1 2 - 19423 + 21259 @@ -2324,7 +2417,7 @@ 1 2 - 19423 + 21259 @@ -2338,18 +2431,18 @@ 12 - 1266 - 1267 + 1803 + 1804 2 - 1757 - 1758 + 1878 + 1879 2 - 3514 - 3515 + 3606 + 3607 2 @@ -2364,18 +2457,18 @@ 12 - 52 - 53 + 5 + 6 2 - 884 - 885 + 932 + 933 2 - 1016 - 1017 + 1042 + 1043 2 @@ -2392,22 +2485,17 @@ 1 2 - 4662 + 4667 2 3 - 659 + 679 3 - 23 - 436 - - - 32 - 1696 - 41 + 1742 + 425 @@ -2423,7 +2511,7 @@ 1 2 - 5800 + 5773 @@ -2433,15 +2521,15 @@ files - 17168 + 17206 id - 17168 + 17206 name - 17168 + 17206 @@ -2455,7 +2543,7 @@ 1 2 - 17168 + 17206 @@ -2471,7 +2559,7 @@ 1 2 - 17168 + 17206 @@ -2481,15 +2569,15 @@ folders - 4792 + 4799 id - 4792 + 4799 name - 4792 + 4799 @@ -2503,7 +2591,7 @@ 1 2 - 4792 + 4799 @@ -2519,7 +2607,7 @@ 1 2 - 4792 + 4799 @@ -2529,31 +2617,31 @@ locations_default - 8508604 + 8706731 id - 8508604 + 8706731 file - 17168 + 17206 start_line - 30674 + 30719 start_column - 5064 + 5072 end_line - 30674 + 30719 end_column - 5129 + 5163 @@ -2567,7 +2655,7 @@ 1 2 - 8508604 + 8706731 @@ -2583,7 +2671,7 @@ 1 2 - 8508604 + 8706731 @@ -2599,7 +2687,7 @@ 1 2 - 8508604 + 8706731 @@ -2615,7 +2703,7 @@ 1 2 - 8508604 + 8706731 @@ -2631,7 +2719,7 @@ 1 2 - 8508604 + 8706731 @@ -2647,67 +2735,67 @@ 1 32 - 1337 + 1300 32 - 48 - 1311 + 49 + 1339 - 48 - 72 - 1376 + 49 + 73 + 1482 - 72 - 94 - 1493 + 73 + 95 + 1352 - 94 - 127 - 1298 + 95 + 126 + 1313 127 - 169 - 1311 + 170 + 1313 - 169 - 216 - 1298 + 170 + 218 + 1339 - 216 - 271 - 1298 + 218 + 277 + 1326 - 271 - 353 - 1311 + 277 + 359 + 1300 - 353 - 475 - 1298 + 361 + 489 + 1300 - 476 - 721 - 1298 + 492 + 736 + 1313 - 724 - 1480 - 1298 + 741 + 1508 + 1300 - 1481 - 22817 - 1233 + 1509 + 22819 + 1222 @@ -2716,158 +2804,6 @@ file start_line - - - 12 - - - 1 - 7 - 1116 - - - 7 - 10 - 1545 - - - 10 - 13 - 1389 - - - 13 - 16 - 1493 - - - 16 - 20 - 1571 - - - 20 - 25 - 1363 - - - 25 - 31 - 1441 - - - 31 - 38 - 1350 - - - 38 - 49 - 1441 - - - 49 - 69 - 1324 - - - 69 - 117 - 1298 - - - 119 - 257 - 1298 - - - 260 - 2337 - 532 - - - - - - - file - start_column - - - 12 - - - 1 - 16 - 1415 - - - 16 - 25 - 1428 - - - 25 - 32 - 1363 - - - 32 - 41 - 1376 - - - 41 - 47 - 1506 - - - 47 - 54 - 1532 - - - 54 - 62 - 1363 - - - 62 - 69 - 1402 - - - 69 - 77 - 1428 - - - 77 - 87 - 1350 - - - 87 - 101 - 1324 - - - 101 - 130 - 1298 - - - 130 - 357 - 376 - - - - - - - file - end_line 12 @@ -2875,67 +2811,219 @@ 1 8 - 1558 + 1586 8 11 - 1467 + 1443 11 14 - 1506 + 1521 14 17 - 1415 + 1430 17 21 - 1467 + 1417 21 26 - 1337 + 1352 26 32 - 1363 + 1378 32 39 - 1415 + 1378 39 51 - 1402 + 1417 51 75 - 1298 + 1326 75 126 - 1311 + 1313 126 343 - 1298 + 1300 354 2337 - 324 + 338 + + + + + + + file + start_column + + + 12 + + + 1 + 16 + 1404 + + + 16 + 25 + 1417 + + + 25 + 32 + 1378 + + + 32 + 41 + 1391 + + + 41 + 47 + 1495 + + + 47 + 54 + 1547 + + + 54 + 62 + 1339 + + + 62 + 69 + 1391 + + + 69 + 77 + 1443 + + + 77 + 87 + 1365 + + + 87 + 101 + 1326 + + + 101 + 129 + 1313 + + + 129 + 357 + 390 + + + + + + + file + end_line + + + 12 + + + 1 + 8 + 1547 + + + 8 + 11 + 1430 + + + 11 + 14 + 1547 + + + 14 + 17 + 1430 + + + 17 + 21 + 1430 + + + 21 + 26 + 1365 + + + 26 + 32 + 1378 + + + 32 + 39 + 1378 + + + 39 + 51 + 1417 + + + 51 + 75 + 1326 + + + 75 + 126 + 1313 + + + 126 + 343 + 1300 + + + 354 + 2337 + 338 @@ -2951,67 +3039,67 @@ 1 20 - 1441 + 1430 20 28 - 1298 + 1300 28 36 - 1389 + 1404 36 45 - 1363 + 1365 45 50 - 1311 + 1313 50 57 - 1350 + 1352 57 64 - 1376 + 1339 64 71 - 1298 + 1300 71 78 - 1376 + 1391 78 87 - 1428 + 1443 87 99 - 1402 + 1417 99 120 - 1363 + 1365 120 367 - 766 + 780 @@ -3027,67 +3115,72 @@ 1 2 - 1519 + 1430 2 4 - 1753 + 1716 5 6 - 3545 + 3316 6 10 - 2454 + 2523 10 - 17 - 2805 + 16 + 2367 - 17 - 24 - 2441 + 16 + 22 + 2562 - 24 - 42 - 2350 + 22 + 37 + 2327 - 42 - 78 - 2337 + 37 + 68 + 2341 - 78 - 119 - 2311 + 68 + 110 + 2314 - 119 - 173 - 2324 + 110 + 161 + 2314 - 173 - 279 - 2311 + 161 + 249 + 2314 - 281 - 866 - 2311 + 250 + 596 + 2314 - 866 - 10012 - 2207 + 601 + 3089 + 2314 + + + 3257 + 10293 + 559 @@ -3103,47 +3196,47 @@ 1 2 - 10713 + 9884 2 3 - 4753 + 5605 3 6 - 2337 + 2341 6 9 - 2363 + 2341 9 14 - 2792 + 2419 14 22 - 2324 + 2484 22 - 57 - 2311 + 49 + 2327 - 57 - 287 - 2311 + 49 + 220 + 2314 - 291 - 1322 - 766 + 223 + 1323 + 1001 @@ -3159,72 +3252,72 @@ 1 2 - 1519 + 1430 2 3 - 1584 + 1495 3 4 - 2558 + 2510 4 6 - 2441 + 2419 6 8 - 1584 + 1573 8 - 13 - 2818 + 12 + 2393 - 13 - 18 - 2610 + 12 + 16 + 2432 - 18 - 30 - 2506 + 16 + 25 + 2549 - 30 - 43 - 2363 + 25 + 39 + 2314 - 43 - 57 - 2428 + 39 + 53 + 2406 - 57 - 70 - 2324 + 53 + 66 + 2314 - 70 - 89 - 2350 + 66 + 81 + 2314 - 89 - 116 - 2311 + 81 + 104 + 2341 - 116 - 203 - 1272 + 104 + 205 + 2223 @@ -3240,42 +3333,42 @@ 1 2 - 12648 + 11106 2 3 - 6714 + 6294 3 4 - 2363 + 2275 4 5 - 1792 + 1547 5 7 - 2324 + 2653 7 - 12 - 2337 + 10 + 2432 - 12 - 34 - 2311 + 10 + 18 + 2536 - 40 + 18 241 - 181 + 1872 @@ -3291,67 +3384,67 @@ 1 2 - 1519 + 1430 2 4 - 1766 + 1742 4 5 - 3636 + 3407 5 8 - 2662 + 2757 8 13 - 2792 + 2822 13 - 17 - 2311 + 18 + 2562 - 17 + 18 28 - 2376 + 2445 28 - 42 - 2428 + 44 + 2367 - 42 - 57 - 2415 + 44 + 59 + 2419 - 57 - 71 - 2389 + 59 + 72 + 2367 - 71 + 72 88 - 2363 + 2341 88 - 113 - 2311 + 114 + 2314 - 113 - 203 - 1701 + 114 + 208 + 1742 @@ -3367,72 +3460,72 @@ 1 2 - 441 + 442 2 3 - 623 + 585 3 4 - 233 + 247 4 5 - 272 + 247 5 6 - 246 + 273 6 9 - 467 + 455 9 - 16 - 415 + 15 + 403 - 16 - 41 - 389 + 15 + 37 + 390 - 46 - 172 - 389 + 37 + 159 + 390 - 181 - 773 - 389 + 159 + 700 + 390 - 791 - 2919 - 389 + 723 + 2453 + 390 - 2920 - 8125 - 389 + 2462 + 7702 + 390 - 8227 - 25706 - 389 + 7795 + 14906 + 390 - 33875 - 34983 - 25 + 16424 + 38206 + 78 @@ -3448,52 +3541,52 @@ 1 2 - 1506 + 1456 2 3 - 545 + 481 3 4 - 428 + 481 4 - 10 - 389 + 9 + 390 - 10 - 39 - 389 + 9 + 33 + 390 - 39 - 139 - 389 + 34 + 109 + 390 - 147 - 387 - 389 + 112 + 353 + 390 - 397 - 748 - 389 + 358 + 696 + 390 - 769 - 963 - 389 + 698 + 950 + 390 - 964 - 1322 - 246 + 950 + 1323 + 312 @@ -3509,62 +3602,62 @@ 1 2 - 545 + 533 2 3 - 675 + 637 3 4 - 337 + 351 4 6 - 402 + 416 6 9 - 467 + 455 9 - 19 - 389 + 17 + 403 - 19 - 64 - 389 + 18 + 63 + 390 - 66 - 184 - 402 + 64 + 158 + 390 - 201 - 390 - 389 + 171 + 379 + 390 - 418 - 742 - 389 + 380 + 735 + 390 - 752 - 1025 - 389 + 735 + 1008 + 390 - 1028 - 1382 - 285 + 1010 + 1392 + 325 @@ -3580,62 +3673,62 @@ 1 2 - 545 + 533 2 3 - 675 + 637 3 4 - 337 + 351 4 6 - 402 + 416 6 9 - 467 + 455 9 - 19 - 389 + 17 + 403 - 19 + 18 64 - 389 + 390 - 66 - 184 - 389 + 64 + 159 + 390 - 184 + 171 381 - 389 + 390 - 396 - 752 - 389 + 385 + 749 + 390 - 753 - 1034 - 402 + 750 + 1026 + 390 - 1050 - 1386 - 285 + 1027 + 1399 + 325 @@ -3651,52 +3744,52 @@ 1 2 - 1285 + 1274 2 3 - 727 + 728 3 4 - 441 + 403 4 6 - 415 + 429 6 - 16 - 389 + 14 + 390 - 16 - 37 - 389 + 14 + 35 + 403 - 37 - 67 - 402 + 35 + 66 + 429 67 - 103 - 389 + 104 + 390 104 127 - 402 + 403 - 127 - 177 - 220 + 128 + 178 + 221 @@ -3712,72 +3805,72 @@ 1 2 - 311 + 286 3 4 - 3532 + 3316 4 6 - 2636 + 2458 6 9 - 2415 + 2497 9 14 - 2350 + 2471 14 21 - 2467 + 2393 21 - 34 - 2324 + 32 + 2341 - 34 - 64 - 2311 + 32 + 60 + 2367 - 64 - 103 - 2337 + 60 + 101 + 2314 - 103 + 101 152 - 2311 + 2354 152 230 - 2311 + 2341 230 - 525 - 2311 + 480 + 2314 - 528 - 2539 - 2311 + 482 + 2152 + 2314 - 2543 - 9864 - 740 + 2200 + 9921 + 949 @@ -3793,47 +3886,47 @@ 1 2 - 10713 + 9884 2 3 - 4753 + 5605 3 6 - 2337 + 2341 6 9 - 2363 + 2341 9 14 - 2792 + 2419 14 22 - 2324 + 2484 22 - 57 - 2311 + 49 + 2327 - 57 - 287 - 2311 + 49 + 220 + 2314 - 291 - 1306 - 766 + 223 + 1307 + 1001 @@ -3849,42 +3942,42 @@ 1 2 - 12428 + 11327 2 3 - 6532 + 5839 3 4 - 2532 + 2197 4 - 5 - 1753 + 6 + 2835 - 5 - 7 - 2207 + 6 + 8 + 2132 - 7 + 8 12 - 2441 + 2419 12 - 27 - 2363 + 24 + 2445 - 27 - 36 - 415 + 24 + 42 + 1521 @@ -3900,67 +3993,67 @@ 1 3 - 1519 + 1430 3 4 - 3688 + 3446 4 6 - 2714 + 2757 6 8 - 1649 + 1729 8 - 13 - 2766 + 12 + 2354 - 13 - 17 - 2363 + 12 + 16 + 2354 - 17 - 28 - 2415 + 16 + 24 + 2406 - 28 - 42 - 2415 + 24 + 39 + 2458 - 42 - 55 - 2337 + 39 + 53 + 2445 - 55 - 69 - 2441 + 53 + 67 + 2432 - 69 - 86 - 2415 + 67 + 82 + 2393 - 86 - 112 - 2376 + 82 + 105 + 2327 - 112 - 200 - 1571 + 105 + 204 + 2184 @@ -3976,72 +4069,72 @@ 1 2 - 1506 + 1417 2 3 - 1623 + 1534 3 4 - 2558 + 2510 4 6 - 2402 + 2367 6 8 - 1649 + 1690 8 13 - 2688 + 2783 13 18 - 2636 + 2549 18 - 30 - 2402 + 28 + 2432 - 30 + 28 44 - 2389 + 2445 44 - 58 - 2337 + 59 + 2393 - 58 + 59 72 - 2324 + 2419 72 90 - 2389 + 2354 90 117 - 2311 + 2327 117 - 202 - 1454 + 208 + 1495 @@ -4057,72 +4150,67 @@ 1 2 - 350 + 338 2 3 - 480 + 468 3 5 - 402 + 455 5 - 6 - 194 + 7 + 455 - 6 - 8 - 467 + 7 + 10 + 403 - 8 - 14 - 389 + 10 + 19 + 442 - 14 - 28 - 389 + 19 + 50 + 403 - 28 - 68 - 389 + 53 + 168 + 390 - 69 - 258 - 389 + 169 + 691 + 390 - 264 - 1063 - 389 + 806 + 2495 + 390 - 1113 - 3378 - 389 + 2618 + 6562 + 390 - 3687 - 8035 - 389 + 6710 + 9993 + 390 - 8096 - 10367 - 389 - - - 10416 - 17990 - 116 + 10241 + 19364 + 247 @@ -4138,52 +4226,52 @@ 1 2 - 1441 + 1404 2 3 - 610 + 585 3 4 - 428 + 429 4 - 9 - 402 + 7 + 390 - 9 - 41 - 389 + 7 + 24 + 390 - 42 - 123 - 389 + 24 + 94 + 390 - 143 - 406 - 389 + 95 + 314 + 390 - 406 - 760 - 389 + 325 + 676 + 390 - 771 - 994 - 389 + 688 + 977 + 390 - 1006 - 1289 - 298 + 979 + 1290 + 403 @@ -4199,67 +4287,67 @@ 1 2 - 519 + 507 2 3 - 675 + 650 3 4 - 298 + 338 4 6 - 402 + 429 6 9 - 454 + 429 9 - 16 - 415 + 15 + 390 16 39 - 389 + 429 - 39 - 136 - 389 + 40 + 138 + 390 - 136 - 344 - 389 + 141 + 332 + 390 - 353 - 637 - 389 + 352 + 653 + 390 - 675 - 1011 - 389 + 657 + 998 + 390 1011 - 1272 - 389 + 1264 + 390 - 1284 - 1387 - 25 + 1281 + 1401 + 39 @@ -4275,62 +4363,62 @@ 1 2 - 896 + 884 2 3 - 311 + 338 3 4 - 506 + 520 4 5 - 350 + 325 5 8 - 441 + 416 8 - 18 - 389 + 17 + 403 - 19 + 17 33 - 389 + 429 33 49 - 389 + 390 49 64 - 402 + 390 64 - 82 - 428 + 81 + 403 - 82 + 81 95 - 402 + 429 95 - 112 - 220 + 108 + 234 @@ -4346,67 +4434,67 @@ 1 2 - 519 + 507 2 3 - 675 + 663 3 4 - 298 + 338 4 6 - 402 + 416 6 9 - 454 + 429 9 - 16 - 415 + 15 + 403 - 16 - 39 - 402 + 15 + 36 + 390 - 48 - 141 - 389 + 37 + 131 + 390 - 142 - 352 - 389 + 133 + 314 + 390 - 359 - 637 - 389 + 314 + 632 + 390 - 674 - 999 - 389 + 637 + 969 + 390 - 1010 - 1283 - 389 + 970 + 1181 + 390 - 1381 - 1382 - 12 + 1211 + 1394 + 65 @@ -4416,19 +4504,19 @@ ruby_alias_def - 1244 + 1264 id - 1244 + 1264 alias - 1244 + 1264 name - 1244 + 1264 @@ -4442,7 +4530,7 @@ 1 2 - 1244 + 1264 @@ -4458,7 +4546,7 @@ 1 2 - 1244 + 1264 @@ -4474,7 +4562,7 @@ 1 2 - 1244 + 1264 @@ -4490,7 +4578,7 @@ 1 2 - 1244 + 1264 @@ -4506,7 +4594,7 @@ 1 2 - 1244 + 1264 @@ -4522,7 +4610,7 @@ 1 2 - 1244 + 1264 @@ -4635,19 +4723,19 @@ ruby_argument_list_child - 823783 + 832018 ruby_argument_list - 664257 + 669942 index - 428 + 429 child - 823783 + 832018 @@ -4661,17 +4749,17 @@ 1 2 - 562976 + 567211 2 3 - 64088 + 64884 3 34 - 37193 + 37846 @@ -4687,17 +4775,17 @@ 1 2 - 562976 + 567211 2 3 - 64088 + 64884 3 34 - 37193 + 37846 @@ -4713,47 +4801,47 @@ 1 2 - 142 + 143 2 3 - 38 + 39 3 7 - 38 + 39 7 11 - 38 + 39 11 - 20 - 38 + 21 + 39 - 22 - 42 - 38 + 23 + 43 + 39 - 55 - 372 - 38 + 56 + 378 + 39 - 900 - 7800 - 38 + 919 + 7900 + 39 - 51150 - 51151 - 12 + 51512 + 51513 + 13 @@ -4769,47 +4857,47 @@ 1 2 - 142 + 143 2 3 - 38 + 39 3 7 - 38 + 39 7 11 - 38 + 39 11 - 20 - 38 + 21 + 39 - 22 - 42 - 38 + 23 + 43 + 39 - 55 - 372 - 38 + 56 + 378 + 39 - 900 - 7800 - 38 + 919 + 7900 + 39 - 51150 - 51151 - 12 + 51512 + 51513 + 13 @@ -4825,7 +4913,7 @@ 1 2 - 823783 + 832018 @@ -4841,7 +4929,7 @@ 1 2 - 823783 + 832018 @@ -4851,22 +4939,22 @@ ruby_argument_list_def - 664517 + 670202 id - 664517 + 670202 ruby_array_child - 699082 + 700387 ruby_array - 237416 + 237942 index @@ -4874,7 +4962,7 @@ child - 699082 + 700387 @@ -4888,17 +4976,17 @@ 1 2 - 11987 + 12128 2 3 - 212081 + 212308 3 63361 - 13348 + 13506 @@ -4914,17 +5002,17 @@ 1 2 - 11987 + 12128 2 3 - 212081 + 212308 3 63361 - 13348 + 13506 @@ -4964,7 +5052,7 @@ 11 - 237417 + 237943 1294 @@ -5005,7 +5093,7 @@ 11 - 237417 + 237943 1294 @@ -5022,7 +5110,7 @@ 1 2 - 699082 + 700387 @@ -5038,7 +5126,7 @@ 1 2 - 699082 + 700387 @@ -5048,11 +5136,11 @@ ruby_array_def - 245561 + 246221 id - 245561 + 246221 @@ -5302,19 +5390,19 @@ ruby_assignment_def - 130246 + 131940 id - 130246 + 131940 left - 130246 + 131940 right - 130246 + 131940 @@ -5328,7 +5416,7 @@ 1 2 - 130246 + 131940 @@ -5344,7 +5432,7 @@ 1 2 - 130246 + 131940 @@ -5360,7 +5448,7 @@ 1 2 - 130246 + 131940 @@ -5376,7 +5464,7 @@ 1 2 - 130246 + 131940 @@ -5392,7 +5480,7 @@ 1 2 - 130246 + 131940 @@ -5408,7 +5496,7 @@ 1 2 - 130246 + 131940 @@ -5418,23 +5506,23 @@ ruby_ast_node_info - 8791047 + 9180290 node - 8791047 + 9180290 parent - 2884450 + 3212205 parent_index - 2792 + 2796 loc - 8496293 + 8693375 @@ -5448,7 +5536,7 @@ 1 2 - 8791047 + 9180290 @@ -5464,7 +5552,7 @@ 1 2 - 8791047 + 9180290 @@ -5480,7 +5568,7 @@ 1 2 - 8791047 + 9180290 @@ -5496,27 +5584,27 @@ 1 2 - 325272 + 517803 2 3 - 393074 + 442358 3 4 - 1608542 + 1733980 4 5 - 344466 + 339055 5 216 - 213094 + 179008 @@ -5532,27 +5620,27 @@ 1 2 - 325272 + 517803 2 3 - 393074 + 442358 3 4 - 1608542 + 1733980 4 5 - 344466 + 339055 5 216 - 213094 + 179008 @@ -5568,27 +5656,27 @@ 1 2 - 325272 + 517803 2 3 - 393074 + 442358 3 4 - 1608542 + 1733980 4 5 - 344466 + 339055 5 216 - 213094 + 179008 @@ -5604,52 +5692,57 @@ 1 2 - 649 + 455 2 3 - 389 + 195 3 - 5 - 233 + 4 + 390 - 5 + 4 6 - 233 + 234 6 - 9 - 233 + 7 + 234 - 9 + 7 + 10 + 234 + + + 10 21 - 246 + 208 21 - 48 - 220 + 42 + 221 - 48 - 127 - 220 + 43 + 95 + 221 - 130 - 946 - 220 + 99 + 491 + 221 - 1416 - 222113 - 142 + 524 + 246988 + 182 @@ -5665,52 +5758,57 @@ 1 2 - 649 + 455 2 3 - 389 + 195 3 - 5 - 233 + 4 + 390 - 5 + 4 6 - 233 + 234 6 - 9 - 233 + 7 + 234 - 9 + 7 + 10 + 234 + + + 10 21 - 246 + 208 21 - 48 - 220 + 42 + 221 - 48 - 127 - 220 + 43 + 95 + 221 - 130 - 946 - 220 + 99 + 491 + 221 - 1416 - 222113 - 142 + 524 + 246988 + 182 @@ -5726,52 +5824,57 @@ 1 2 - 649 + 455 2 3 - 389 + 195 3 - 5 - 233 + 4 + 390 - 5 + 4 6 - 233 + 234 6 - 9 - 233 + 7 + 234 - 9 + 7 + 10 + 234 + + + 10 21 - 246 + 208 21 - 48 - 220 + 42 + 221 - 48 - 127 - 220 + 43 + 95 + 221 - 130 - 946 - 220 + 99 + 491 + 221 - 1416 - 221838 - 142 + 524 + 246621 + 182 @@ -5787,12 +5890,12 @@ 1 2 - 8202149 + 8208085 2 4 - 294143 + 485289 @@ -5808,12 +5911,12 @@ 1 2 - 8202149 + 8208085 2 4 - 294143 + 485289 @@ -5829,12 +5932,12 @@ 1 2 - 8205110 + 8211232 2 3 - 291182 + 482142 @@ -5844,11 +5947,11 @@ ruby_bare_string_child - 14936 + 15074 ruby_bare_string - 11487 + 11622 index @@ -5856,7 +5959,7 @@ child - 14936 + 15074 @@ -5870,12 +5973,12 @@ 1 2 - 11159 + 11291 2 2233 - 328 + 331 @@ -5891,12 +5994,12 @@ 1 2 - 11159 + 11291 2 2233 - 328 + 331 @@ -5926,7 +6029,7 @@ 4 - 11488 + 11623 19 @@ -5957,7 +6060,7 @@ 4 - 11488 + 11623 19 @@ -5974,7 +6077,7 @@ 1 2 - 14936 + 15074 @@ -5990,7 +6093,7 @@ 1 2 - 14936 + 15074 @@ -6000,22 +6103,22 @@ ruby_bare_string_def - 11487 + 11622 id - 11487 + 11622 ruby_bare_symbol_child - 2106 + 2085 ruby_bare_symbol - 2106 + 2085 index @@ -6023,7 +6126,7 @@ child - 2106 + 2085 @@ -6037,7 +6140,7 @@ 1 2 - 2106 + 2085 @@ -6053,7 +6156,7 @@ 1 2 - 2106 + 2085 @@ -6067,8 +6170,8 @@ 12 - 709 - 710 + 715 + 716 2 @@ -6083,8 +6186,8 @@ 12 - 709 - 710 + 715 + 716 2 @@ -6101,7 +6204,7 @@ 1 2 - 2106 + 2085 @@ -6117,7 +6220,7 @@ 1 2 - 2106 + 2085 @@ -6127,11 +6230,11 @@ ruby_bare_symbol_def - 2106 + 2085 id - 2106 + 2085 @@ -6365,11 +6468,11 @@ ruby_begin_child - 7535 + 7615 ruby_begin - 2523 + 2549 index @@ -6377,7 +6480,7 @@ child - 7535 + 7615 @@ -6391,17 +6494,17 @@ 1 2 - 164 + 160 2 3 - 1317 + 1328 3 4 - 516 + 531 4 @@ -6411,7 +6514,7 @@ 5 8 - 230 + 234 8 @@ -6432,17 +6535,17 @@ 1 2 - 164 + 160 2 3 - 1317 + 1328 3 4 - 516 + 531 4 @@ -6452,7 +6555,7 @@ 5 8 - 230 + 234 8 @@ -6502,11 +6605,11 @@ 24 - 35 + 34 3 - 40 + 39 63 3 @@ -6516,13 +6619,13 @@ 3 - 314 - 1043 + 318 + 1062 3 - 2359 - 2524 + 2389 + 2550 2 @@ -6568,11 +6671,11 @@ 24 - 35 + 34 3 - 40 + 39 63 3 @@ -6582,13 +6685,13 @@ 3 - 314 - 1043 + 318 + 1062 3 - 2359 - 2524 + 2389 + 2550 2 @@ -6605,7 +6708,7 @@ 1 2 - 7535 + 7615 @@ -6621,7 +6724,7 @@ 1 2 - 7535 + 7615 @@ -6631,26 +6734,26 @@ ruby_begin_def - 2523 + 2549 id - 2523 + 2549 ruby_binary_def - 67730 + 68619 id - 67730 + 68619 left - 67730 + 68619 operator @@ -6658,7 +6761,7 @@ right - 67730 + 68619 @@ -6672,7 +6775,7 @@ 1 2 - 67730 + 68619 @@ -6688,7 +6791,7 @@ 1 2 - 67730 + 68619 @@ -6704,7 +6807,7 @@ 1 2 - 67730 + 68619 @@ -6720,7 +6823,7 @@ 1 2 - 67730 + 68619 @@ -6736,7 +6839,7 @@ 1 2 - 67730 + 68619 @@ -6752,7 +6855,7 @@ 1 2 - 67730 + 68619 @@ -6766,68 +6869,68 @@ 12 - 155 - 179 + 157 + 178 2 231 - 369 + 378 2 - 474 - 559 + 491 + 576 2 - 603 - 666 + 622 + 632 2 - 749 - 813 + 758 + 836 2 - 949 - 969 + 956 + 970 2 - 1000 - 1010 + 1011 + 1018 2 - 1248 - 1317 + 1182 + 1258 2 - 1348 - 1633 + 1332 + 1732 2 - 1820 - 1968 + 1804 + 2211 2 - 2381 - 3287 + 2409 + 3329 2 - 6116 - 6739 + 6173 + 6848 2 - 31159 - 31160 + 31539 + 31540 1 @@ -6842,68 +6945,68 @@ 12 - 155 - 179 + 157 + 178 2 231 - 369 + 378 2 - 474 - 559 + 491 + 576 2 - 603 - 666 + 622 + 632 2 - 749 - 813 + 758 + 836 2 - 949 - 969 + 956 + 970 2 - 1000 - 1010 + 1011 + 1018 2 - 1248 - 1317 + 1182 + 1258 2 - 1348 - 1633 + 1332 + 1732 2 - 1820 - 1968 + 1804 + 2211 2 - 2381 - 3287 + 2409 + 3329 2 - 6116 - 6739 + 6173 + 6848 2 - 31159 - 31160 + 31539 + 31540 1 @@ -6918,68 +7021,68 @@ 12 - 155 - 179 + 157 + 178 2 231 - 369 + 378 2 - 474 - 559 + 491 + 576 2 - 603 - 666 + 622 + 632 2 - 749 - 813 + 758 + 836 2 - 949 - 969 + 956 + 970 2 - 1000 - 1010 + 1011 + 1018 2 - 1248 - 1317 + 1182 + 1258 2 - 1348 - 1633 + 1332 + 1732 2 - 1820 - 1968 + 1804 + 2211 2 - 2381 - 3287 + 2409 + 3329 2 - 6116 - 6739 + 6173 + 6848 2 - 31159 - 31160 + 31539 + 31540 1 @@ -6996,7 +7099,7 @@ 1 2 - 67730 + 68619 @@ -7012,7 +7115,7 @@ 1 2 - 67730 + 68619 @@ -7028,7 +7131,7 @@ 1 2 - 67730 + 68619 @@ -7038,15 +7141,15 @@ ruby_block_argument_child - 6050 + 6115 ruby_block_argument - 6050 + 6115 child - 6050 + 6115 @@ -7060,7 +7163,7 @@ 1 2 - 6050 + 6115 @@ -7076,7 +7179,7 @@ 1 2 - 6050 + 6115 @@ -7086,36 +7189,32 @@ ruby_block_argument_def - 6050 + 6115 id - 6050 + 6115 - ruby_block_child - 97203 + ruby_block_body + 97983 ruby_block - 97060 + 97983 - index - 51 - - - child - 97203 + body + 97983 ruby_block - index + body 12 @@ -7123,92 +7222,14 @@ 1 2 - 96969 - - - 2 - 5 - 90 + 97983 - ruby_block - child - - - 12 - - - 1 - 2 - 96969 - - - 2 - 5 - 90 - - - - - - - index - ruby_block - - - 12 - - - 2 - 3 - 25 - - - 7 - 8 - 12 - - - 7474 - 7475 - 12 - - - - - - - index - child - - - 12 - - - 2 - 3 - 25 - - - 7 - 8 - 12 - - - 7474 - 7475 - 12 - - - - - - - child + body ruby_block @@ -7217,23 +7238,7 @@ 1 2 - 97203 - - - - - - - child - index - - - 12 - - - 1 - 2 - 97203 + 97983 @@ -7242,38 +7247,195 @@ - ruby_block_def - 97359 + ruby_block_body_child + 98126 + + + ruby_block_body + 97983 + + + index + 52 + + + child + 98126 + + + + + ruby_block_body + index + + + 12 + + + 1 + 2 + 97892 + + + 2 + 5 + 91 + + + + + + + ruby_block_body + child + + + 12 + + + 1 + 2 + 97892 + + + 2 + 5 + 91 + + + + + + + index + ruby_block_body + + + 12 + + + 2 + 3 + 26 + + + 7 + 8 + 13 + + + 7534 + 7535 + 13 + + + + + + + index + child + + + 12 + + + 2 + 3 + 26 + + + 7 + 8 + 13 + + + 7534 + 7535 + 13 + + + + + + + child + ruby_block_body + + + 12 + + + 1 + 2 + 98126 + + + + + + + child + index + + + 12 + + + 1 + 2 + 98126 + + + + + + + + + ruby_block_body_def + 97983 id - 97359 + 97983 + + + + + + ruby_block_def + 98296 + + + id + 98296 ruby_block_parameter_def - 2410 + 2442 id - 2410 + 2442 ruby_block_parameter_name - 2410 + 2442 ruby_block_parameter - 2410 + 2442 name - 2410 + 2442 @@ -7287,7 +7449,7 @@ 1 2 - 2410 + 2442 @@ -7303,7 +7465,7 @@ 1 2 - 2410 + 2442 @@ -7313,15 +7475,15 @@ ruby_block_parameters - 10459 + 10539 ruby_block - 10459 + 10539 parameters - 10459 + 10539 @@ -7335,7 +7497,7 @@ 1 2 - 10459 + 10539 @@ -7351,7 +7513,7 @@ 1 2 - 10459 + 10539 @@ -7361,11 +7523,11 @@ ruby_block_parameters_child - 27190 + 27656 ruby_block_parameters - 23336 + 23772 index @@ -7373,7 +7535,7 @@ child - 27190 + 27656 @@ -7387,17 +7549,17 @@ 1 2 - 19964 + 20371 2 3 - 3022 + 3053 3 6 - 349 + 347 @@ -7413,17 +7575,17 @@ 1 2 - 19964 + 20371 2 3 - 3022 + 3053 3 6 - 349 + 347 @@ -7437,28 +7599,28 @@ 12 - 9 - 10 + 10 + 11 3 - 33 - 34 + 34 + 35 3 - 111 - 112 + 112 + 113 3 - 1070 - 1071 + 1097 + 1098 3 - 7405 - 7406 + 7669 + 7670 3 @@ -7473,28 +7635,28 @@ 12 - 9 - 10 + 10 + 11 3 - 33 - 34 + 34 + 35 3 - 111 - 112 + 112 + 113 3 - 1070 - 1071 + 1097 + 1098 3 - 7405 - 7406 + 7669 + 7670 3 @@ -7511,7 +7673,7 @@ 1 2 - 27190 + 27656 @@ -7527,7 +7689,7 @@ 1 2 - 27190 + 27656 @@ -7537,11 +7699,11 @@ ruby_block_parameters_def - 23336 + 23772 id - 23336 + 23772 @@ -7683,16 +7845,323 @@ - ruby_break_child - 350 + ruby_body_statement_child + 606175 - ruby_break - 350 + ruby_body_statement + 195703 + + + index + 1103 child - 350 + 606175 + + + + + ruby_body_statement + index + + + 12 + + + 1 + 2 + 89956 + + + 2 + 3 + 35812 + + + 3 + 4 + 23304 + + + 4 + 5 + 14659 + + + 5 + 7 + 15433 + + + 7 + 22 + 14696 + + + 22 + 357 + 1841 + + + + + + + ruby_body_statement + child + + + 12 + + + 1 + 2 + 89956 + + + 2 + 3 + 35812 + + + 3 + 4 + 23304 + + + 4 + 5 + 14659 + + + 5 + 7 + 15433 + + + 7 + 22 + 14696 + + + 22 + 357 + 1841 + + + + + + + index + ruby_body_statement + + + 12 + + + 1 + 2 + 61 + + + 2 + 3 + 102 + + + 3 + 4 + 77 + + + 4 + 5 + 111 + + + 5 + 7 + 83 + + + 7 + 10 + 74 + + + 10 + 13 + 92 + + + 13 + 22 + 86 + + + 22 + 39 + 83 + + + 40 + 66 + 83 + + + 68 + 128 + 83 + + + 130 + 418 + 83 + + + 456 + 63135 + 77 + + + + + + + index + child + + + 12 + + + 1 + 2 + 61 + + + 2 + 3 + 102 + + + 3 + 4 + 77 + + + 4 + 5 + 111 + + + 5 + 7 + 83 + + + 7 + 10 + 74 + + + 10 + 13 + 92 + + + 13 + 22 + 86 + + + 22 + 39 + 83 + + + 40 + 66 + 83 + + + 68 + 128 + 83 + + + 130 + 418 + 83 + + + 456 + 63135 + 77 + + + + + + + child + ruby_body_statement + + + 12 + + + 1 + 2 + 606175 + + + + + + + child + index + + + 12 + + + 1 + 2 + 606175 + + + + + + + + + ruby_body_statement_def + 201560 + + + id + 201560 + + + + + + ruby_break_child + 354 + + + ruby_break + 354 + + + child + 354 @@ -7706,7 +8175,7 @@ 1 2 - 350 + 354 @@ -7722,7 +8191,7 @@ 1 2 - 350 + 354 @@ -7732,26 +8201,26 @@ ruby_break_def - 3338 + 3355 id - 3338 + 3355 ruby_call_arguments - 661504 + 667146 ruby_call - 661504 + 667146 arguments - 661504 + 667146 @@ -7765,7 +8234,7 @@ 1 2 - 661504 + 667146 @@ -7781,7 +8250,7 @@ 1 2 - 661504 + 667146 @@ -7791,15 +8260,15 @@ ruby_call_block - 232457 + 233892 ruby_call - 232457 + 233892 block - 232457 + 233892 @@ -7813,7 +8282,7 @@ 1 2 - 232457 + 233892 @@ -7829,7 +8298,7 @@ 1 2 - 232457 + 233892 @@ -7839,26 +8308,26 @@ ruby_call_def - 965401 + 974897 id - 965401 + 974897 ruby_call_method - 965401 + 974897 ruby_call - 965401 + 974897 method - 965401 + 974897 @@ -7872,7 +8341,7 @@ 1 2 - 965401 + 974897 @@ -7888,7 +8357,7 @@ 1 2 - 965401 + 974897 @@ -7898,15 +8367,15 @@ ruby_call_operator - 540944 + 548273 ruby_call - 540944 + 548273 operator - 540944 + 548273 @@ -7920,7 +8389,7 @@ 1 2 - 540944 + 548273 @@ -7936,7 +8405,7 @@ 1 2 - 540944 + 548273 @@ -7946,15 +8415,15 @@ ruby_call_receiver - 540944 + 548273 ruby_call - 540944 + 548273 receiver - 540944 + 548273 @@ -7968,7 +8437,7 @@ 1 2 - 540944 + 548273 @@ -7984,7 +8453,7 @@ 1 2 - 540944 + 548273 @@ -7994,19 +8463,19 @@ ruby_case_child - 4141 + 4153 ruby_case__ - 1219 + 1224 index - 69 + 68 child - 4141 + 4153 @@ -8025,12 +8494,12 @@ 2 3 - 315 + 316 3 4 - 504 + 511 4 @@ -8040,12 +8509,12 @@ 5 7 - 107 + 105 7 23 - 66 + 65 @@ -8066,12 +8535,12 @@ 2 3 - 315 + 316 3 4 - 504 + 511 4 @@ -8081,12 +8550,12 @@ 5 7 - 107 + 105 7 23 - 66 + 65 @@ -8102,12 +8571,12 @@ 1 2 - 25 + 21 2 3 - 6 + 9 3 @@ -8125,18 +8594,18 @@ 6 - 32 + 34 56 6 - 115 - 276 + 116 + 282 6 - 375 - 388 + 383 + 396 6 @@ -8153,12 +8622,12 @@ 1 2 - 25 + 21 2 3 - 6 + 9 3 @@ -8176,18 +8645,18 @@ 6 - 32 + 34 56 6 - 115 - 276 + 116 + 282 6 - 375 - 388 + 383 + 396 6 @@ -8204,7 +8673,7 @@ 1 2 - 4141 + 4153 @@ -8220,7 +8689,7 @@ 1 2 - 4141 + 4153 @@ -8230,11 +8699,11 @@ ruby_case_def - 1219 + 1224 id - 1219 + 1224 @@ -8423,15 +8892,15 @@ ruby_case_value - 1178 + 1184 ruby_case__ - 1178 + 1184 value - 1178 + 1184 @@ -8445,7 +8914,7 @@ 1 2 - 1178 + 1184 @@ -8461,7 +8930,7 @@ 1 2 - 1178 + 1184 @@ -8471,11 +8940,11 @@ ruby_chained_string_child - 3353 + 3329 ruby_chained_string - 885 + 877 index @@ -8483,7 +8952,7 @@ child - 3353 + 3329 @@ -8497,32 +8966,32 @@ 2 3 - 302 + 291 3 4 - 195 + 201 4 5 - 135 + 133 5 6 - 122 + 123 6 8 - 66 + 65 8 13 - 63 + 61 @@ -8538,32 +9007,32 @@ 2 3 - 302 + 291 3 4 - 195 + 201 4 5 - 135 + 133 5 6 - 122 + 123 6 8 - 66 + 65 8 13 - 63 + 61 @@ -8612,23 +9081,23 @@ 3 - 80 - 81 + 81 + 82 3 - 123 - 124 + 124 + 125 3 - 185 - 186 + 189 + 190 3 - 281 - 282 + 283 + 284 6 @@ -8678,23 +9147,23 @@ 3 - 80 - 81 + 81 + 82 3 - 123 - 124 + 124 + 125 3 - 185 - 186 + 189 + 190 3 - 281 - 282 + 283 + 284 6 @@ -8711,7 +9180,7 @@ 1 2 - 3353 + 3329 @@ -8727,7 +9196,7 @@ 1 2 - 3353 + 3329 @@ -8737,36 +9206,32 @@ ruby_chained_string_def - 885 + 877 id - 885 + 877 - ruby_class_child - 130958 + ruby_class_body + 15291 ruby_class - 15183 + 15291 - index - 1055 - - - child - 130958 + body + 15291 ruby_class - index + body 12 @@ -8774,130 +9239,14 @@ 1 2 - 3290 - - - 2 - 3 - 2407 - - - 3 - 4 - 1556 - - - 4 - 5 - 1263 - - - 5 - 6 - 961 - - - 6 - 7 - 838 - - - 7 - 9 - 1118 - - - 9 - 13 - 1266 - - - 13 - 21 - 1169 - - - 21 - 84 - 1143 - - - 85 - 336 - 167 + 15291 - ruby_class - child - - - 12 - - - 1 - 2 - 3290 - - - 2 - 3 - 2407 - - - 3 - 4 - 1556 - - - 4 - 5 - 1263 - - - 5 - 6 - 961 - - - 6 - 7 - 838 - - - 7 - 9 - 1118 - - - 9 - 13 - 1266 - - - 13 - 21 - 1169 - - - 21 - 84 - 1143 - - - 85 - 336 - 167 - - - - - - - index + body ruby_class @@ -8906,185 +9255,7 @@ 1 2 - 37 - - - 2 - 3 - 63 - - - 3 - 4 - 81 - - - 4 - 5 - 113 - - - 5 - 7 - 81 - - - 7 - 9 - 81 - - - 9 - 12 - 88 - - - 12 - 19 - 85 - - - 19 - 29 - 81 - - - 30 - 56 - 81 - - - 56 - 94 - 81 - - - 96 - 228 - 81 - - - 237 - 2116 - 81 - - - 2516 - 4819 - 12 - - - - - - - index - child - - - 12 - - - 1 - 2 - 37 - - - 2 - 3 - 63 - - - 3 - 4 - 81 - - - 4 - 5 - 113 - - - 5 - 7 - 81 - - - 7 - 9 - 81 - - - 9 - 12 - 88 - - - 12 - 19 - 85 - - - 19 - 29 - 81 - - - 30 - 56 - 81 - - - 56 - 94 - 81 - - - 96 - 228 - 81 - - - 237 - 2116 - 81 - - - 2516 - 4819 - 12 - - - - - - - child - ruby_class - - - 12 - - - 1 - 2 - 130958 - - - - - - - child - index - - - 12 - - - 1 - 2 - 130958 + 15291 @@ -9094,15 +9265,15 @@ ruby_class_def - 16841 + 16946 id - 16841 + 16946 name - 16841 + 16946 @@ -9116,7 +9287,7 @@ 1 2 - 16841 + 16946 @@ -9132,7 +9303,7 @@ 1 2 - 16841 + 16946 @@ -9142,15 +9313,15 @@ ruby_class_superclass - 13314 + 13378 ruby_class - 13314 + 13378 superclass - 13314 + 13378 @@ -9164,7 +9335,7 @@ 1 2 - 13314 + 13378 @@ -9180,7 +9351,7 @@ 1 2 - 13314 + 13378 @@ -9238,23 +9409,23 @@ ruby_conditional_def - 3464 + 3495 id - 3464 + 3495 alternative - 3464 + 3495 condition - 3464 + 3495 consequence - 3464 + 3495 @@ -9268,7 +9439,7 @@ 1 2 - 3464 + 3495 @@ -9284,7 +9455,7 @@ 1 2 - 3464 + 3495 @@ -9300,7 +9471,7 @@ 1 2 - 3464 + 3495 @@ -9316,7 +9487,7 @@ 1 2 - 3464 + 3495 @@ -9332,7 +9503,7 @@ 1 2 - 3464 + 3495 @@ -9348,7 +9519,7 @@ 1 2 - 3464 + 3495 @@ -9364,7 +9535,7 @@ 1 2 - 3464 + 3495 @@ -9380,7 +9551,7 @@ 1 2 - 3464 + 3495 @@ -9396,7 +9567,7 @@ 1 2 - 3464 + 3495 @@ -9412,7 +9583,7 @@ 1 2 - 3464 + 3495 @@ -9428,7 +9599,7 @@ 1 2 - 3464 + 3495 @@ -9444,7 +9615,7 @@ 1 2 - 3464 + 3495 @@ -9454,19 +9625,19 @@ ruby_delimited_symbol_child - 1739 + 1757 ruby_delimited_symbol - 1257 + 1264 index - 25 + 24 child - 1739 + 1757 @@ -9480,17 +9651,17 @@ 1 2 - 939 + 936 2 3 - 245 + 254 3 9 - 72 + 74 @@ -9506,17 +9677,17 @@ 1 2 - 939 + 936 2 3 - 245 + 254 3 9 - 72 + 74 @@ -9555,18 +9726,18 @@ 3 - 23 - 24 + 24 + 25 3 - 101 - 102 + 106 + 107 3 - 399 - 400 + 408 + 409 3 @@ -9606,18 +9777,18 @@ 3 - 23 - 24 + 24 + 25 3 - 101 - 102 + 106 + 107 3 - 399 - 400 + 408 + 409 3 @@ -9634,7 +9805,7 @@ 1 2 - 1739 + 1757 @@ -9650,7 +9821,7 @@ 1 2 - 1739 + 1757 @@ -9660,11 +9831,11 @@ ruby_delimited_symbol_def - 1257 + 1264 id - 1257 + 1264 @@ -9858,19 +10029,19 @@ ruby_destructured_parameter_child - 406 + 412 ruby_destructured_parameter - 198 + 188 index - 12 + 11 child - 406 + 412 @@ -9884,17 +10055,22 @@ 1 2 - 9 + 15 2 3 - 173 + 146 3 - 5 - 15 + 4 + 18 + + + 4 + 12 + 9 @@ -9910,17 +10086,22 @@ 1 2 - 9 + 15 2 3 - 173 + 146 3 - 5 - 15 + 4 + 18 + + + 4 + 12 + 9 @@ -9936,22 +10117,37 @@ 1 2 - 3 + 1 - 5 - 6 - 3 + 2 + 3 + 5 - 60 - 61 - 3 + 4 + 5 + 1 - 63 - 64 - 3 + 9 + 10 + 1 + + + 27 + 28 + 1 + + + 173 + 174 + 1 + + + 188 + 189 + 1 @@ -9967,22 +10163,37 @@ 1 2 - 3 + 1 - 5 - 6 - 3 + 2 + 3 + 5 - 60 - 61 - 3 + 4 + 5 + 1 - 63 - 64 - 3 + 9 + 10 + 1 + + + 27 + 28 + 1 + + + 173 + 174 + 1 + + + 188 + 189 + 1 @@ -9998,7 +10209,7 @@ 1 2 - 406 + 412 @@ -10014,7 +10225,7 @@ 1 2 - 406 + 412 @@ -10034,26 +10245,22 @@ - ruby_do_block_child - 395009 + ruby_do_block_body + 137963 ruby_do_block - 137279 + 137963 - index - 935 - - - child - 395009 + body + 137963 ruby_do_block - index + body 12 @@ -10061,80 +10268,14 @@ 1 2 - 48036 - - - 2 - 3 - 36712 - - - 3 - 4 - 21583 - - - 4 - 5 - 10506 - - - 5 - 7 - 10583 - - - 7 - 73 - 9856 + 137963 - ruby_do_block - child - - - 12 - - - 1 - 2 - 48036 - - - 2 - 3 - 36712 - - - 3 - 4 - 21583 - - - 4 - 5 - 10506 - - - 5 - 7 - 10583 - - - 7 - 73 - 9856 - - - - - - - index + body ruby_do_block @@ -10143,165 +10284,7 @@ 1 2 - 51 - - - 2 - 3 - 220 - - - 4 - 7 - 77 - - - 7 - 8 - 51 - - - 8 - 11 - 77 - - - 11 - 14 - 51 - - - 14 - 18 - 77 - - - 21 - 54 - 77 - - - 62 - 142 - 77 - - - 175 - 592 - 77 - - - 759 - 6873 - 77 - - - 10571 - 10572 - 12 - - - - - - - index - child - - - 12 - - - 1 - 2 - 51 - - - 2 - 3 - 220 - - - 4 - 7 - 77 - - - 7 - 8 - 51 - - - 8 - 11 - 77 - - - 11 - 14 - 51 - - - 14 - 18 - 77 - - - 21 - 54 - 77 - - - 62 - 142 - 77 - - - 175 - 592 - 77 - - - 759 - 6873 - 77 - - - 10571 - 10572 - 12 - - - - - - - child - ruby_do_block - - - 12 - - - 1 - 2 - 395009 - - - - - - - child - index - - - 12 - - - 1 - 2 - 395009 + 137963 @@ -10311,26 +10294,26 @@ ruby_do_block_def - 137435 + 138119 id - 137435 + 138119 ruby_do_block_parameters - 15073 + 15269 ruby_do_block - 15073 + 15269 parameters - 15073 + 15269 @@ -10344,7 +10327,7 @@ 1 2 - 15073 + 15269 @@ -10360,7 +10343,7 @@ 1 2 - 15073 + 15269 @@ -10370,11 +10353,11 @@ ruby_do_child - 9177 + 9244 ruby_do - 1588 + 1608 index @@ -10382,7 +10365,7 @@ child - 9177 + 9244 @@ -10396,27 +10379,27 @@ 1 2 - 324 + 331 2 3 - 273 + 279 3 4 - 191 + 194 4 5 - 77 + 78 5 7 - 104 + 106 7 @@ -10431,12 +10414,12 @@ 9 14 - 117 + 115 14 18 - 121 + 124 18 @@ -10457,27 +10440,27 @@ 1 2 - 324 + 331 2 3 - 273 + 279 3 4 - 191 + 194 4 5 - 77 + 78 5 7 - 104 + 106 7 @@ -10492,12 +10475,12 @@ 9 14 - 117 + 115 14 18 - 121 + 124 18 @@ -10537,12 +10520,12 @@ 6 - 59 + 61 16 - 112 - 1589 + 114 + 1609 15 @@ -10578,12 +10561,12 @@ 6 - 59 + 61 16 - 112 - 1589 + 114 + 1609 15 @@ -10600,7 +10583,7 @@ 1 2 - 9177 + 9244 @@ -10616,7 +10599,7 @@ 1 2 - 9177 + 9244 @@ -10626,22 +10609,22 @@ ruby_do_def - 1610 + 1632 id - 1610 + 1632 ruby_element_reference_child - 82398 + 83029 ruby_element_reference - 82228 + 82863 index @@ -10649,7 +10632,7 @@ child - 82398 + 83029 @@ -10663,12 +10646,12 @@ 1 2 - 82059 + 82697 2 3 - 169 + 166 @@ -10684,12 +10667,12 @@ 1 2 - 82059 + 82697 2 3 - 169 + 166 @@ -10708,8 +10691,8 @@ 2 - 27674 - 27675 + 28403 + 28404 2 @@ -10729,8 +10712,8 @@ 2 - 27674 - 27675 + 28403 + 28404 2 @@ -10747,7 +10730,7 @@ 1 2 - 82398 + 83029 @@ -10763,7 +10746,7 @@ 1 2 - 82398 + 83029 @@ -10773,15 +10756,15 @@ ruby_element_reference_def - 82234 + 82869 id - 82234 + 82869 object - 82234 + 82869 @@ -10795,7 +10778,7 @@ 1 2 - 82234 + 82869 @@ -10811,7 +10794,7 @@ 1 2 - 82234 + 82869 @@ -10821,11 +10804,11 @@ ruby_else_child - 8802 + 9054 ruby_else - 6923 + 7126 index @@ -10833,7 +10816,7 @@ child - 8802 + 9054 @@ -10847,17 +10830,17 @@ 1 2 - 5833 + 6004 2 3 - 687 + 703 3 12 - 403 + 418 @@ -10873,17 +10856,17 @@ 1 2 - 5833 + 6004 2 3 - 687 + 703 3 12 - 403 + 418 @@ -10927,28 +10910,28 @@ 3 - 29 - 30 + 28 + 29 3 - 55 - 56 + 59 + 60 3 - 128 - 129 + 135 + 136 3 - 346 - 347 + 362 + 363 3 - 2197 - 2198 + 2299 + 2300 3 @@ -10993,28 +10976,28 @@ 3 - 29 - 30 + 28 + 29 3 - 55 - 56 + 59 + 60 3 - 128 - 129 + 135 + 136 3 - 346 - 347 + 362 + 363 3 - 2197 - 2198 + 2299 + 2300 3 @@ -11031,7 +11014,7 @@ 1 2 - 8802 + 9054 @@ -11047,7 +11030,7 @@ 1 2 - 8802 + 9054 @@ -11057,26 +11040,26 @@ ruby_else_def - 6933 + 7138 id - 6933 + 7138 ruby_elsif_alternative - 903 + 936 ruby_elsif - 903 + 936 alternative - 903 + 936 @@ -11090,7 +11073,7 @@ 1 2 - 903 + 936 @@ -11106,7 +11089,7 @@ 1 2 - 903 + 936 @@ -11116,15 +11099,15 @@ ruby_elsif_consequence - 1589 + 1572 ruby_elsif - 1589 + 1572 consequence - 1589 + 1572 @@ -11138,7 +11121,7 @@ 1 2 - 1589 + 1572 @@ -11154,7 +11137,7 @@ 1 2 - 1589 + 1572 @@ -11164,15 +11147,15 @@ ruby_elsif_def - 1595 + 1578 id - 1595 + 1578 condition - 1595 + 1578 @@ -11186,7 +11169,7 @@ 1 2 - 1595 + 1578 @@ -11202,7 +11185,7 @@ 1 2 - 1595 + 1578 @@ -11399,19 +11382,19 @@ ruby_ensure_child - 4834 + 4925 ruby_ensure - 3718 + 3803 index - 50 + 49 child - 4834 + 4925 @@ -11425,17 +11408,17 @@ 1 2 - 2956 + 3034 2 3 - 516 + 526 3 17 - 245 + 241 @@ -11451,17 +11434,17 @@ 1 2 - 2956 + 3034 2 3 - 516 + 526 3 17 - 245 + 241 @@ -11477,7 +11460,7 @@ 1 2 - 25 + 24 3 @@ -11490,8 +11473,8 @@ 6 - 12 - 13 + 14 + 15 3 @@ -11500,13 +11483,13 @@ 3 - 242 - 243 + 248 + 249 3 - 1180 - 1181 + 1227 + 1228 3 @@ -11523,7 +11506,7 @@ 1 2 - 25 + 24 3 @@ -11536,8 +11519,8 @@ 6 - 12 - 13 + 14 + 15 3 @@ -11546,13 +11529,13 @@ 3 - 242 - 243 + 248 + 249 3 - 1180 - 1181 + 1227 + 1228 3 @@ -11569,7 +11552,7 @@ 1 2 - 4834 + 4925 @@ -11585,7 +11568,7 @@ 1 2 - 4834 + 4925 @@ -11595,26 +11578,26 @@ ruby_ensure_def - 3718 + 3803 id - 3718 + 3803 ruby_exception_variable_def - 1001 + 991 id - 1001 + 991 child - 1001 + 991 @@ -11628,7 +11611,7 @@ 1 2 - 1001 + 991 @@ -11644,7 +11627,7 @@ 1 2 - 1001 + 991 @@ -11654,11 +11637,11 @@ ruby_exceptions_child - 1849 + 1873 ruby_exceptions - 1639 + 1654 index @@ -11666,7 +11649,7 @@ child - 1849 + 1873 @@ -11680,17 +11663,17 @@ 1 2 - 1497 + 1509 2 4 - 129 + 131 4 10 - 13 + 14 @@ -11706,17 +11689,17 @@ 1 2 - 1497 + 1509 2 4 - 129 + 131 4 10 - 13 + 14 @@ -11745,28 +11728,28 @@ 1 - 8 - 9 + 9 + 10 1 - 13 - 14 + 14 + 15 1 - 38 - 39 + 42 + 43 1 - 142 - 143 + 145 + 146 1 - 1639 - 1640 + 1654 + 1655 1 @@ -11796,28 +11779,28 @@ 1 - 8 - 9 + 9 + 10 1 - 13 - 14 + 14 + 15 1 - 38 - 39 + 42 + 43 1 - 142 - 143 + 145 + 146 1 - 1639 - 1640 + 1654 + 1655 1 @@ -11834,7 +11817,7 @@ 1 2 - 1849 + 1873 @@ -11850,7 +11833,7 @@ 1 2 - 1849 + 1873 @@ -11860,11 +11843,11 @@ ruby_exceptions_def - 1639 + 1654 id - 1639 + 1654 @@ -12280,19 +12263,19 @@ ruby_hash_child - 88983 + 89413 ruby_hash - 35712 + 35882 index - 1389 + 1391 child - 88983 + 89413 @@ -12306,32 +12289,32 @@ 1 2 - 14778 + 14813 2 3 - 9960 + 10040 3 4 - 3960 + 3992 4 5 - 4142 + 4161 5 19 - 2688 + 2692 19 108 - 181 + 182 @@ -12347,32 +12330,32 @@ 1 2 - 14778 + 14813 2 3 - 9960 + 10040 3 4 - 3960 + 3992 4 5 - 4142 + 4161 5 19 - 2688 + 2692 19 108 - 181 + 182 @@ -12388,32 +12371,32 @@ 1 2 - 922 + 923 3 4 - 103 + 104 5 11 - 116 + 117 14 51 - 116 + 117 57 - 1613 - 116 + 1621 + 117 - 2750 - 2751 - 12 + 2759 + 2760 + 13 @@ -12429,32 +12412,32 @@ 1 2 - 922 + 923 3 4 - 103 + 104 5 11 - 116 + 117 14 51 - 116 + 117 57 - 1613 - 116 + 1621 + 117 - 2750 - 2751 - 12 + 2759 + 2760 + 13 @@ -12470,7 +12453,7 @@ 1 2 - 88983 + 89413 @@ -12486,7 +12469,7 @@ 1 2 - 88983 + 89413 @@ -12496,11 +12479,11 @@ ruby_hash_def - 39413 + 39640 id - 39413 + 39640 @@ -12658,15 +12641,15 @@ ruby_hash_splat_argument_def - 1856 + 1857 id - 1856 + 1857 child - 1856 + 1857 @@ -12680,7 +12663,7 @@ 1 2 - 1856 + 1857 @@ -12696,7 +12679,7 @@ 1 2 - 1856 + 1857 @@ -12706,26 +12689,26 @@ ruby_hash_splat_parameter_def - 1355 + 1447 id - 1355 + 1447 ruby_hash_splat_parameter_name - 1134 + 1218 ruby_hash_splat_parameter - 1134 + 1218 name - 1134 + 1218 @@ -12739,7 +12722,7 @@ 1 2 - 1134 + 1218 @@ -12755,7 +12738,7 @@ 1 2 - 1134 + 1218 @@ -12765,19 +12748,19 @@ ruby_heredoc_body_child - 25318 + 25699 ruby_heredoc_body - 5363 + 5519 index - 264 + 259 child - 25318 + 25699 @@ -12791,12 +12774,12 @@ 2 3 - 2929 + 3080 4 5 - 692 + 685 5 @@ -12806,22 +12789,22 @@ 6 7 - 781 + 787 7 9 - 341 + 335 10 15 - 421 + 440 16 90 - 193 + 186 @@ -12837,12 +12820,12 @@ 2 3 - 2929 + 3080 4 5 - 692 + 685 5 @@ -12852,22 +12835,22 @@ 6 7 - 781 + 787 7 9 - 341 + 335 10 15 - 421 + 440 16 90 - 193 + 186 @@ -12883,12 +12866,17 @@ 1 2 - 50 + 49 2 3 - 83 + 46 + + + 3 + 4 + 35 4 @@ -12897,11 +12885,11 @@ 8 - 12 + 13 23 - 12 + 13 26 23 @@ -12912,12 +12900,12 @@ 96 - 323 + 331 20 - 585 - 1806 + 600 + 1893 17 @@ -12934,12 +12922,17 @@ 1 2 - 50 + 49 2 3 - 83 + 46 + + + 3 + 4 + 35 4 @@ -12948,11 +12941,11 @@ 8 - 12 + 13 23 - 12 + 13 26 23 @@ -12963,12 +12956,12 @@ 96 - 323 + 331 20 - 585 - 1806 + 600 + 1893 17 @@ -12985,7 +12978,7 @@ 1 2 - 25318 + 25699 @@ -13001,7 +12994,7 @@ 1 2 - 25318 + 25699 @@ -13011,26 +13004,26 @@ ruby_heredoc_body_def - 5575 + 5789 id - 5575 + 5789 ruby_if_alternative - 6454 + 6667 ruby_if - 6454 + 6667 alternative - 6454 + 6667 @@ -13044,7 +13037,7 @@ 1 2 - 6454 + 6667 @@ -13060,7 +13053,7 @@ 1 2 - 6454 + 6667 @@ -13070,15 +13063,15 @@ ruby_if_consequence - 18324 + 18280 ruby_if - 18324 + 18280 consequence - 18324 + 18280 @@ -13092,7 +13085,7 @@ 1 2 - 18324 + 18280 @@ -13108,7 +13101,7 @@ 1 2 - 18324 + 18280 @@ -13118,15 +13111,15 @@ ruby_if_def - 18392 + 18341 id - 18392 + 18341 condition - 18392 + 18341 @@ -13140,7 +13133,7 @@ 1 2 - 18392 + 18341 @@ -13156,7 +13149,7 @@ 1 2 - 18392 + 18341 @@ -13208,19 +13201,19 @@ ruby_if_modifier_def - 13620 + 13708 id - 13620 + 13708 body - 13620 + 13708 condition - 13620 + 13708 @@ -13234,7 +13227,7 @@ 1 2 - 13620 + 13708 @@ -13250,7 +13243,7 @@ 1 2 - 13620 + 13708 @@ -13266,7 +13259,7 @@ 1 2 - 13620 + 13708 @@ -13282,7 +13275,7 @@ 1 2 - 13620 + 13708 @@ -13298,7 +13291,7 @@ 1 2 - 13620 + 13708 @@ -13314,7 +13307,7 @@ 1 2 - 13620 + 13708 @@ -13510,11 +13503,11 @@ ruby_interpolation_child - 38208 + 38051 ruby_interpolation - 38208 + 38051 index @@ -13522,7 +13515,7 @@ child - 38208 + 38051 @@ -13536,7 +13529,7 @@ 1 2 - 38208 + 38051 @@ -13552,7 +13545,7 @@ 1 2 - 38208 + 38051 @@ -13566,8 +13559,8 @@ 12 - 12859 - 12860 + 13043 + 13044 2 @@ -13582,8 +13575,8 @@ 12 - 12859 - 12860 + 13043 + 13044 2 @@ -13600,7 +13593,7 @@ 1 2 - 38208 + 38051 @@ -13616,7 +13609,7 @@ 1 2 - 38208 + 38051 @@ -13626,26 +13619,26 @@ ruby_interpolation_def - 38208 + 38051 id - 38208 + 38051 ruby_keyword_parameter_def - 3794 + 3939 id - 3794 + 3939 name - 3794 + 3939 @@ -13659,7 +13652,7 @@ 1 2 - 3794 + 3939 @@ -13675,7 +13668,7 @@ 1 2 - 3794 + 3939 @@ -13685,15 +13678,15 @@ ruby_keyword_parameter_value - 2874 + 2985 ruby_keyword_parameter - 2874 + 2985 value - 2874 + 2985 @@ -13707,7 +13700,7 @@ 1 2 - 2874 + 2985 @@ -13723,7 +13716,7 @@ 1 2 - 2874 + 2985 @@ -13823,15 +13816,15 @@ ruby_lambda_def - 7472 + 7557 id - 7472 + 7557 body - 7472 + 7557 @@ -13845,7 +13838,7 @@ 1 2 - 7472 + 7557 @@ -13861,7 +13854,7 @@ 1 2 - 7472 + 7557 @@ -13871,15 +13864,15 @@ ruby_lambda_parameters - 1664 + 1665 ruby_lambda - 1664 + 1665 parameters - 1664 + 1665 @@ -13893,7 +13886,7 @@ 1 2 - 1664 + 1665 @@ -13909,7 +13902,7 @@ 1 2 - 1664 + 1665 @@ -13919,11 +13912,11 @@ ruby_lambda_parameters_child - 1905 + 1907 ruby_lambda_parameters - 1655 + 1656 index @@ -13931,7 +13924,7 @@ child - 1905 + 1907 @@ -13950,7 +13943,7 @@ 2 3 - 144 + 145 3 @@ -13976,7 +13969,7 @@ 2 3 - 144 + 145 3 @@ -14020,13 +14013,13 @@ 1 - 183 - 184 + 184 + 185 1 - 1655 - 1656 + 1656 + 1657 1 @@ -14066,13 +14059,13 @@ 1 - 183 - 184 + 184 + 185 1 - 1655 - 1656 + 1656 + 1657 1 @@ -14089,7 +14082,7 @@ 1 2 - 1905 + 1907 @@ -14105,7 +14098,7 @@ 1 2 - 1905 + 1907 @@ -14115,22 +14108,22 @@ ruby_lambda_parameters_def - 1664 + 1665 id - 1664 + 1665 ruby_left_assignment_list_child - 6358 + 6436 ruby_left_assignment_list - 2873 + 2910 index @@ -14138,7 +14131,7 @@ child - 6358 + 6436 @@ -14152,17 +14145,17 @@ 1 2 - 360 + 361 2 3 - 1861 + 1892 3 4 - 489 + 494 4 @@ -14183,17 +14176,17 @@ 1 2 - 360 + 361 2 3 - 1861 + 1892 3 4 - 489 + 494 4 @@ -14257,18 +14250,18 @@ 1 - 652 - 653 + 657 + 658 1 - 2513 - 2514 + 2549 + 2550 1 - 2873 - 2874 + 2910 + 2911 1 @@ -14328,18 +14321,18 @@ 1 - 652 - 653 + 657 + 658 1 - 2513 - 2514 + 2549 + 2550 1 - 2873 - 2874 + 2910 + 2911 1 @@ -14356,7 +14349,7 @@ 1 2 - 6358 + 6436 @@ -14372,7 +14365,7 @@ 1 2 - 6358 + 6436 @@ -14382,36 +14375,32 @@ ruby_left_assignment_list_def - 2873 + 2910 id - 2873 + 2910 - ruby_method_child - 264218 + ruby_method_body + 98487 ruby_method - 97351 + 98487 - index - 239 - - - child - 264218 + body + 98487 ruby_method - index + body 12 @@ -14419,80 +14408,14 @@ 1 2 - 43682 - - - 2 - 3 - 18007 - - - 3 - 4 - 12772 - - - 4 - 5 - 7790 - - - 5 - 7 - 8159 - - - 7 - 77 - 6939 + 98487 - ruby_method - child - - - 12 - - - 1 - 2 - 43682 - - - 2 - 3 - 18007 - - - 3 - 4 - 12772 - - - 4 - 5 - 7790 - - - 5 - 7 - 8159 - - - 7 - 77 - 6939 - - - - - - - index + body ruby_method @@ -14501,165 +14424,7 @@ 1 2 - 22 - - - 2 - 4 - 6 - - - 4 - 5 - 28 - - - 5 - 6 - 31 - - - 6 - 7 - 18 - - - 7 - 13 - 18 - - - 14 - 20 - 18 - - - 21 - 41 - 18 - - - 49 - 115 - 18 - - - 150 - 400 - 18 - - - 511 - 2203 - 18 - - - 3217 - 30892 - 18 - - - - - - - index - child - - - 12 - - - 1 - 2 - 22 - - - 2 - 4 - 6 - - - 4 - 5 - 28 - - - 5 - 6 - 31 - - - 6 - 7 - 18 - - - 7 - 13 - 18 - - - 14 - 20 - 18 - - - 21 - 41 - 18 - - - 49 - 115 - 18 - - - 150 - 400 - 18 - - - 511 - 2203 - 18 - - - 3217 - 30892 - 18 - - - - - - - child - ruby_method - - - 12 - - - 1 - 2 - 264218 - - - - - - - child - index - - - 12 - - - 1 - 2 - 264218 + 98487 @@ -14669,15 +14434,15 @@ ruby_method_def - 98356 + 99525 id - 98356 + 99525 name - 98356 + 99525 @@ -14691,7 +14456,7 @@ 1 2 - 98356 + 99525 @@ -14707,7 +14472,7 @@ 1 2 - 98356 + 99525 @@ -14717,15 +14482,15 @@ ruby_method_parameters - 27238 + 27765 ruby_method - 27238 + 27765 parameters - 27238 + 27765 @@ -14739,7 +14504,7 @@ 1 2 - 27238 + 27765 @@ -14755,7 +14520,7 @@ 1 2 - 27238 + 27765 @@ -14765,19 +14530,19 @@ ruby_method_parameters_child - 47287 + 48416 ruby_method_parameters - 28643 + 29203 index - 34 + 37 child - 47287 + 48416 @@ -14791,22 +14556,22 @@ 1 2 - 17310 + 17656 2 3 - 7021 + 7064 3 4 - 2678 + 2765 4 - 12 - 1632 + 13 + 1717 @@ -14822,22 +14587,22 @@ 1 2 - 17310 + 17656 2 3 - 7021 + 7064 3 4 - 2678 + 2765 4 - 12 - 1632 + 13 + 1717 @@ -14850,6 +14615,11 @@ 12 + + 1 + 2 + 3 + 3 4 @@ -14861,48 +14631,48 @@ 3 - 9 - 10 + 11 + 12 3 - 28 - 29 + 29 + 30 3 - 48 - 49 + 53 + 54 3 - 115 - 116 + 125 + 126 3 - 226 - 227 + 246 + 247 3 - 518 - 519 + 554 + 555 3 - 1368 - 1369 + 1446 + 1447 3 - 3596 - 3597 + 3725 + 3726 3 - 9089 - 9090 + 9421 + 9422 3 @@ -14916,6 +14686,11 @@ 12 + + 1 + 2 + 3 + 3 4 @@ -14927,48 +14702,48 @@ 3 - 9 - 10 + 11 + 12 3 - 28 - 29 + 29 + 30 3 - 48 - 49 + 53 + 54 3 - 115 - 116 + 125 + 126 3 - 226 - 227 + 246 + 247 3 - 518 - 519 + 554 + 555 3 - 1368 - 1369 + 1446 + 1447 3 - 3596 - 3597 + 3725 + 3726 3 - 9089 - 9090 + 9421 + 9422 3 @@ -14985,7 +14760,7 @@ 1 2 - 47287 + 48416 @@ -15001,7 +14776,7 @@ 1 2 - 47287 + 48416 @@ -15011,36 +14786,32 @@ ruby_method_parameters_def - 28861 + 29417 id - 28861 + 29417 - ruby_module_child - 31303 + ruby_module_body + 21511 ruby_module - 10513 + 21511 - index - 393 - - - child - 31303 + body + 21511 ruby_module - index + body 12 @@ -15048,70 +14819,14 @@ 1 2 - 7443 - - - 2 - 3 - 863 - - - 3 - 5 - 772 - - - 5 - 10 - 794 - - - 10 - 126 - 639 + 21511 - ruby_module - child - - - 12 - - - 1 - 2 - 7443 - - - 2 - 3 - 863 - - - 3 - 5 - 772 - - - 5 - 10 - 794 - - - 10 - 126 - 639 - - - - - - - index + body ruby_module @@ -15120,165 +14835,7 @@ 1 2 - 31 - - - 2 - 3 - 37 - - - 3 - 4 - 9 - - - 4 - 5 - 72 - - - 5 - 8 - 31 - - - 8 - 10 - 31 - - - 10 - 17 - 34 - - - 17 - 25 - 34 - - - 27 - 49 - 31 - - - 52 - 109 - 31 - - - 122 - 376 - 31 - - - 455 - 3337 - 15 - - - - - - - index - child - - - 12 - - - 1 - 2 - 31 - - - 2 - 3 - 37 - - - 3 - 4 - 9 - - - 4 - 5 - 72 - - - 5 - 8 - 31 - - - 8 - 10 - 31 - - - 10 - 17 - 34 - - - 17 - 25 - 34 - - - 27 - 49 - 31 - - - 52 - 109 - 31 - - - 122 - 376 - 31 - - - 455 - 3337 - 15 - - - - - - - child - ruby_module - - - 12 - - - 1 - 2 - 31303 - - - - - - - child - index - - - 12 - - - 1 - 2 - 31303 + 21511 @@ -15288,15 +14845,15 @@ ruby_module_def - 21557 + 21589 id - 21557 + 21589 name - 21557 + 21589 @@ -15310,7 +14867,7 @@ 1 2 - 21557 + 21589 @@ -15326,7 +14883,7 @@ 1 2 - 21557 + 21589 @@ -15336,15 +14893,15 @@ ruby_next_child - 240 + 245 ruby_next - 240 + 245 child - 240 + 245 @@ -15358,7 +14915,7 @@ 1 2 - 240 + 245 @@ -15374,7 +14931,7 @@ 1 2 - 240 + 245 @@ -15384,26 +14941,26 @@ ruby_next_def - 2005 + 2021 id - 2005 + 2021 ruby_operator_assignment_def - 6596 + 6502 id - 6596 + 6502 left - 6596 + 6502 operator @@ -15411,7 +14968,7 @@ right - 6596 + 6502 @@ -15425,7 +14982,7 @@ 1 2 - 6596 + 6502 @@ -15441,7 +14998,7 @@ 1 2 - 6596 + 6502 @@ -15457,7 +15014,7 @@ 1 2 - 6596 + 6502 @@ -15473,7 +15030,7 @@ 1 2 - 6596 + 6502 @@ -15489,7 +15046,7 @@ 1 2 - 6596 + 6502 @@ -15505,7 +15062,7 @@ 1 2 - 6596 + 6502 @@ -15534,18 +15091,18 @@ 2 - 61 - 62 + 62 + 63 2 - 592 - 593 + 594 + 595 2 - 1552 - 1553 + 1558 + 1559 2 @@ -15575,18 +15132,18 @@ 2 - 61 - 62 + 62 + 63 2 - 592 - 593 + 594 + 595 2 - 1552 - 1553 + 1558 + 1559 2 @@ -15616,18 +15173,18 @@ 2 - 61 - 62 + 62 + 63 2 - 592 - 593 + 594 + 595 2 - 1552 - 1553 + 1558 + 1559 2 @@ -15644,7 +15201,7 @@ 1 2 - 6596 + 6502 @@ -15660,7 +15217,7 @@ 1 2 - 6596 + 6502 @@ -15676,7 +15233,7 @@ 1 2 - 6596 + 6502 @@ -15686,19 +15243,19 @@ ruby_optional_parameter_def - 6435 + 6540 id - 6435 + 6540 name - 6435 + 6540 value - 6435 + 6540 @@ -15712,7 +15269,7 @@ 1 2 - 6435 + 6540 @@ -15728,7 +15285,7 @@ 1 2 - 6435 + 6540 @@ -15744,7 +15301,7 @@ 1 2 - 6435 + 6540 @@ -15760,7 +15317,7 @@ 1 2 - 6435 + 6540 @@ -15776,7 +15333,7 @@ 1 2 - 6435 + 6540 @@ -15792,7 +15349,7 @@ 1 2 - 6435 + 6540 @@ -15802,15 +15359,15 @@ ruby_pair_def - 235158 + 237637 id - 235158 + 237637 key__ - 235158 + 237637 @@ -15824,7 +15381,7 @@ 1 2 - 235158 + 237637 @@ -15840,7 +15397,7 @@ 1 2 - 235158 + 237637 @@ -15850,15 +15407,15 @@ ruby_pair_value - 235158 + 237637 ruby_pair - 235158 + 237637 value - 235158 + 237637 @@ -15872,7 +15429,7 @@ 1 2 - 235158 + 237637 @@ -15888,7 +15445,7 @@ 1 2 - 235158 + 237637 @@ -15940,11 +15497,11 @@ ruby_parenthesized_statements_child - 10272 + 10537 ruby_parenthesized_statements - 10208 + 10471 index @@ -15952,7 +15509,7 @@ child - 10272 + 10537 @@ -15966,12 +15523,12 @@ 1 2 - 10152 + 10413 2 5 - 56 + 58 @@ -15987,12 +15544,12 @@ 1 2 - 10152 + 10413 2 5 - 56 + 58 @@ -16016,13 +15573,13 @@ 1 - 56 - 57 + 58 + 59 1 - 10208 - 10209 + 10471 + 10472 1 @@ -16047,13 +15604,13 @@ 1 - 56 - 57 + 58 + 59 1 - 10208 - 10209 + 10471 + 10472 1 @@ -16070,7 +15627,7 @@ 1 2 - 10272 + 10537 @@ -16086,7 +15643,7 @@ 1 2 - 10272 + 10537 @@ -16096,26 +15653,26 @@ ruby_parenthesized_statements_def - 10247 + 10510 id - 10247 + 10510 ruby_pattern_def - 3895 + 3918 id - 3895 + 3918 child - 3895 + 3918 @@ -16129,7 +15686,7 @@ 1 2 - 3895 + 3918 @@ -16145,7 +15702,7 @@ 1 2 - 3895 + 3918 @@ -16155,19 +15712,19 @@ ruby_program_child - 33147 + 33068 ruby_program - 10456 + 10393 index - 236 + 235 child - 33147 + 33068 @@ -16181,32 +15738,32 @@ 1 2 - 3857 + 3809 2 3 - 2527 + 2513 3 4 - 1660 + 1661 4 5 - 791 + 796 5 8 - 910 + 895 8 - 76 - 709 + 77 + 716 @@ -16222,32 +15779,32 @@ 1 2 - 3857 + 3809 2 3 - 2527 + 2513 3 4 - 1660 + 1661 4 5 - 791 + 796 5 8 - 910 + 895 8 - 76 - 709 + 77 + 716 @@ -16263,7 +15820,7 @@ 1 2 - 50 + 52 2 @@ -16272,16 +15829,16 @@ 4 - 9 + 10 18 - 9 - 15 + 11 + 16 18 - 15 + 16 23 18 @@ -16291,23 +15848,23 @@ 18 - 38 - 63 + 39 + 64 18 68 - 139 + 141 18 - 157 - 515 + 159 + 521 18 - 765 - 3319 + 777 + 3354 12 @@ -16324,7 +15881,7 @@ 1 2 - 50 + 52 2 @@ -16333,16 +15890,16 @@ 4 - 9 + 10 18 - 9 - 15 + 11 + 16 18 - 15 + 16 23 18 @@ -16352,23 +15909,23 @@ 18 - 38 - 63 + 39 + 64 18 68 - 139 + 141 18 - 157 - 515 + 159 + 521 18 - 765 - 3319 + 777 + 3354 12 @@ -16385,7 +15942,7 @@ 1 2 - 33147 + 33068 @@ -16401,7 +15958,7 @@ 1 2 - 33147 + 33068 @@ -16411,26 +15968,26 @@ ruby_program_def - 17142 + 17193 id - 17142 + 17193 ruby_range_begin - 3997 + 4174 ruby_range - 3997 + 4174 begin - 3997 + 4174 @@ -16444,7 +16001,7 @@ 1 2 - 3997 + 4174 @@ -16460,7 +16017,7 @@ 1 2 - 3997 + 4174 @@ -16470,11 +16027,11 @@ ruby_range_def - 4187 + 4435 id - 4187 + 4435 operator @@ -16492,7 +16049,7 @@ 1 2 - 4187 + 4435 @@ -16506,13 +16063,13 @@ 12 - 1356 - 1357 + 1459 + 1460 1 - 2831 - 2832 + 2976 + 2977 1 @@ -16523,15 +16080,15 @@ ruby_range_end - 4070 + 4268 ruby_range - 4070 + 4268 end - 4070 + 4268 @@ -16545,7 +16102,7 @@ 1 2 - 4070 + 4268 @@ -16561,7 +16118,7 @@ 1 2 - 4070 + 4268 @@ -16571,15 +16128,15 @@ ruby_rational_def - 123 + 124 id - 123 + 124 child - 123 + 124 @@ -16593,7 +16150,7 @@ 1 2 - 123 + 124 @@ -16609,7 +16166,7 @@ 1 2 - 123 + 124 @@ -16678,19 +16235,19 @@ ruby_regex_child - 43301 + 43722 ruby_regex - 12839 + 13081 index - 154 + 151 child - 43301 + 43722 @@ -16704,42 +16261,42 @@ 1 2 - 6577 + 6732 2 3 - 696 + 712 3 4 - 1723 + 1745 4 5 - 466 + 492 5 6 - 1087 + 1094 6 8 - 1002 + 1016 8 15 - 986 + 995 15 50 - 299 + 291 @@ -16755,42 +16312,42 @@ 1 2 - 6577 + 6732 2 3 - 696 + 712 3 4 - 1723 + 1745 4 5 - 466 + 492 5 6 - 1087 + 1094 6 8 - 1002 + 1016 8 15 - 986 + 995 15 50 - 299 + 291 @@ -16830,17 +16387,17 @@ 15 - 18 + 19 12 - 18 - 22 + 19 + 23 9 - 22 - 30 + 23 + 31 12 @@ -16849,23 +16406,23 @@ 12 - 95 + 94 165 12 - 230 - 409 + 229 + 416 12 - 645 - 1220 + 658 + 1256 12 - 1766 - 4075 + 1818 + 4221 9 @@ -16906,17 +16463,17 @@ 15 - 18 + 19 12 - 18 - 22 + 19 + 23 9 - 22 - 30 + 23 + 31 12 @@ -16925,23 +16482,23 @@ 12 - 95 + 94 165 12 - 230 - 409 + 229 + 416 12 - 645 - 1220 + 658 + 1256 12 - 1766 - 4075 + 1818 + 4221 9 @@ -16958,7 +16515,7 @@ 1 2 - 43301 + 43722 @@ -16974,7 +16531,7 @@ 1 2 - 43301 + 43722 @@ -16984,26 +16541,26 @@ ruby_regex_def - 12854 + 13096 id - 12854 + 13096 ruby_rescue_body - 1767 + 1762 ruby_rescue - 1767 + 1762 body - 1767 + 1762 @@ -17017,7 +16574,7 @@ 1 2 - 1767 + 1762 @@ -17033,7 +16590,7 @@ 1 2 - 1767 + 1762 @@ -17043,26 +16600,26 @@ ruby_rescue_def - 2061 + 2085 id - 2061 + 2085 ruby_rescue_exceptions - 1639 + 1654 ruby_rescue - 1639 + 1654 exceptions - 1639 + 1654 @@ -17076,7 +16633,7 @@ 1 2 - 1639 + 1654 @@ -17092,7 +16649,7 @@ 1 2 - 1639 + 1654 @@ -17102,19 +16659,19 @@ ruby_rescue_modifier_def - 525 + 519 id - 525 + 519 body - 525 + 519 handler - 525 + 519 @@ -17128,7 +16685,7 @@ 1 2 - 525 + 519 @@ -17144,7 +16701,7 @@ 1 2 - 525 + 519 @@ -17160,7 +16717,7 @@ 1 2 - 525 + 519 @@ -17176,7 +16733,7 @@ 1 2 - 525 + 519 @@ -17192,7 +16749,7 @@ 1 2 - 525 + 519 @@ -17208,7 +16765,7 @@ 1 2 - 525 + 519 @@ -17218,15 +16775,15 @@ ruby_rescue_variable - 1001 + 991 ruby_rescue - 1001 + 991 variable - 1001 + 991 @@ -17240,7 +16797,7 @@ 1 2 - 1001 + 991 @@ -17256,7 +16813,7 @@ 1 2 - 1001 + 991 @@ -17314,11 +16871,11 @@ ruby_rest_assignment_def - 398 + 399 id - 398 + 399 @@ -17373,26 +16930,26 @@ ruby_retry_def - 56 + 59 id - 56 + 59 ruby_return_child - 5336 + 5330 ruby_return - 5336 + 5330 child - 5336 + 5330 @@ -17406,7 +16963,7 @@ 1 2 - 5336 + 5330 @@ -17422,7 +16979,7 @@ 1 2 - 5336 + 5330 @@ -17432,22 +16989,22 @@ ruby_return_def - 8495 + 8486 id - 8495 + 8486 ruby_right_assignment_list_child - 2757 + 2721 ruby_right_assignment_list - 1288 + 1274 index @@ -17455,7 +17012,7 @@ child - 2757 + 2721 @@ -17469,17 +17026,17 @@ 2 3 - 1147 + 1134 3 4 - 110 + 111 4 6 - 31 + 27 @@ -17495,17 +17052,17 @@ 2 3 - 1147 + 1134 3 4 - 110 + 111 4 6 - 31 + 27 @@ -17524,8 +17081,8 @@ 3 - 10 - 11 + 9 + 10 3 @@ -17534,8 +17091,8 @@ 3 - 409 - 410 + 411 + 412 6 @@ -17555,8 +17112,8 @@ 3 - 10 - 11 + 9 + 10 3 @@ -17565,8 +17122,8 @@ 3 - 409 - 410 + 411 + 412 6 @@ -17583,7 +17140,7 @@ 1 2 - 2757 + 2721 @@ -17599,7 +17156,7 @@ 1 2 - 2757 + 2721 @@ -17609,26 +17166,26 @@ ruby_right_assignment_list_def - 1288 + 1274 id - 1288 + 1274 ruby_scope_resolution_def - 80009 + 81024 id - 80009 + 81024 name - 80009 + 81024 @@ -17642,7 +17199,7 @@ 1 2 - 80009 + 81024 @@ -17658,7 +17215,7 @@ 1 2 - 80009 + 81024 @@ -17668,15 +17225,15 @@ ruby_scope_resolution_scope - 78256 + 79203 ruby_scope_resolution - 78256 + 79203 scope - 78256 + 79203 @@ -17690,7 +17247,7 @@ 1 2 - 78256 + 79203 @@ -17706,7 +17263,7 @@ 1 2 - 78256 + 79203 @@ -17716,15 +17273,15 @@ ruby_setter_def - 598 + 601 id - 598 + 601 name - 598 + 601 @@ -17738,7 +17295,7 @@ 1 2 - 598 + 601 @@ -17754,7 +17311,7 @@ 1 2 - 598 + 601 @@ -17763,26 +17320,22 @@ - ruby_singleton_class_child - 2322 + ruby_singleton_class_body + 635 ruby_singleton_class - 620 + 635 - index - 72 - - - child - 2322 + body + 635 ruby_singleton_class - index + body 12 @@ -17790,100 +17343,14 @@ 1 2 - 283 - - - 2 - 3 - 81 - - - 3 - 4 - 40 - - - 4 - 5 - 40 - - - 5 - 6 - 40 - - - 6 - 8 - 44 - - - 8 - 13 - 53 - - - 13 - 24 - 34 + 635 - ruby_singleton_class - child - - - 12 - - - 1 - 2 - 283 - - - 2 - 3 - 81 - - - 3 - 4 - 40 - - - 4 - 5 - 40 - - - 5 - 6 - 40 - - - 6 - 8 - 44 - - - 8 - 13 - 53 - - - 13 - 24 - 34 - - - - - - - index + body ruby_singleton_class @@ -17892,155 +17359,7 @@ 1 2 - 3 - - - 2 - 3 - 9 - - - 3 - 4 - 9 - - - 6 - 8 - 6 - - - 9 - 12 - 6 - - - 16 - 20 - 6 - - - 21 - 23 - 6 - - - 28 - 33 - 6 - - - 42 - 56 - 6 - - - 68 - 82 - 6 - - - 107 - 198 - 6 - - - - - - - index - child - - - 12 - - - 1 - 2 - 3 - - - 2 - 3 - 9 - - - 3 - 4 - 9 - - - 6 - 8 - 6 - - - 9 - 12 - 6 - - - 16 - 20 - 6 - - - 21 - 23 - 6 - - - 28 - 33 - 6 - - - 42 - 56 - 6 - - - 68 - 82 - 6 - - - 107 - 198 - 6 - - - - - - - child - ruby_singleton_class - - - 12 - - - 1 - 2 - 2322 - - - - - - - child - index - - - 12 - - - 1 - 2 - 2322 + 635 @@ -18050,15 +17369,15 @@ ruby_singleton_class_def - 620 + 635 id - 620 + 635 value - 620 + 635 @@ -18072,7 +17391,7 @@ 1 2 - 620 + 635 @@ -18088,7 +17407,7 @@ 1 2 - 620 + 635 @@ -18097,26 +17416,22 @@ - ruby_singleton_method_child - 16018 + ruby_singleton_method_body + 6677 ruby_singleton_method - 6539 + 6677 - index - 89 - - - child - 16018 + body + 6677 ruby_singleton_method - index + body 12 @@ -18124,80 +17439,14 @@ 1 2 - 3714 - - - 2 - 3 - 965 - - - 3 - 4 - 612 - - - 4 - 5 - 374 - - - 5 - 8 - 505 - - - 8 - 31 - 368 + 6677 - ruby_singleton_method - child - - - 12 - - - 1 - 2 - 3714 - - - 2 - 3 - 965 - - - 3 - 4 - 612 - - - 4 - 5 - 374 - - - 5 - 8 - 505 - - - 8 - 31 - 368 - - - - - - - index + body ruby_singleton_method @@ -18206,195 +17455,7 @@ 1 2 - 2 - - - 2 - 3 - 11 - - - 3 - 4 - 5 - - - 4 - 5 - 2 - - - 5 - 6 - 8 - - - 9 - 10 - 5 - - - 12 - 17 - 5 - - - 23 - 28 - 5 - - - 32 - 41 - 5 - - - 51 - 66 - 5 - - - 93 - 125 - 5 - - - 155 - 210 - 5 - - - 294 - 421 - 5 - - - 626 - 952 - 5 - - - 2201 - 2202 - 2 - - - - - - - index - child - - - 12 - - - 1 - 2 - 2 - - - 2 - 3 - 11 - - - 3 - 4 - 5 - - - 4 - 5 - 2 - - - 5 - 6 - 8 - - - 9 - 10 - 5 - - - 12 - 17 - 5 - - - 23 - 28 - 5 - - - 32 - 41 - 5 - - - 51 - 66 - 5 - - - 93 - 125 - 5 - - - 155 - 210 - 5 - - - 294 - 421 - 5 - - - 626 - 952 - 5 - - - 2201 - 2202 - 2 - - - - - - - child - ruby_singleton_method - - - 12 - - - 1 - 2 - 16018 - - - - - - - child - index - - - 12 - - - 1 - 2 - 16018 + 6677 @@ -18404,19 +17465,19 @@ ruby_singleton_method_def - 6539 + 6692 id - 6539 + 6692 name - 6539 + 6692 object - 6539 + 6692 @@ -18430,7 +17491,7 @@ 1 2 - 6539 + 6692 @@ -18446,7 +17507,7 @@ 1 2 - 6539 + 6692 @@ -18462,7 +17523,7 @@ 1 2 - 6539 + 6692 @@ -18478,7 +17539,7 @@ 1 2 - 6539 + 6692 @@ -18494,7 +17555,7 @@ 1 2 - 6539 + 6692 @@ -18510,7 +17571,7 @@ 1 2 - 6539 + 6692 @@ -18520,15 +17581,15 @@ ruby_singleton_method_parameters - 4082 + 4183 ruby_singleton_method - 4082 + 4183 parameters - 4082 + 4183 @@ -18542,7 +17603,7 @@ 1 2 - 4082 + 4183 @@ -18558,7 +17619,7 @@ 1 2 - 4082 + 4183 @@ -18568,15 +17629,15 @@ ruby_splat_argument_def - 3046 + 3093 id - 3046 + 3093 child - 3046 + 3093 @@ -18590,7 +17651,7 @@ 1 2 - 3046 + 3093 @@ -18606,7 +17667,7 @@ 1 2 - 3046 + 3093 @@ -18616,26 +17677,26 @@ ruby_splat_parameter_def - 2905 + 2978 id - 2905 + 2978 ruby_splat_parameter_name - 2354 + 2383 ruby_splat_parameter - 2354 + 2383 name - 2354 + 2383 @@ -18649,7 +17710,7 @@ 1 2 - 2354 + 2383 @@ -18665,7 +17726,7 @@ 1 2 - 2354 + 2383 @@ -18675,11 +17736,11 @@ ruby_string_array_child - 11487 + 11622 ruby_string_array - 3704 + 3773 index @@ -18687,7 +17748,7 @@ child - 11487 + 11622 @@ -18701,27 +17762,27 @@ 1 2 - 1200 + 1222 2 3 - 1218 + 1256 3 4 - 576 + 581 4 5 - 294 + 296 5 10 - 282 + 284 10 @@ -18742,27 +17803,27 @@ 1 2 - 1200 + 1222 2 3 - 1218 + 1256 3 4 - 576 + 581 4 5 - 294 + 296 5 10 - 282 + 284 10 @@ -18792,12 +17853,12 @@ 17 - 417 + 419 35 - 710 - 3705 + 714 + 3774 4 @@ -18823,12 +17884,12 @@ 17 - 417 + 419 35 - 710 - 3705 + 714 + 3774 4 @@ -18845,7 +17906,7 @@ 1 2 - 11487 + 11622 @@ -18861,7 +17922,7 @@ 1 2 - 11487 + 11622 @@ -18871,22 +17932,22 @@ ruby_string_array_def - 3840 + 3913 id - 3840 + 3913 ruby_string_child - 534498 + 538306 ruby_string__ - 466613 + 469399 index @@ -18894,7 +17955,7 @@ child - 534498 + 538306 @@ -18908,12 +17969,12 @@ 1 2 - 439982 + 442362 2 282 - 26631 + 27037 @@ -18929,12 +17990,12 @@ 1 2 - 439982 + 442362 2 282 - 26631 + 27037 @@ -18974,7 +18035,7 @@ 102 - 466614 + 469400 22 @@ -19015,7 +18076,7 @@ 102 - 466614 + 469400 22 @@ -19032,7 +18093,7 @@ 1 2 - 534498 + 538306 @@ -19048,7 +18109,7 @@ 1 2 - 534498 + 538306 @@ -19058,22 +18119,22 @@ ruby_string_def - 473533 + 476418 id - 473533 + 476418 ruby_subshell_child - 620 + 604 ruby_subshell - 403 + 393 index @@ -19081,7 +18142,7 @@ child - 620 + 604 @@ -19095,22 +18156,22 @@ 1 2 - 296 + 288 2 3 - 59 + 58 3 4 - 18 + 21 4 12 - 28 + 24 @@ -19126,22 +18187,22 @@ 1 2 - 296 + 288 2 3 - 59 + 58 3 4 - 18 + 21 4 12 - 28 + 24 @@ -19170,8 +18231,8 @@ 3 - 9 - 10 + 8 + 9 3 @@ -19185,8 +18246,8 @@ 3 - 128 - 129 + 127 + 128 3 @@ -19216,8 +18277,8 @@ 3 - 9 - 10 + 8 + 9 3 @@ -19231,8 +18292,8 @@ 3 - 128 - 129 + 127 + 128 3 @@ -19249,7 +18310,7 @@ 1 2 - 620 + 604 @@ -19265,7 +18326,7 @@ 1 2 - 620 + 604 @@ -19275,26 +18336,26 @@ ruby_subshell_def - 403 + 393 id - 403 + 393 ruby_superclass_def - 13318 + 13378 id - 13318 + 13378 child - 13318 + 13378 @@ -19308,7 +18369,7 @@ 1 2 - 13318 + 13378 @@ -19324,7 +18385,7 @@ 1 2 - 13318 + 13378 @@ -19334,19 +18395,19 @@ ruby_symbol_array_child - 2106 + 2085 ruby_symbol_array - 463 + 460 index - 98 + 96 child - 2106 + 2085 @@ -19360,17 +18421,17 @@ 1 2 - 184 + 180 2 3 - 92 + 93 3 4 - 38 + 40 4 @@ -19385,12 +18446,12 @@ 8 13 - 38 + 37 13 22 - 38 + 37 27 @@ -19411,17 +18472,17 @@ 1 2 - 184 + 180 2 3 - 92 + 93 3 4 - 38 + 40 4 @@ -19436,12 +18497,12 @@ 8 13 - 38 + 37 13 22 - 38 + 37 27 @@ -19462,12 +18523,12 @@ 1 2 - 11 + 8 2 3 - 5 + 8 3 @@ -19505,8 +18566,8 @@ 8 - 63 - 157 + 64 + 159 8 @@ -19523,12 +18584,12 @@ 1 2 - 11 + 8 2 3 - 5 + 8 3 @@ -19566,8 +18627,8 @@ 8 - 63 - 157 + 64 + 159 8 @@ -19584,7 +18645,7 @@ 1 2 - 2106 + 2085 @@ -19600,7 +18661,7 @@ 1 2 - 2106 + 2085 @@ -19610,30 +18671,30 @@ ruby_symbol_array_def - 463 + 460 id - 463 + 460 ruby_then_child - 41375 + 40747 ruby_then - 24329 + 24194 index - 288 + 105 child - 41375 + 40747 @@ -19647,22 +18708,22 @@ 1 2 - 15210 + 15103 2 3 - 5479 + 5505 3 4 - 2011 + 1954 4 - 98 - 1628 + 37 + 1630 @@ -19678,22 +18739,22 @@ 1 2 - 15210 + 15103 2 3 - 5479 + 5505 3 4 - 2011 + 1954 4 - 98 - 1628 + 37 + 1630 @@ -19709,33 +18770,48 @@ 1 2 - 184 + 35 2 4 - 20 + 8 4 - 7 - 20 - - - 7 - 12 - 23 - - - 12 - 157 - 23 - - - 292 - 8189 + 5 14 + + 6 + 10 + 8 + + + 10 + 20 + 8 + + + 30 + 59 + 8 + + + 91 + 293 + 8 + + + 559 + 3117 + 8 + + + 8293 + 8294 + 2 + @@ -19750,33 +18826,48 @@ 1 2 - 184 + 35 2 4 - 20 + 8 4 - 7 - 20 - - - 7 - 12 - 23 - - - 12 - 157 - 23 - - - 292 - 8189 + 5 14 + + 6 + 10 + 8 + + + 10 + 20 + 8 + + + 30 + 59 + 8 + + + 91 + 293 + 8 + + + 559 + 3117 + 8 + + + 8293 + 8294 + 2 + @@ -19791,7 +18882,7 @@ 1 2 - 41375 + 40747 @@ -19807,7 +18898,7 @@ 1 2 - 41375 + 40747 @@ -19817,30 +18908,30 @@ ruby_then_def - 24329 + 24194 id - 24329 + 24194 ruby_tokeninfo - 5932219 + 5993849 id - 5932219 + 5993849 kind - 65 + 64 value - 268924 + 272090 @@ -19854,7 +18945,7 @@ 1 2 - 5932219 + 5993849 @@ -19870,7 +18961,7 @@ 1 2 - 5932219 + 5993849 @@ -19884,65 +18975,65 @@ 12 - 36 - 154 + 38 + 162 5 - 218 + 229 427 5 - 1610 - 1611 + 1651 + 1652 2 - 1805 - 1806 + 1892 + 1893 5 - 3990 - 4222 - 5 - - - 4225 - 5692 - 5 - - - 7841 - 9805 - 5 - - - 13552 - 17172 - 5 - - - 25328 - 54391 - 5 - - - 55573 - 79435 - 5 - - - 95059 - 499129 - 5 - - - 1115017 - 1115018 + 4175 + 4176 2 + + 4361 + 4362 + 5 + + + 5941 + 8156 + 5 + + + 9961 + 13707 + 5 + + + 17937 + 25691 + 5 + + + 55821 + 57168 + 5 + + + 82456 + 97584 + 5 + + + 513548 + 1147355 + 5 + @@ -19961,47 +19052,47 @@ 5 - 22 + 24 5 25 - 30 + 32 5 - 69 - 123 + 71 + 122 5 - 123 + 124 148 5 - 1480 - 1754 + 1483 + 1800 5 - 3052 - 3730 + 3157 + 3799 5 - 4632 - 7672 + 4735 + 7872 5 - 10019 - 18637 + 10529 + 19137 5 - 44586 - 44587 + 45798 + 45799 2 @@ -20018,32 +19109,32 @@ 1 2 - 159668 + 162126 2 3 - 39566 + 39738 3 4 - 18844 + 18995 4 7 - 22228 + 22513 7 27 - 20374 + 20459 27 - 183191 - 8242 + 189123 + 8256 @@ -20059,12 +19150,12 @@ 1 2 - 255594 + 259066 2 5 - 13329 + 13023 @@ -20074,15 +19165,15 @@ ruby_unary_def - 13057 + 13450 id - 13057 + 13450 operand - 13057 + 13450 operator @@ -20100,7 +19191,7 @@ 1 2 - 13057 + 13450 @@ -20116,7 +19207,7 @@ 1 2 - 13057 + 13450 @@ -20132,7 +19223,7 @@ 1 2 - 13057 + 13450 @@ -20148,7 +19239,7 @@ 1 2 - 13057 + 13450 @@ -20162,33 +19253,33 @@ 12 - 88 - 89 + 89 + 90 1 - 236 - 237 + 190 + 191 1 - 557 - 558 + 559 + 560 1 - 1312 - 1313 + 1320 + 1321 1 - 1742 - 1743 + 1820 + 1821 1 - 9122 - 9123 + 9472 + 9473 1 @@ -20203,33 +19294,33 @@ 12 - 88 - 89 + 89 + 90 1 - 236 - 237 + 190 + 191 1 - 557 - 558 + 559 + 560 1 - 1312 - 1313 + 1320 + 1321 1 - 1742 - 1743 + 1820 + 1821 1 - 9122 - 9123 + 9472 + 9473 1 @@ -20240,11 +19331,11 @@ ruby_undef_child - 181 + 182 ruby_undef - 180 + 181 index @@ -20252,7 +19343,7 @@ child - 181 + 182 @@ -20266,7 +19357,7 @@ 1 2 - 179 + 180 2 @@ -20287,7 +19378,7 @@ 1 2 - 179 + 180 2 @@ -20311,8 +19402,8 @@ 1 - 180 - 181 + 181 + 182 1 @@ -20332,8 +19423,8 @@ 1 - 180 - 181 + 181 + 182 1 @@ -20350,7 +19441,7 @@ 1 2 - 181 + 182 @@ -20366,7 +19457,7 @@ 1 2 - 181 + 182 @@ -20376,11 +19467,11 @@ ruby_undef_def - 180 + 181 id - 180 + 181 @@ -20435,15 +19526,15 @@ ruby_unless_consequence - 2575 + 2593 ruby_unless - 2575 + 2593 consequence - 2575 + 2593 @@ -20457,7 +19548,7 @@ 1 2 - 2575 + 2593 @@ -20473,7 +19564,7 @@ 1 2 - 2575 + 2593 @@ -20483,15 +19574,15 @@ ruby_unless_def - 2578 + 2594 id - 2578 + 2594 condition - 2578 + 2594 @@ -20505,7 +19596,7 @@ 1 2 - 2578 + 2594 @@ -20521,7 +19612,7 @@ 1 2 - 2578 + 2594 @@ -20573,19 +19664,19 @@ ruby_unless_modifier_def - 4207 + 4163 id - 4207 + 4163 body - 4207 + 4163 condition - 4207 + 4163 @@ -20599,7 +19690,7 @@ 1 2 - 4207 + 4163 @@ -20615,7 +19706,7 @@ 1 2 - 4207 + 4163 @@ -20631,7 +19722,7 @@ 1 2 - 4207 + 4163 @@ -20647,7 +19738,7 @@ 1 2 - 4207 + 4163 @@ -20663,7 +19754,7 @@ 1 2 - 4207 + 4163 @@ -20679,7 +19770,7 @@ 1 2 - 4207 + 4163 @@ -20689,19 +19780,19 @@ ruby_until_def - 113 + 121 id - 113 + 121 body - 113 + 121 condition - 113 + 121 @@ -20715,7 +19806,7 @@ 1 2 - 113 + 121 @@ -20731,7 +19822,7 @@ 1 2 - 113 + 121 @@ -20747,7 +19838,7 @@ 1 2 - 113 + 121 @@ -20763,7 +19854,7 @@ 1 2 - 113 + 121 @@ -20779,7 +19870,7 @@ 1 2 - 113 + 121 @@ -20795,7 +19886,7 @@ 1 2 - 113 + 121 @@ -20805,19 +19896,19 @@ ruby_until_modifier_def - 206 + 223 id - 206 + 223 body - 206 + 223 condition - 206 + 223 @@ -20831,7 +19922,7 @@ 1 2 - 206 + 223 @@ -20847,7 +19938,7 @@ 1 2 - 206 + 223 @@ -20863,7 +19954,7 @@ 1 2 - 206 + 223 @@ -20879,7 +19970,7 @@ 1 2 - 206 + 223 @@ -20895,7 +19986,7 @@ 1 2 - 206 + 223 @@ -20911,7 +20002,7 @@ 1 2 - 206 + 223 @@ -20963,15 +20054,15 @@ ruby_when_body - 3208 + 3211 ruby_when - 3208 + 3211 body - 3208 + 3211 @@ -20985,7 +20076,7 @@ 1 2 - 3208 + 3211 @@ -21001,7 +20092,7 @@ 1 2 - 3208 + 3211 @@ -21011,30 +20102,30 @@ ruby_when_def - 3239 + 3248 id - 3239 + 3248 ruby_when_pattern - 3895 + 3918 ruby_when - 3239 + 3248 index - 44 + 43 pattern - 3895 + 3918 @@ -21053,12 +20144,12 @@ 2 3 - 305 + 309 3 15 - 103 + 108 @@ -21079,12 +20170,12 @@ 2 3 - 305 + 309 3 15 - 103 + 108 @@ -21118,23 +20209,23 @@ 3 - 12 - 13 + 13 + 14 3 - 33 - 34 + 35 + 36 3 - 130 - 131 + 135 + 136 3 - 1028 - 1029 + 1048 + 1049 3 @@ -21169,23 +20260,23 @@ 3 - 12 - 13 + 13 + 14 3 - 33 - 34 + 35 + 36 3 - 130 - 131 + 135 + 136 3 - 1028 - 1029 + 1048 + 1049 3 @@ -21202,7 +20293,7 @@ 1 2 - 3895 + 3918 @@ -21218,7 +20309,7 @@ 1 2 - 3895 + 3918 @@ -21228,19 +20319,19 @@ ruby_while_def - 1335 + 1349 id - 1335 + 1349 body - 1335 + 1349 condition - 1335 + 1349 @@ -21254,7 +20345,7 @@ 1 2 - 1335 + 1349 @@ -21270,7 +20361,7 @@ 1 2 - 1335 + 1349 @@ -21286,7 +20377,7 @@ 1 2 - 1335 + 1349 @@ -21302,7 +20393,7 @@ 1 2 - 1335 + 1349 @@ -21318,7 +20409,7 @@ 1 2 - 1335 + 1349 @@ -21334,7 +20425,7 @@ 1 2 - 1335 + 1349 @@ -21344,19 +20435,19 @@ ruby_while_modifier_def - 179 + 190 id - 179 + 190 body - 179 + 190 condition - 179 + 190 @@ -21370,7 +20461,7 @@ 1 2 - 179 + 190 @@ -21386,7 +20477,7 @@ 1 2 - 179 + 190 @@ -21402,7 +20493,7 @@ 1 2 - 179 + 190 @@ -21418,7 +20509,7 @@ 1 2 - 179 + 190 @@ -21434,7 +20525,7 @@ 1 2 - 179 + 190 @@ -21450,7 +20541,7 @@ 1 2 - 179 + 190 @@ -21460,15 +20551,15 @@ ruby_yield_child - 1112 + 1097 ruby_yield - 1112 + 1097 child - 1112 + 1097 @@ -21482,7 +20573,7 @@ 1 2 - 1112 + 1097 @@ -21498,7 +20589,7 @@ 1 2 - 1112 + 1097 @@ -21508,22 +20599,22 @@ ruby_yield_def - 2385 + 2389 id - 2385 + 2389 sourceLocationPrefix - 12 + 13 prefix - 12 + 13 From b51c6d665109e725fb89e1e713a2bce383280817 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 25 Aug 2022 16:40:50 -0700 Subject: [PATCH 024/203] Fixes based on PR feedback --- .../JsonWebTokenHandlerLib.qll | 34 ++++++++----------- ...security-validations-always-return-true.ql | 3 +- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index f976556534e..316eff287d9 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -6,12 +6,11 @@ import DataFlow */ class TokenValidationParametersPropertySensitiveValidation extends Property { TokenValidationParametersPropertySensitiveValidation() { - exists(Property p, Class c | + exists(Class c | c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") | - p = this and - c.getAProperty() = p and - p.getName() in [ + c.getAProperty() = this and + this.getName() in [ "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", "RequireAudience" ] @@ -34,8 +33,8 @@ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation override predicate isSink(DataFlow::Node sink) { exists(Assignment a | - sink.asExpr() = a.getRValue() and - a.getLValue().(PropertyAccess).getProperty() instanceof TokenValidationParametersPropertySensitiveValidation + sink.asExpr() = + any(TokenValidationParametersPropertySensitiveValidation p).getAnAssignedValue() ) } } @@ -106,12 +105,11 @@ private class FlowsToTokenValidationResultIsValidCall extends DataFlow::Configur */ class TokenValidationParametersProperty extends Property { TokenValidationParametersProperty() { - exists(Property p, Class c | + exists(Class c | c.hasQualifiedName("Microsoft.IdentityModel.Tokens.TokenValidationParameters") | - p = this and - c.getAProperty() = p and - p.getName() in [ + c.getAProperty() = this and + this.getName() in [ "SignatureValidator", "TokenReplayValidator", "AlgorithmValidator", "AudienceValidator", "IssuerSigningKeyValidator", "LifetimeValidator" ] @@ -153,9 +151,7 @@ class CallableAlwaysReturnsTrue extends Callable { or lambdaExprReturnsOnlyLiteralTrue(this) or - exists(AnonymousFunctionExpr le, Call call, Callable callable | - this = le - | + exists(AnonymousFunctionExpr le, Call call, Callable callable | this = le | callable.getACall() = call and call = le.getExpressionBody() and callableHasAReturnStmtAndAlwaysReturnsTrue(callable) @@ -231,13 +227,13 @@ class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsStri class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString { CallableAlwaysReturnsParameter0MayThrowExceptions() { forex(Expr ret | this.canReturn(ret) | - ret = this.getParameter(0).getAnAccess() - or - exists(CallableAlwaysReturnsParameter0MayThrowExceptions c | - ret = c.getACall() and - ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() + ret = this.getParameter(0).getAnAccess() + or + exists(CallableAlwaysReturnsParameter0MayThrowExceptions c | + ret = c.getACall() and + ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() + ) ) - ) } } diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 39220e3cddf..5ec9e574202 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -15,8 +15,7 @@ import csharp import DataFlow import JsonWebTokenHandlerLib -from - TokenValidationParametersProperty p , CallableAlwaysReturnsTrueHigherPrecision e +from TokenValidationParametersProperty p, CallableAlwaysReturnsTrueHigherPrecision e where e = p.getAnAssignedValue() select e, "JsonWebTokenHandler security-sensitive property $@ is being delegated to $@.", p, p.getQualifiedName().toString(), e, "a callable that always returns \"true\"" From b5c54f5a3b83adc126badd7d540af3db06cb1356 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 30 Aug 2022 12:53:12 -0400 Subject: [PATCH 025/203] Add check for android:allowBackup explicitly set `android:allowBackup` has a default value of `true`. So we want to flag any file which explicitly sets it. --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index 7911b1a8518..f795e91163b 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -85,6 +85,19 @@ class AndroidApplicationXmlElement extends XmlElement { attr.getValue() = "false" ) } + + /** + * Holds if this application element sets the `android:allowBackup` attribute to `true`. + * + * https://developer.android.com/guide/topics/data/autobackup + */ + predicate allowsBackupExplicitly() { + exists(AndroidXmlAttribute attr | + this.getAnAttribute() = attr and + attr.getName() = "allowBackup" and + attr.getValue() = "true" + ) + } } /** From 500a6f3b8656ef2d982ae8cdd1e77db5036d44b9 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 30 Aug 2022 12:54:26 -0400 Subject: [PATCH 026/203] Add check for files which provide the app launcher Adds support for filtering which applications include the `android.intent.action.MAIN` intent. --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 10 ++++++++++ .../CWE/CWE-312/AllowBackupAttributeEnabled.ql | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index f795e91163b..c79a5d5c10f 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -98,6 +98,16 @@ class AndroidApplicationXmlElement extends XmlElement { attr.getValue() = "true" ) } + + predicate providesMainIntent() { + exists(AndroidActivityXmlElement activity | + activity = this.getAChild() and + exists(AndroidIntentFilterXmlElement intentFilter | + intentFilter = activity.getAChild() and + intentFilter.getAnActionElement().getActionName() = "android.intent.action.MAIN" + ) + ) + } } /** diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 6e015c7a237..e8bd3487b00 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -15,6 +15,11 @@ import semmle.code.xml.AndroidManifest from AndroidApplicationXmlElement androidAppElem where - androidAppElem.allowsBackup() and - androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() + not androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() and + ( + androidAppElem.allowsBackupExplicitly() + or + androidAppElem.providesMainIntent() and + androidAppElem.allowsBackup() + ) select androidAppElem, "The 'android:allowBackup' attribute is enabled." From 6485e73cd3a0f375ce5be1b8a9cc012251c10c97 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 30 Aug 2022 13:00:44 -0400 Subject: [PATCH 027/203] Added documentation for `providesMainIntent` pred --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index c79a5d5c10f..155213212fc 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -99,6 +99,10 @@ class AndroidApplicationXmlElement extends XmlElement { ) } + /** + * Holds if the application element contains a child element which provides the + * `android.intent.action.MAIN` intent. + */ predicate providesMainIntent() { exists(AndroidActivityXmlElement activity | activity = this.getAChild() and From 476562ec62abdd148d60c46dce7d51c2aad31440 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 31 Aug 2022 12:32:47 -0700 Subject: [PATCH 028/203] Fixes based on the PR comments --- .../JsonWebTokenHandler/JsonWebTokenHandlerLib.qll | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll index 316eff287d9..5f0b823d09c 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll @@ -32,10 +32,7 @@ class FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation } override predicate isSink(DataFlow::Node sink) { - exists(Assignment a | - sink.asExpr() = - any(TokenValidationParametersPropertySensitiveValidation p).getAnAssignedValue() - ) + sink.asExpr() = any(TokenValidationParametersPropertySensitiveValidation p).getAnAssignedValue() } } @@ -245,7 +242,7 @@ class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsS predicate isExpressionAlwaysTrue(Expr e) { e.(BoolLiteral).getBoolValue() = true or - e.(Expr).getValue() = "true" + e.getValue() = "true" or e instanceof ConditionalExpr and isExpressionAlwaysTrue(e.(ConditionalExpr).getThen()) and From 0b0777addfef63e86f5b8439e1ae1c1baa3aed2c Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 1 Sep 2022 09:45:11 -0700 Subject: [PATCH 029/203] Fixing the @id fields --- .../delegated-security-validations-always-return-true.ql | 2 +- .../JsonWebTokenHandler/security-validation-disabled.ql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql index 5ec9e574202..57561944718 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql @@ -6,7 +6,7 @@ * @tags security * JsonWebTokenHandler * manual-verification-required - * @id cs/JsonWebTokenHandler/delegated-security-validations-always-return-true + * @id cs/json-webtoken-handler/delegated-security-validations-always-return-true * @problem.severity error * @precision high */ diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql index 15a8813171d..cfc745e5314 100644 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql @@ -5,7 +5,7 @@ * @tags security * JsonWebTokenHandler * manual-verification-required - * @id cs/JsonWebTokenHandler/security-validations-disabled + * @id cs/json-webtoken-handler/security-validations-disabled * @problem.severity error * @precision high */ From 93fcaf24c19edb8c855eb8c3d730c274e19cf326 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Sep 2022 21:45:57 +0200 Subject: [PATCH 030/203] python: `RaisingTuple.ql` to not use `poins-to` Use local dataflow instead and simply check for tuple literals. --- python/ql/src/Exceptions/RaisingTuple.ql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/ql/src/Exceptions/RaisingTuple.ql b/python/ql/src/Exceptions/RaisingTuple.ql index abfe785e9cb..9116430ac18 100644 --- a/python/ql/src/Exceptions/RaisingTuple.ql +++ b/python/ql/src/Exceptions/RaisingTuple.ql @@ -10,11 +10,14 @@ */ import python +import semmle.python.dataflow.new.DataFlow -from Raise r, Value v, AstNode origin +from Raise r, DataFlow::LocalSourceNode origin where - r.getException().pointsTo(v, origin) and - v.getClass() = ClassValue::tuple() and + exists(DataFlow::Node exception | exception.asExpr() = r.getException() | + origin.flowsTo(exception) + ) and + origin.asExpr() instanceof Tuple and major_version() = 2 /* Raising a tuple is a type error in Python 3, so is handled by the IllegalRaise query. */ select r, From 163bfc4f71364d42dbebffdd9ef64fe196fb459f Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Sep 2022 22:47:32 +0200 Subject: [PATCH 031/203] python: replace `points-to` with API graph - values are identified via `API::builtin` - `points-to` is approximated by `getAValueReachableFromSource` --- .../ql/src/Exceptions/UnguardedNextInGenerator.ql | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql index 0ff11dfd5b0..d4007facb9c 100644 --- a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql +++ b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql @@ -11,17 +11,22 @@ */ import python +private import semmle.python.ApiGraphs -FunctionValue iter() { result = Value::named("iter") } +API::Node iter() { result = API::builtin("iter") } -BuiltinFunctionValue next() { result = Value::named("next") } +API::Node next() { result = API::builtin("next") } + +API::Node stopIteration() { result = API::builtin("StopIteration") } predicate call_to_iter(CallNode call, EssaVariable sequence) { - sequence.getAUse() = iter().getArgumentForCall(call, 0) + call = iter().getACall().asCfgNode() and + call.getArg(0) = sequence.getAUse() } predicate call_to_next(CallNode call, ControlFlowNode iter) { - iter = next().getArgumentForCall(call, 0) + call = next().getACall().asCfgNode() and + call.getArg(0) = iter } predicate call_to_next_has_default(CallNode call) { @@ -47,7 +52,7 @@ predicate iter_not_exhausted(EssaVariable iterator) { predicate stop_iteration_handled(CallNode call) { exists(Try t | t.containsInScope(call.getNode()) and - t.getAHandler().getType().pointsTo(ClassValue::stopIteration()) + t.getAHandler().getType() = stopIteration().getAValueReachableFromSource().asExpr() ) } From d102a84e0201f63bee39ddacdab97f8193e8d0ac Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Sep 2022 22:58:46 +0200 Subject: [PATCH 032/203] python: replace `points-to` with API graph --- python/ql/src/Exceptions/CatchingBaseException.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/src/Exceptions/CatchingBaseException.ql b/python/ql/src/Exceptions/CatchingBaseException.ql index 828cbf46e4b..5205af33441 100644 --- a/python/ql/src/Exceptions/CatchingBaseException.ql +++ b/python/ql/src/Exceptions/CatchingBaseException.ql @@ -13,11 +13,12 @@ */ import python +import semmle.python.ApiGraphs predicate doesnt_reraise(ExceptStmt ex) { ex.getAFlowNode().getBasicBlock().reachesExit() } predicate catches_base_exception(ExceptStmt ex) { - ex.getType().pointsTo(ClassValue::baseException()) + ex.getType() = API::builtin("BaseException").getAValueReachableFromSource().asExpr() or not exists(ex.getType()) } From 0599e8ac35615c3a3e7791f560deb3bee50011bb Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Sep 2022 23:47:07 +0200 Subject: [PATCH 033/203] python: add version check and attempt to set version for tests --- python/ql/src/Exceptions/UnguardedNextInGenerator.ql | 9 ++++++++- python/ql/test/query-tests/Exceptions/generators/options | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 python/ql/test/query-tests/Exceptions/generators/options diff --git a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql index d4007facb9c..c174732ed48 100644 --- a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql +++ b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql @@ -66,5 +66,12 @@ where ) and call.getNode().getScope().(Function).isGenerator() and not exists(Comp comp | comp.contains(call.getNode())) and - not stop_iteration_handled(call) + not stop_iteration_handled(call) and + // PEP 479 removes this concern from 3.5 onwards + // see: https://peps.python.org/pep-0479/ + ( + major_version() = 2 + or + major_version() = 3 and minor_version() < 5 + ) select call, "Call to next() in a generator" diff --git a/python/ql/test/query-tests/Exceptions/generators/options b/python/ql/test/query-tests/Exceptions/generators/options new file mode 100644 index 00000000000..b5ac2abad45 --- /dev/null +++ b/python/ql/test/query-tests/Exceptions/generators/options @@ -0,0 +1 @@ +semmle-extractor-options: --lang=3 --version=3.2 From 0c971bcc8c3fded42d9d3c19120624e7d2a88d5c Mon Sep 17 00:00:00 2001 From: james Date: Fri, 2 Sep 2022 10:36:02 +0100 Subject: [PATCH 034/203] update info about downloading dbs in vs code --- .../analyzing-your-projects.rst | 4 +--- .../customizing-settings.rst | 2 +- .../setting-up-codeql-in-visual-studio-code.rst | 16 +--------------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst index 71f72223620..87776892114 100644 --- a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst +++ b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst @@ -14,7 +14,7 @@ To analyze a project, you need to add a :ref:`CodeQL database ` #. Open the CodeQL Databases view in the sidebar. -#. Hover over the **Databases** title bar and click the appropriate icon to add your database. You can add a database from a local ZIP archive or folder, from a public URL, or from a project slug or URL on LGTM.com. +#. Hover over the **Databases** title bar and click the appropriate icon to add your database. You can add a database from a local ZIP archive or folder, from a public URL, or from a project slug on GitHub.com. .. image:: ../images/codeql-for-visual-studio-code/choose-database.png :width: 350 @@ -31,8 +31,6 @@ If you have a CodeQL database saved locally, as an unarchived folder or as a ZIP - To create a database with the CodeQL CLI, see ":ref:`Creating CodeQL databases `." -- .. include:: ../reusables/download-lgtm-database.rst - - To analyze a test database, add a ``.testproj`` folder to the Databases view. Test databases (that is, folders with a ``.testproj`` extension) are generated when you run regression tests on custom queries using the :ref:`CodeQL CLI `. If a query fails a regression test, you may want to analyze the test database in Visual Studio Code to debug the failure. diff --git a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst index 940a8a0c50c..8899bc97bc7 100644 --- a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst +++ b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst @@ -28,7 +28,7 @@ Editing settings Choosing a version of the CodeQL CLI -------------------------------------- -The CodeQL extension uses the CodeQL CLI to run commands. If you already have the CLI installed and added to your ``PATH``, the extension uses that version. This might be the case if you create your own CodeQL databases instead of downloading them from LGTM.com. Otherwise, the extension automatically manages access to the executable of the CLI for you. For more information about creating databases, see ":ref:`Creating CodeQL databases `" in the CLI help. +The CodeQL extension uses the CodeQL CLI to run commands. If you already have the CLI installed and added to your ``PATH``, the extension uses that version. This might be the case if you create your own CodeQL databases instead of downloading them from GitHub.com. Otherwise, the extension automatically manages access to the executable of the CLI for you. For more information about creating databases, see ":ref:`Creating CodeQL databases `" in the CLI help. To override the default behavior and use a different CLI, you can specify the CodeQL CLI **Executable Path**. diff --git a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst index b4969ce785d..1451901d0b2 100644 --- a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst @@ -28,7 +28,7 @@ Configuring access to the CodeQL CLI The extension uses the CodeQL CLI to compile and run queries. -If you already have the CLI installed and added to your ``PATH``, the extension uses that version. This might be the case if you create your own CodeQL databases instead of downloading them from LGTM.com. For more information, see ":ref:`CodeQL CLI `." +If you already have the CLI installed and added to your ``PATH``, the extension uses that version. This might be the case if you create your own CodeQL databases instead of downloading them from GitHub.com. For more information, see ":ref:`CodeQL CLI `." Otherwise, the extension automatically manages access to the executable of the CLI for you. This ensures that the CLI is compatible with the CodeQL extension. You can also check for updates with the **CodeQL: Check for CLI Updates** command. @@ -57,20 +57,6 @@ There are two ways to do this: For CLI users there is a third option: If you have followed the instructions in ":ref:`Getting started with the CodeQL CLI `" to create a CodeQL directory (for example ``codeql-home``) containing the CodeQL libraries, you can open this directory in VS Code. This also gives the extension access to the CodeQL libraries. -.. container:: toggle - - .. container:: name - - **Click to show information for LGTM Enterprise users** - - Your local version of the CodeQL queries and libraries should match your version of LGTM Enterprise. For example, if you - use LGTM Enterprise 1.27, then you should clone the ``1.27.0`` branch of the `starter workspace `__ (or the appropriate ``1.27.x`` branch, corresponding to each maintenance release). - - This ensures that the queries and libraries you write in VS Code also work in the query console on LGTM Enterprise. - - If you prefer to add the CodeQL queries and libraries to an :ref:`existing workspace ` instead of the starter workspace, then you should - clone the appropriate branch of the `CodeQL repository `__ and add it to your workspace. - .. _starter-workspace: Using the starter workspace From c0b9be0ecbddc2e11aa0f37263d9bb43e8a371a3 Mon Sep 17 00:00:00 2001 From: james Date: Fri, 2 Sep 2022 10:43:36 +0100 Subject: [PATCH 035/203] new screenshot --- .../choose-database.png | Bin 58515 -> 112731 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/codeql/images/codeql-for-visual-studio-code/choose-database.png b/docs/codeql/images/codeql-for-visual-studio-code/choose-database.png index 71ca5d6b4c3512bcdc641be0a14043c108a320a5..58287111cc162e7ed95e8e59ecbfc84e55d8b187 100644 GIT binary patch literal 112731 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
    FSR4dalV%}_BZmvXwt2~Feg0LpIX@c>uIG^ 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

    )`;o~)I6-}KHVMM|0DqM9DTC7XzX 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 I)bh>$0HH%;UjP6A literal 58515 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 b)Sl7Hmup;LzbhV4kdvB{wqlclW#s<=JOCS{ From c38062ce93065137ac8730c0d642d572230839b8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 2 Sep 2022 20:26:31 +0200 Subject: [PATCH 036/203] convert RelevantState to a class in the PrefixConstruction module --- .../code/java/security/regexp/NfaUtils.qll | 49 +++++++++---------- .../javascript/security/regexp/NfaUtils.qll | 49 +++++++++---------- .../python/security/regexp/NfaUtils.qll | 49 +++++++++---------- .../codeql/ruby/security/regexp/NfaUtils.qll | 49 +++++++++---------- 4 files changed, 88 insertions(+), 108 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll index 033b8aa8cfd..1c806c305ba 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -887,11 +887,10 @@ module PrefixConstruction { /** * Holds if `state` is the textually last start state for the regular expression. */ - private predicate lastStartState(State state) { + private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = max(State s, Location l | - s = stateInRelevantRegexp() and isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() @@ -963,10 +962,13 @@ module PrefixConstruction { min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) } - /** Gets a state within a regular expression that contains a candidate state. */ - pragma[noinline] - State stateInRelevantRegexp() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + /** A state within a regular expression that contains a candidate state. */ + class RelevantState instanceof State { + RelevantState() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) + } + + string toString() { result = "RelevantState" } } } @@ -1007,6 +1009,8 @@ module ReDoSPruning { import PrefixConstruction as Prefix + class RelevantState = Prefix::RelevantState; + /** * Predicates for testing the presence of a rejecting suffix. * @@ -1040,32 +1044,26 @@ module ReDoSPruning { * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. */ pragma[noinline] - private predicate isLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and - ( - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - ) + private predicate isLikelyRejectable(RelevantState s) { + // exists a reject edge with some char. + hasRejectEdge(s) + or + hasEdgeToLikelyRejectable(s) + or + // stopping here is rejection + isRejectState(s) } /** * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ - predicate isRejectState(State s) { - s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_) - } + predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } /** * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. */ pragma[noopt] - predicate hasEdgeToLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and + predicate hasEdgeToLikelyRejectable(RelevantState s) { // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1080,8 +1078,7 @@ module ReDoSPruning { * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. */ pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(State s) { - s = Prefix::stateInRelevantRegexp() and + private string hasEdgeToLikelyRejectableHelper(RelevantState s) { not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1092,9 +1089,7 @@ module ReDoSPruning { * along epsilon edges, such that there is a transition from * `prev` to `next` that the character symbol `char`. */ - predicate deltaClosedChar(State prev, string char, State next) { - prev = Prefix::stateInRelevantRegexp() and - next = Prefix::stateInRelevantRegexp() and + predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll index 033b8aa8cfd..1c806c305ba 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll @@ -887,11 +887,10 @@ module PrefixConstruction { /** * Holds if `state` is the textually last start state for the regular expression. */ - private predicate lastStartState(State state) { + private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = max(State s, Location l | - s = stateInRelevantRegexp() and isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() @@ -963,10 +962,13 @@ module PrefixConstruction { min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) } - /** Gets a state within a regular expression that contains a candidate state. */ - pragma[noinline] - State stateInRelevantRegexp() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + /** A state within a regular expression that contains a candidate state. */ + class RelevantState instanceof State { + RelevantState() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) + } + + string toString() { result = "RelevantState" } } } @@ -1007,6 +1009,8 @@ module ReDoSPruning { import PrefixConstruction as Prefix + class RelevantState = Prefix::RelevantState; + /** * Predicates for testing the presence of a rejecting suffix. * @@ -1040,32 +1044,26 @@ module ReDoSPruning { * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. */ pragma[noinline] - private predicate isLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and - ( - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - ) + private predicate isLikelyRejectable(RelevantState s) { + // exists a reject edge with some char. + hasRejectEdge(s) + or + hasEdgeToLikelyRejectable(s) + or + // stopping here is rejection + isRejectState(s) } /** * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ - predicate isRejectState(State s) { - s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_) - } + predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } /** * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. */ pragma[noopt] - predicate hasEdgeToLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and + predicate hasEdgeToLikelyRejectable(RelevantState s) { // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1080,8 +1078,7 @@ module ReDoSPruning { * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. */ pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(State s) { - s = Prefix::stateInRelevantRegexp() and + private string hasEdgeToLikelyRejectableHelper(RelevantState s) { not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1092,9 +1089,7 @@ module ReDoSPruning { * along epsilon edges, such that there is a transition from * `prev` to `next` that the character symbol `char`. */ - predicate deltaClosedChar(State prev, string char, State next) { - prev = Prefix::stateInRelevantRegexp() and - next = Prefix::stateInRelevantRegexp() and + predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } diff --git a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll index 033b8aa8cfd..1c806c305ba 100644 --- a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll +++ b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll @@ -887,11 +887,10 @@ module PrefixConstruction { /** * Holds if `state` is the textually last start state for the regular expression. */ - private predicate lastStartState(State state) { + private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = max(State s, Location l | - s = stateInRelevantRegexp() and isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() @@ -963,10 +962,13 @@ module PrefixConstruction { min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) } - /** Gets a state within a regular expression that contains a candidate state. */ - pragma[noinline] - State stateInRelevantRegexp() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + /** A state within a regular expression that contains a candidate state. */ + class RelevantState instanceof State { + RelevantState() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) + } + + string toString() { result = "RelevantState" } } } @@ -1007,6 +1009,8 @@ module ReDoSPruning { import PrefixConstruction as Prefix + class RelevantState = Prefix::RelevantState; + /** * Predicates for testing the presence of a rejecting suffix. * @@ -1040,32 +1044,26 @@ module ReDoSPruning { * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. */ pragma[noinline] - private predicate isLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and - ( - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - ) + private predicate isLikelyRejectable(RelevantState s) { + // exists a reject edge with some char. + hasRejectEdge(s) + or + hasEdgeToLikelyRejectable(s) + or + // stopping here is rejection + isRejectState(s) } /** * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ - predicate isRejectState(State s) { - s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_) - } + predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } /** * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. */ pragma[noopt] - predicate hasEdgeToLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and + predicate hasEdgeToLikelyRejectable(RelevantState s) { // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1080,8 +1078,7 @@ module ReDoSPruning { * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. */ pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(State s) { - s = Prefix::stateInRelevantRegexp() and + private string hasEdgeToLikelyRejectableHelper(RelevantState s) { not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1092,9 +1089,7 @@ module ReDoSPruning { * along epsilon edges, such that there is a transition from * `prev` to `next` that the character symbol `char`. */ - predicate deltaClosedChar(State prev, string char, State next) { - prev = Prefix::stateInRelevantRegexp() and - next = Prefix::stateInRelevantRegexp() and + predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll index 033b8aa8cfd..1c806c305ba 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll @@ -887,11 +887,10 @@ module PrefixConstruction { /** * Holds if `state` is the textually last start state for the regular expression. */ - private predicate lastStartState(State state) { + private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = max(State s, Location l | - s = stateInRelevantRegexp() and isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() @@ -963,10 +962,13 @@ module PrefixConstruction { min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next)) } - /** Gets a state within a regular expression that contains a candidate state. */ - pragma[noinline] - State stateInRelevantRegexp() { - exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(result.getRepr())) + /** A state within a regular expression that contains a candidate state. */ + class RelevantState instanceof State { + RelevantState() { + exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) + } + + string toString() { result = "RelevantState" } } } @@ -1007,6 +1009,8 @@ module ReDoSPruning { import PrefixConstruction as Prefix + class RelevantState = Prefix::RelevantState; + /** * Predicates for testing the presence of a rejecting suffix. * @@ -1040,32 +1044,26 @@ module ReDoSPruning { * This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs. */ pragma[noinline] - private predicate isLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and - ( - // exists a reject edge with some char. - hasRejectEdge(s) - or - hasEdgeToLikelyRejectable(s) - or - // stopping here is rejection - isRejectState(s) - ) + private predicate isLikelyRejectable(RelevantState s) { + // exists a reject edge with some char. + hasRejectEdge(s) + or + hasEdgeToLikelyRejectable(s) + or + // stopping here is rejection + isRejectState(s) } /** * Holds if `s` is not an accept state, and there is no epsilon transition to an accept state. */ - predicate isRejectState(State s) { - s = Prefix::stateInRelevantRegexp() and not epsilonSucc*(s) = Accept(_) - } + predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) } /** * Holds if there is likely a non-empty suffix leading to rejection starting in `s`. */ pragma[noopt] - predicate hasEdgeToLikelyRejectable(State s) { - s = Prefix::stateInRelevantRegexp() and + predicate hasEdgeToLikelyRejectable(RelevantState s) { // all edges (at least one) with some char leads to another state that is rejectable. // the `next` states might not share a common suffix, which can cause FPs. exists(string char | char = hasEdgeToLikelyRejectableHelper(s) | @@ -1080,8 +1078,7 @@ module ReDoSPruning { * and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`. */ pragma[noinline] - private string hasEdgeToLikelyRejectableHelper(State s) { - s = Prefix::stateInRelevantRegexp() and + private string hasEdgeToLikelyRejectableHelper(RelevantState s) { not hasRejectEdge(s) and not isRejectState(s) and deltaClosedChar(s, result, _) @@ -1092,9 +1089,7 @@ module ReDoSPruning { * along epsilon edges, such that there is a transition from * `prev` to `next` that the character symbol `char`. */ - predicate deltaClosedChar(State prev, string char, State next) { - prev = Prefix::stateInRelevantRegexp() and - next = Prefix::stateInRelevantRegexp() and + predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) { deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next) } From a8a042db57352631146a41932a858383608d71e3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Sat, 3 Sep 2022 20:33:48 +0200 Subject: [PATCH 037/203] python: remove illegal option --- python/ql/test/query-tests/Exceptions/generators/options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/query-tests/Exceptions/generators/options b/python/ql/test/query-tests/Exceptions/generators/options index b5ac2abad45..82e71280e70 100644 --- a/python/ql/test/query-tests/Exceptions/generators/options +++ b/python/ql/test/query-tests/Exceptions/generators/options @@ -1 +1 @@ -semmle-extractor-options: --lang=3 --version=3.2 +semmle-extractor-options: --lang=3.2 From afb50212a014ed04945a90d7f24ad82669979ada Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 5 Sep 2022 10:50:53 +0200 Subject: [PATCH 038/203] Python: update version check doc said 3.5 experience says 3.7 --- python/ql/src/Exceptions/UnguardedNextInGenerator.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql index c174732ed48..7e1e0f868be 100644 --- a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql +++ b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql @@ -69,9 +69,11 @@ where not stop_iteration_handled(call) and // PEP 479 removes this concern from 3.5 onwards // see: https://peps.python.org/pep-0479/ + // + // However, testing it out, the problem is not removed until 3.7. ( major_version() = 2 or - major_version() = 3 and minor_version() < 5 + major_version() = 3 and minor_version() < 7 ) select call, "Call to next() in a generator" From 0162bc3c773182e967bc542c5caa69e71d68a2cd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 5 Sep 2022 11:22:12 +0200 Subject: [PATCH 039/203] use `RelevantState` inside the `lastStartState` predicate Co-authored-by: Arthur Baars --- java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll index 1c806c305ba..8706b827a6f 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -890,7 +890,7 @@ module PrefixConstruction { private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = - max(State s, Location l | + max(RelevantState s, Location l | isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() From 3f1cb04f3e8b450f5508781bf572b13f029a3e50 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 5 Sep 2022 11:22:34 +0200 Subject: [PATCH 040/203] sync files --- .../ql/lib/semmle/javascript/security/regexp/NfaUtils.qll | 2 +- python/ql/lib/semmle/python/security/regexp/NfaUtils.qll | 2 +- ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll index 1c806c305ba..8706b827a6f 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll @@ -890,7 +890,7 @@ module PrefixConstruction { private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = - max(State s, Location l | + max(RelevantState s, Location l | isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() diff --git a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll index 1c806c305ba..8706b827a6f 100644 --- a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll +++ b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll @@ -890,7 +890,7 @@ module PrefixConstruction { private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = - max(State s, Location l | + max(RelevantState s, Location l | isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll index 1c806c305ba..8706b827a6f 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll @@ -890,7 +890,7 @@ module PrefixConstruction { private predicate lastStartState(RelevantState state) { exists(RegExpRoot root | state = - max(State s, Location l | + max(RelevantState s, Location l | isStartState(s) and getRoot(s.getRepr()) = root and l = s.getRepr().getLocation() From a86a940df7b26ccc57bd44a25b9d7774cf1d8100 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 5 Sep 2022 13:27:34 +0200 Subject: [PATCH 041/203] add getRepr() and toString() on RelevantState --- java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll | 6 +++++- .../ql/lib/semmle/javascript/security/regexp/NfaUtils.qll | 6 +++++- python/ql/lib/semmle/python/security/regexp/NfaUtils.qll | 6 +++++- ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll index 8706b827a6f..5112bdad11e 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll @@ -968,7 +968,11 @@ module PrefixConstruction { exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) } - string toString() { result = "RelevantState" } + /** Gets a string representation for this state in a regular expression. */ + string toString() { result = State.super.toString() } + + /** Gets the term represented by this state. */ + RegExpTerm getRepr() { result = State.super.getRepr() } } } diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll index 8706b827a6f..5112bdad11e 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll @@ -968,7 +968,11 @@ module PrefixConstruction { exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) } - string toString() { result = "RelevantState" } + /** Gets a string representation for this state in a regular expression. */ + string toString() { result = State.super.toString() } + + /** Gets the term represented by this state. */ + RegExpTerm getRepr() { result = State.super.getRepr() } } } diff --git a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll index 8706b827a6f..5112bdad11e 100644 --- a/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll +++ b/python/ql/lib/semmle/python/security/regexp/NfaUtils.qll @@ -968,7 +968,11 @@ module PrefixConstruction { exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) } - string toString() { result = "RelevantState" } + /** Gets a string representation for this state in a regular expression. */ + string toString() { result = State.super.toString() } + + /** Gets the term represented by this state. */ + RegExpTerm getRepr() { result = State.super.getRepr() } } } diff --git a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll index 8706b827a6f..5112bdad11e 100644 --- a/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll +++ b/ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll @@ -968,7 +968,11 @@ module PrefixConstruction { exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr())) } - string toString() { result = "RelevantState" } + /** Gets a string representation for this state in a regular expression. */ + string toString() { result = State.super.toString() } + + /** Gets the term represented by this state. */ + RegExpTerm getRepr() { result = State.super.getRepr() } } } From 5fc1bbc8c5b4337d4bf8a9b34ccc874100249963 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 5 Sep 2022 13:38:14 +0200 Subject: [PATCH 042/203] Python: Only alert on Python 2 code since - Python 3 is ok from 3.7 onwards - support for Python 3.6 was just dropped - we do not actually know the minor version of the analysed code (only of the extractor) --- python/ql/src/Exceptions/UnguardedNextInGenerator.ql | 11 ++++------- .../generators/UnguardedNextInGenerator.expected | 0 .../generators/UnguardedNextInGenerator.qlref | 0 .../{ => 2}/query-tests/Exceptions/generators/test.py | 0 .../ql/test/query-tests/Exceptions/generators/options | 1 - 5 files changed, 4 insertions(+), 8 deletions(-) rename python/ql/test/{ => 2}/query-tests/Exceptions/generators/UnguardedNextInGenerator.expected (100%) rename python/ql/test/{ => 2}/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref (100%) rename python/ql/test/{ => 2}/query-tests/Exceptions/generators/test.py (100%) delete mode 100644 python/ql/test/query-tests/Exceptions/generators/options diff --git a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql index 7e1e0f868be..890df3374d9 100644 --- a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql +++ b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql @@ -67,13 +67,10 @@ where call.getNode().getScope().(Function).isGenerator() and not exists(Comp comp | comp.contains(call.getNode())) and not stop_iteration_handled(call) and - // PEP 479 removes this concern from 3.5 onwards + // PEP 479 removes this concern from 3.7 onwards // see: https://peps.python.org/pep-0479/ // - // However, testing it out, the problem is not removed until 3.7. - ( - major_version() = 2 - or - major_version() = 3 and minor_version() < 7 - ) + // However, we do not know the minor version of the analysed code (only of the extractor), + // so we only alert on Python 2. + major_version() = 2 select call, "Call to next() in a generator" diff --git a/python/ql/test/query-tests/Exceptions/generators/UnguardedNextInGenerator.expected b/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.expected similarity index 100% rename from python/ql/test/query-tests/Exceptions/generators/UnguardedNextInGenerator.expected rename to python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.expected diff --git a/python/ql/test/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref b/python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref similarity index 100% rename from python/ql/test/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref rename to python/ql/test/2/query-tests/Exceptions/generators/UnguardedNextInGenerator.qlref diff --git a/python/ql/test/query-tests/Exceptions/generators/test.py b/python/ql/test/2/query-tests/Exceptions/generators/test.py similarity index 100% rename from python/ql/test/query-tests/Exceptions/generators/test.py rename to python/ql/test/2/query-tests/Exceptions/generators/test.py diff --git a/python/ql/test/query-tests/Exceptions/generators/options b/python/ql/test/query-tests/Exceptions/generators/options deleted file mode 100644 index 82e71280e70..00000000000 --- a/python/ql/test/query-tests/Exceptions/generators/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --lang=3.2 From d31d763328f99512bc683d94a4a733d556a0d95c Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 5 Sep 2022 16:45:43 +0200 Subject: [PATCH 043/203] Python: adjust test expectations We now locate a `DataFlow::Node` rather than an 'AstNode`. --- .../2/query-tests/Exceptions/raising/RaisingTuple.expected | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.expected b/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.expected index f95dd5defde..7200c147ea9 100644 --- a/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.expected +++ b/python/ql/test/2/query-tests/Exceptions/raising/RaisingTuple.expected @@ -1,3 +1,3 @@ -| test.py:8:5:8:12 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:7:10:7:29 | Tuple | a tuple | -| test.py:11:5:11:32 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:11:12:11:31 | Tuple | a tuple | -| test.py:15:5:15:23 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:14:10:14:19 | Tuple | a tuple | +| test.py:8:5:8:12 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:7:10:7:29 | ControlFlowNode for Tuple | a tuple | +| test.py:11:5:11:32 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:11:12:11:31 | ControlFlowNode for Tuple | a tuple | +| test.py:15:5:15:23 | Raise | Raising $@ will result in the first element (recursively) being raised and all other elements being discarded. | test.py:14:10:14:19 | ControlFlowNode for Tuple | a tuple | From cb3c53dee72c6f4ef8b6d2f4b8cf17b08d16b56a Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Tue, 6 Sep 2022 11:31:24 +0200 Subject: [PATCH 044/203] Kotlin: Add test case for unexpected `vararg` extraction error --- .../test/kotlin/library-tests/vararg/args.expected | 6 ++++++ java/ql/test/kotlin/library-tests/vararg/args.ql | 5 +++++ java/ql/test/kotlin/library-tests/vararg/test.kt | 12 +++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/java/ql/test/kotlin/library-tests/vararg/args.expected b/java/ql/test/kotlin/library-tests/vararg/args.expected index 3d6a2347a95..dd966a10b2c 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.expected +++ b/java/ql/test/kotlin/library-tests/vararg/args.expected @@ -1,9 +1,12 @@ +diag +| test.kt:55:15:55:35 | Unexpected IrVararg | varargsParams | test.kt:8:15:8:28 | xs | file://:0:0:0:0 | int[] | | test.kt:12:26:12:39 | xs | file://:0:0:0:0 | int[] | | test.kt:20:24:20:37 | xs | file://:0:0:0:0 | int[] | | test.kt:24:50:24:63 | xs | file://:0:0:0:0 | int[] | | test.kt:28:37:28:50 | xs | file://:0:0:0:0 | int[] | +| test.kt:50:5:50:31 | s | file://:0:0:0:0 | String[] | explicitVarargsArguments | test.kt:12:50:12:51 | xs | test.kt:12:44:12:52 | this(...) | | test.kt:38:25:38:29 | array | test.kt:38:5:38:30 | funWithOnlyVarArgs(...) | @@ -11,6 +14,7 @@ explicitVarargsArguments | test.kt:40:34:40:38 | array | test.kt:40:5:40:49 | funWithMiddleVarArgs(...) | | test.kt:44:27:44:31 | array | test.kt:44:5:44:32 | new HasVarargConstructor(...) | | test.kt:45:34:45:38 | array | test.kt:45:5:45:39 | new HasVarargConstructor(...) | +| test.kt:55:15:55:35 | tmp0_s | test.kt:55:13:55:43 | new X(...) | implicitVarargsArguments | intList.kt:3:21:3:22 | 10 | intList.kt:3:14:3:31 | listOf(...) | 0 | | intList.kt:3:25:3:26 | 11 | intList.kt:3:14:3:31 | listOf(...) | 1 | @@ -78,3 +82,5 @@ implicitVarargsArguments | test.kt:44:5:44:32 | new HasVarargConstructor(...) | 0 | test.kt:44:27:44:31 | array | | test.kt:45:5:45:39 | new HasVarargConstructor(...) | 0 | test.kt:45:27:45:29 | foo | | test.kt:45:5:45:39 | new HasVarargConstructor(...) | 1 | test.kt:45:34:45:38 | array | +| test.kt:55:13:55:43 | new X(...) | 0 | test.kt:55:42:55:42 | 1 | +| test.kt:55:13:55:43 | new X(...) | 1 | test.kt:55:15:55:35 | tmp0_s | diff --git a/java/ql/test/kotlin/library-tests/vararg/args.ql b/java/ql/test/kotlin/library-tests/vararg/args.ql index e58bf622e98..510ea0c2682 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.ql +++ b/java/ql/test/kotlin/library-tests/vararg/args.ql @@ -1,4 +1,9 @@ import java +import semmle.code.java.Diagnostics + +query predicate diag(Diagnostic d) { + d.getMessage() = "Unexpected IrVararg" +} query predicate varargsParams(Parameter p, Type t) { p.getCallable().fromSource() and diff --git a/java/ql/test/kotlin/library-tests/vararg/test.kt b/java/ql/test/kotlin/library-tests/vararg/test.kt index 00dc8f13d78..966f9d0f5a9 100644 --- a/java/ql/test/kotlin/library-tests/vararg/test.kt +++ b/java/ql/test/kotlin/library-tests/vararg/test.kt @@ -1,6 +1,6 @@ fun sink(sunk: Int) { - + } open class HasVarargConstructor { @@ -44,3 +44,13 @@ fun myFun() { HasVarargConstructor(*array) HasVarargConstructor("foo", *array) } + +open class X( + i: Int, + public vararg val s: String +) { } + +fun fn(sl: List) { + // reordered args: + val x = X(s = sl.toTypedArray(), i = 1) +} From 826bbdf834c92f15baa6b90175c82925f09f8cf2 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Tue, 6 Sep 2022 11:32:09 +0200 Subject: [PATCH 045/203] Kotlin: Fix `vararg` extraction outside of method call --- .../src/main/kotlin/KotlinFileExtractor.kt | 8 +++++++- java/ql/test/kotlin/library-tests/vararg/args.expected | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fe88f8a2de4..d1603f0d58d 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -3056,7 +3056,13 @@ open class KotlinFileExtractor( extractTypeOperatorCall(e, callable, exprParent.parent, exprParent.idx, exprParent.enclosingStmt) } is IrVararg -> { - logger.errorElement("Unexpected IrVararg", e) + if (e.elements.size != 1 || e.elements[0] !is IrSpreadElement) { + logger.errorElement("Unexpected IrVararg", e) + return + } + // There are lowered IR cases when the vararg expression is not within a call, such as + // val temp0 = [*expr] + extractExpression((e.elements[0] as IrSpreadElement).expression, callable, parent) } is IrGetObjectValue -> { // For `object MyObject { ... }`, the .class has an diff --git a/java/ql/test/kotlin/library-tests/vararg/args.expected b/java/ql/test/kotlin/library-tests/vararg/args.expected index dd966a10b2c..317a907bdc8 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.expected +++ b/java/ql/test/kotlin/library-tests/vararg/args.expected @@ -1,5 +1,4 @@ diag -| test.kt:55:15:55:35 | Unexpected IrVararg | varargsParams | test.kt:8:15:8:28 | xs | file://:0:0:0:0 | int[] | | test.kt:12:26:12:39 | xs | file://:0:0:0:0 | int[] | @@ -84,3 +83,4 @@ implicitVarargsArguments | test.kt:45:5:45:39 | new HasVarargConstructor(...) | 1 | test.kt:45:34:45:38 | array | | test.kt:55:13:55:43 | new X(...) | 0 | test.kt:55:42:55:42 | 1 | | test.kt:55:13:55:43 | new X(...) | 1 | test.kt:55:15:55:35 | tmp0_s | +| test.kt:55:22:55:35 | toTypedArray(...) | 0 | test.kt:55:19:55:20 | sl | From b745b5ab719ca1ac3fe42b8c4cd354cf25bdf39c Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 6 Sep 2022 14:32:48 +0200 Subject: [PATCH 046/203] Add models for androidx.core.app.NotificationCompat --- ...2022-09-06-notificationcompat-summaries.md | 5 + .../java/frameworks/android/Notifications.qll | 36 +- .../frameworks/android/notification/Test.java | 646 +++++++++++++++- ...otificationBuilderWithBuilderAccessor.java | 10 + .../androidx/core/app/NotificationCompat.java | 720 ++++++++++++++++++ .../androidx/core/app/RemoteInput.java | 71 ++ .../CustomVersionedParcelable.java | 14 + .../VersionedParcelable.java | 8 + 8 files changed, 1503 insertions(+), 7 deletions(-) create mode 100644 java/ql/lib/change-notes/2022-09-06-notificationcompat-summaries.md create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationBuilderWithBuilderAccessor.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationCompat.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/RemoteInput.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/CustomVersionedParcelable.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/VersionedParcelable.java diff --git a/java/ql/lib/change-notes/2022-09-06-notificationcompat-summaries.md b/java/ql/lib/change-notes/2022-09-06-notificationcompat-summaries.md new file mode 100644 index 00000000000..e95ad457844 --- /dev/null +++ b/java/ql/lib/change-notes/2022-09-06-notificationcompat-summaries.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added new flow steps for `androidx.core.app.NotificationCompat` and its inner classes. + \ No newline at end of file diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll b/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll index f16af6dcf89..0f69f0bbe1d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Notifications.qll @@ -19,6 +19,17 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv { "android.app;Notification$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", "android.app;Notification$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", "android.app;Notification$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", + "androidx.core.app;NotificationCompat$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Action;true;Action;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual", + "androidx.core.app;NotificationCompat$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", "android.app;Notification$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", "android.app;Notification$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", "android.app;Notification$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", @@ -32,18 +43,30 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv { "android.app;Notification$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", "android.app;Notification$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", "android.app;Notification$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual", + "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual", + "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual", + "androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual", + "androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual", + "androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual", + "androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual", "android.app;Notification$Style;true;build;;;Argument[-1];ReturnValue;taint;manual", "android.app;Notification$BigPictureStyle;true;BigPictureStyle;(Builder);;Argument[0];Argument[-1];taint;manual", "android.app;Notification$BigTextStyle;true;BigTextStyle;(Builder);;Argument[0];Argument[-1];taint;manual", "android.app;Notification$InboxStyle;true;InboxStyle;(Builder);;Argument[0];Argument[-1];taint;manual", "android.app;Notification$MediaStyle;true;MediaStyle;(Builder);;Argument[0];Argument[-1];taint;manual", // Fluent models - "android.app;Notification$Action$Builder;true;" + + ["android.app;Notification", "androidx.core.app;NotificationCompat"] + + "$Action$Builder;true;" + [ "addExtras", "addRemoteInput", "extend", "setAllowGeneratedReplies", "setAuthenticationRequired", "setContextual", "setSemanticAction" ] + ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$Builder;true;" + + ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$Builder;true;" + [ "addAction", "addExtras", "addPerson", "extend", "setActions", "setAutoCancel", "setBadgeIconType", "setBubbleMetadata", "setCategory", "setChannelId", @@ -58,15 +81,16 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv { "setSubText", "setTicker", "setTimeoutAfter", "setUsesChronometer", "setVibrate", "setVisibility", "setWhen" ] + ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$BigPictureStyle;true;" + + ["android.app;Notification", "androidx.core.app;NotificationCompat"] + + "$BigPictureStyle;true;" + [ "bigLargeIcon", "bigPicture", "setBigContentTitle", "setContentDescription", "setSummaryText", "showBigPictureWhenCollapsed" ] + ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$BigTextStyle;true;" + - ["bigText", "setBigContentTitle", "setSummaryText"] + + ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$BigTextStyle;true;" + + ["bigText", "setBigContentTitle", "setSummaryText"] + ";;;Argument[-1];ReturnValue;value;manual", - "android.app;Notification$InboxStyle;true;" + + ["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$InboxStyle;true;" + ["addLine", "setBigContentTitle", "setSummaryText"] + ";;;Argument[-1];ReturnValue;value;manual", "android.app;Notification$MediaStyle;true;" + diff --git a/java/ql/test/library-tests/frameworks/android/notification/Test.java b/java/ql/test/library-tests/frameworks/android/notification/Test.java index 566c52b0a6e..d669e7421bf 100644 --- a/java/ql/test/library-tests/frameworks/android/notification/Test.java +++ b/java/ql/test/library-tests/frameworks/android/notification/Test.java @@ -1,11 +1,13 @@ package generatedtest; import android.app.Notification; +import androidx.core.app.NotificationCompat; import android.app.PendingIntent; import android.app.Person; import android.app.Notification.Action; import android.graphics.Bitmap; import android.graphics.drawable.Icon; +import androidx.core.graphics.drawable.IconCompat; import android.media.AudioAttributes; import android.net.Uri; import android.os.Bundle; @@ -103,7 +105,8 @@ public class Test { } { // "android.app;Notification$Action$Builder;true;build;;;SyntheticField[android.content.Intent.extras] - // of Argument[-1];SyntheticField[android.content.Intent.extras] of ReturnValue;value;manual" + // of Argument[-1];SyntheticField[android.content.Intent.extras] of + // ReturnValue;value;manual" Notification.Action out = null; Notification.Action.Builder builder = null; Bundle in = (Bundle) newWithMapValueDefault(source()); @@ -814,6 +817,647 @@ public class Test { Notification.MediaStyle out = in.setShowActionsInCompactView(null); sink(out); // $ hasValueFlow } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action in = (NotificationCompat.Action) source(); + out = new NotificationCompat.Action.Builder(in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual" + NotificationCompat.Action.Builder out = null; + PendingIntent in = (PendingIntent) source(); + out = new NotificationCompat.Action.Builder((IconCompat) null, (CharSequence) null, in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual" + NotificationCompat.Action.Builder out = null; + PendingIntent in = (PendingIntent) source(); + out = new NotificationCompat.Action.Builder(0, (CharSequence) null, in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.addExtras(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual" + NotificationCompat.Action.Builder out = null; + Bundle in = (Bundle) newWithMapKeyDefault(source()); + out.addExtras(in); + sink(getMapKeyDefault(out.getExtras())); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual" + NotificationCompat.Action.Builder out = null; + Bundle in = (Bundle) newWithMapValueDefault(source()); + out.addExtras(in); + sink(getMapValueDefault(out.getExtras())); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;addRemoteInput;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.addRemoteInput(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual" + NotificationCompat.Action out = null; + NotificationCompat.Action.Builder builder = null; + Bundle in = (Bundle) newWithMapValueDefault(source()); + builder.addExtras(in); + out = builder.build(); + sink(getMapValueDefault(out.getExtras())); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual" + NotificationCompat.Action out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.build(); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;extend;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.extend(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual" + Bundle out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.getExtras(); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;setAllowGeneratedReplies;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.setAllowGeneratedReplies(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;setContextual;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.setContextual(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action$Builder;true;setSemanticAction;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Action.Builder out = null; + NotificationCompat.Action.Builder in = (NotificationCompat.Action.Builder) source(); + out = in.setSemanticAction(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Action;true;Action;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual" + NotificationCompat.Action out = null; + PendingIntent in = (PendingIntent) source(); + out = new NotificationCompat.Action((IconCompat) null, (CharSequence) null, in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual" + NotificationCompat.Action out = null; + PendingIntent in = (PendingIntent) source(); + out = new NotificationCompat.Action(0, (CharSequence) null, in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual" + Bundle out = null; + NotificationCompat.Action in = (NotificationCompat.Action) source(); + out = in.getExtras(); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$BigPictureStyle;true;bigLargeIcon;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigPictureStyle out = null; + NotificationCompat.BigPictureStyle in = (NotificationCompat.BigPictureStyle) source(); + out = in.bigLargeIcon(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigPictureStyle;true;bigPicture;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigPictureStyle out = null; + NotificationCompat.BigPictureStyle in = (NotificationCompat.BigPictureStyle) source(); + out = in.bigPicture(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigPictureStyle;true;setBigContentTitle;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigPictureStyle out = null; + NotificationCompat.BigPictureStyle in = (NotificationCompat.BigPictureStyle) source(); + out = in.setBigContentTitle(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigPictureStyle;true;setSummaryText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigPictureStyle out = null; + NotificationCompat.BigPictureStyle in = (NotificationCompat.BigPictureStyle) source(); + out = in.setSummaryText(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigTextStyle;true;bigText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigTextStyle out = null; + NotificationCompat.BigTextStyle in = (NotificationCompat.BigTextStyle) source(); + out = in.bigText(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigTextStyle;true;setBigContentTitle;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigTextStyle out = null; + NotificationCompat.BigTextStyle in = (NotificationCompat.BigTextStyle) source(); + out = in.setBigContentTitle(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$BigTextStyle;true;setSummaryText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.BigTextStyle out = null; + NotificationCompat.BigTextStyle in = (NotificationCompat.BigTextStyle) source(); + out = in.setSummaryText(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Action in = (NotificationCompat.Action) source(); + out.addAction(in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual" + NotificationCompat.Builder out = null; + PendingIntent in = (PendingIntent) source(); + out.addAction(0, null, in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addAction;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.addAction(0, null, null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addAction;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.addAction(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.addExtras(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual" + NotificationCompat.Builder out = null; + Bundle in = (Bundle) newWithMapKeyDefault(source()); + out.addExtras(in); + sink(getMapKeyDefault(out.getExtras())); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual" + NotificationCompat.Builder out = null; + Bundle in = (Bundle) newWithMapValueDefault(source()); + out.addExtras(in); + sink(getMapValueDefault(out.getExtras())); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;addPerson;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.addPerson(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual" + Notification out = null; + NotificationCompat.Builder builder = null; + Bundle in = (Bundle) newWithMapValueDefault(source()); + builder.addExtras(in); + out = builder.build(); + sink(getMapValueDefault(out.extras)); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual" + Notification out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.build(); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;extend;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.extend(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual" + Bundle out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.getExtras(); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setAutoCancel;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setAutoCancel(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setBadgeIconType;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setBadgeIconType(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setBubbleMetadata;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setBubbleMetadata(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setCategory;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setCategory(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setChannelId;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setChannelId(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setChronometerCountDown;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setChronometerCountDown(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setColor;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setColor(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setColorized;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setColorized(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContent;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setContent(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContentInfo;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setContentInfo(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setContentIntent(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual" + NotificationCompat.Builder out = null; + PendingIntent in = (PendingIntent) source(); + out.setContentIntent(in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContentText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setContentText(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setContentTitle;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setContentTitle(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setCustomBigContentView;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setCustomBigContentView(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setCustomHeadsUpContentView;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setCustomHeadsUpContentView(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setDefaults;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setDefaults(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setDeleteIntent(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual" + NotificationCompat.Builder out = null; + PendingIntent in = (PendingIntent) source(); + out.setDeleteIntent(in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setExtras(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual" + NotificationCompat.Builder out = null; + Bundle in = (Bundle) source(); + out.setExtras(in); + sink(out.getExtras()); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setFullScreenIntent;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setFullScreenIntent(null, false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setGroup;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setGroup(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setGroupAlertBehavior;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setGroupAlertBehavior(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setGroupSummary;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setGroupSummary(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setLargeIcon;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setLargeIcon(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setLights;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setLights(0, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setLocalOnly;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setLocalOnly(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setNumber;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setNumber(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setOngoing;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setOngoing(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setOnlyAlertOnce;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setOnlyAlertOnce(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setPriority;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setPriority(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setProgress;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setProgress(0, 0, false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setPublicVersion(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual" + NotificationCompat.Builder out = null; + Notification in = (Notification) source(); + out.setPublicVersion(in); + sink(out); // $ hasTaintFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setRemoteInputHistory;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setRemoteInputHistory(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setShortcutId;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setShortcutId(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setShowWhen;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setShowWhen(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSmallIcon;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSmallIcon(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSmallIcon;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSmallIcon(0, 0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSortKey;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSortKey(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSound;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSound(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSound;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSound(null, 0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setStyle;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setStyle(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setSubText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setSubText(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setTicker;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setTicker(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setTicker;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setTicker(null, null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setTimeoutAfter;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setTimeoutAfter(0L); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setUsesChronometer;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setUsesChronometer(false); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setVibrate;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setVibrate(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setVisibility;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setVisibility(0); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$Builder;true;setWhen;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.Builder out = null; + NotificationCompat.Builder in = (NotificationCompat.Builder) source(); + out = in.setWhen(0L); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$InboxStyle;true;addLine;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.InboxStyle out = null; + NotificationCompat.InboxStyle in = (NotificationCompat.InboxStyle) source(); + out = in.addLine(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$InboxStyle;true;setBigContentTitle;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.InboxStyle out = null; + NotificationCompat.InboxStyle in = (NotificationCompat.InboxStyle) source(); + out = in.setBigContentTitle(null); + sink(out); // $ hasValueFlow + } + { + // "androidx.core.app;NotificationCompat$InboxStyle;true;setSummaryText;;;Argument[-1];ReturnValue;value;manual" + NotificationCompat.InboxStyle out = null; + NotificationCompat.InboxStyle in = (NotificationCompat.InboxStyle) source(); + out = in.setSummaryText(null); + sink(out); // $ hasValueFlow + } } } diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationBuilderWithBuilderAccessor.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationBuilderWithBuilderAccessor.java new file mode 100644 index 00000000000..028807b3000 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationBuilderWithBuilderAccessor.java @@ -0,0 +1,10 @@ +// Generated automatically from androidx.core.app.NotificationBuilderWithBuilderAccessor for testing +// purposes + +package androidx.core.app; + +import android.app.Notification; + +public interface NotificationBuilderWithBuilderAccessor { + Notification.Builder getBuilder(); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationCompat.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationCompat.java new file mode 100644 index 00000000000..58beaab5b9c --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationCompat.java @@ -0,0 +1,720 @@ +// Generated automatically from androidx.core.app.NotificationCompat for testing purposes + +package androidx.core.app; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.widget.RemoteViews; +import androidx.core.app.NotificationBuilderWithBuilderAccessor; +import androidx.core.app.RemoteInput; +import androidx.core.graphics.drawable.IconCompat; +import java.util.ArrayList; +import java.util.List; + +public class NotificationCompat { + abstract static public class Style { + protected NotificationCompat.Builder mBuilder = null; + + protected void restoreFromCompatExtras(Bundle p0) {} + + public Bitmap createColoredBitmap(int p0, int p1) { + return null; + } + + public Notification build() { + return null; + } + + public RemoteViews applyStandardTemplate(boolean p0, int p1, boolean p2) { + return null; + } + + public RemoteViews makeBigContentView(NotificationBuilderWithBuilderAccessor p0) { + return null; + } + + public RemoteViews makeContentView(NotificationBuilderWithBuilderAccessor p0) { + return null; + } + + public RemoteViews makeHeadsUpContentView(NotificationBuilderWithBuilderAccessor p0) { + return null; + } + + public Style() {} + + public void addCompatExtras(Bundle p0) {} + + public void apply(NotificationBuilderWithBuilderAccessor p0) {} + + public void buildIntoRemoteViews(RemoteViews p0, RemoteViews p1) {} + + public void setBuilder(NotificationCompat.Builder p0) {} + } + + public NotificationCompat() {} + + public static Bundle getExtras(Notification p0) { + return null; + } + + public static CharSequence getContentTitle(Notification p0) { + return null; + } + + public static List getInvisibleActions(Notification p0) { + return null; + } + + public static NotificationCompat.Action getAction(Notification p0, int p1) { + return null; + } + + public static NotificationCompat.BubbleMetadata getBubbleMetadata(Notification p0) { + return null; + } + + public static String CATEGORY_ALARM = null; + public static String CATEGORY_CALL = null; + public static String CATEGORY_EMAIL = null; + public static String CATEGORY_ERROR = null; + public static String CATEGORY_EVENT = null; + public static String CATEGORY_MESSAGE = null; + public static String CATEGORY_NAVIGATION = null; + public static String CATEGORY_PROGRESS = null; + public static String CATEGORY_PROMO = null; + public static String CATEGORY_RECOMMENDATION = null; + public static String CATEGORY_REMINDER = null; + public static String CATEGORY_SERVICE = null; + public static String CATEGORY_SOCIAL = null; + public static String CATEGORY_STATUS = null; + public static String CATEGORY_SYSTEM = null; + public static String CATEGORY_TRANSPORT = null; + public static String EXTRA_AUDIO_CONTENTS_URI = null; + public static String EXTRA_BACKGROUND_IMAGE_URI = null; + public static String EXTRA_BIG_TEXT = null; + public static String EXTRA_CHRONOMETER_COUNT_DOWN = null; + public static String EXTRA_COMPACT_ACTIONS = null; + public static String EXTRA_CONVERSATION_TITLE = null; + public static String EXTRA_HIDDEN_CONVERSATION_TITLE = null; + public static String EXTRA_INFO_TEXT = null; + public static String EXTRA_IS_GROUP_CONVERSATION = null; + public static String EXTRA_LARGE_ICON = null; + public static String EXTRA_LARGE_ICON_BIG = null; + public static String EXTRA_MEDIA_SESSION = null; + public static String EXTRA_MESSAGES = null; + public static String EXTRA_MESSAGING_STYLE_USER = null; + public static String EXTRA_PEOPLE = null; + public static String EXTRA_PICTURE = null; + public static String EXTRA_PROGRESS = null; + public static String EXTRA_PROGRESS_INDETERMINATE = null; + public static String EXTRA_PROGRESS_MAX = null; + public static String EXTRA_REMOTE_INPUT_HISTORY = null; + public static String EXTRA_SELF_DISPLAY_NAME = null; + public static String EXTRA_SHOW_CHRONOMETER = null; + public static String EXTRA_SHOW_WHEN = null; + public static String EXTRA_SMALL_ICON = null; + public static String EXTRA_SUB_TEXT = null; + public static String EXTRA_SUMMARY_TEXT = null; + public static String EXTRA_TEMPLATE = null; + public static String EXTRA_TEXT = null; + public static String EXTRA_TEXT_LINES = null; + public static String EXTRA_TITLE = null; + public static String EXTRA_TITLE_BIG = null; + public static String GROUP_KEY_SILENT = null; + + public static String getCategory(Notification p0) { + return null; + } + + public static String getChannelId(Notification p0) { + return null; + } + + public static String getGroup(Notification p0) { + return null; + } + + public static String getShortcutId(Notification p0) { + return null; + } + + public static String getSortKey(Notification p0) { + return null; + } + + public static boolean getAllowSystemGeneratedContextualActions(Notification p0) { + return false; + } + + public static boolean getLocalOnly(Notification p0) { + return false; + } + + public static boolean isGroupSummary(Notification p0) { + return false; + } + + public static int BADGE_ICON_LARGE = 0; + public static int BADGE_ICON_NONE = 0; + public static int BADGE_ICON_SMALL = 0; + public static int COLOR_DEFAULT = 0; + public static int DEFAULT_ALL = 0; + public static int DEFAULT_LIGHTS = 0; + public static int DEFAULT_SOUND = 0; + public static int DEFAULT_VIBRATE = 0; + public static int FLAG_AUTO_CANCEL = 0; + public static int FLAG_BUBBLE = 0; + public static int FLAG_FOREGROUND_SERVICE = 0; + public static int FLAG_GROUP_SUMMARY = 0; + public static int FLAG_HIGH_PRIORITY = 0; + public static int FLAG_INSISTENT = 0; + public static int FLAG_LOCAL_ONLY = 0; + public static int FLAG_NO_CLEAR = 0; + public static int FLAG_ONGOING_EVENT = 0; + public static int FLAG_ONLY_ALERT_ONCE = 0; + public static int FLAG_SHOW_LIGHTS = 0; + public static int GROUP_ALERT_ALL = 0; + public static int GROUP_ALERT_CHILDREN = 0; + public static int GROUP_ALERT_SUMMARY = 0; + public static int PRIORITY_DEFAULT = 0; + public static int PRIORITY_HIGH = 0; + public static int PRIORITY_LOW = 0; + public static int PRIORITY_MAX = 0; + public static int PRIORITY_MIN = 0; + public static int STREAM_DEFAULT = 0; + public static int VISIBILITY_PRIVATE = 0; + public static int VISIBILITY_PUBLIC = 0; + public static int VISIBILITY_SECRET = 0; + + public static int getActionCount(Notification p0) { + return 0; + } + + public static int getBadgeIconType(Notification p0) { + return 0; + } + + public static int getGroupAlertBehavior(Notification p0) { + return 0; + } + + public static long getTimeoutAfter(Notification p0) { + return 0; + } + + static public class Action { + protected Action() {} + + public Action(IconCompat p0, CharSequence p1, PendingIntent p2) {} + + public Action(int p0, CharSequence p1, PendingIntent p2) {} + + public Bundle getExtras() { + return null; + } + + public CharSequence getTitle() { + return null; + } + + public CharSequence title = null; + + public IconCompat getIconCompat() { + return null; + } + + public PendingIntent actionIntent = null; + + public PendingIntent getActionIntent() { + return null; + } + + public RemoteInput[] getDataOnlyRemoteInputs() { + return null; + } + + public RemoteInput[] getRemoteInputs() { + return null; + } + + public boolean getAllowGeneratedReplies() { + return false; + } + + public boolean getShowsUserInterface() { + return false; + } + + public boolean isContextual() { + return false; + } + + public int getIcon() { + return 0; + } + + public int getSemanticAction() { + return 0; + } + + public int icon = 0; + public static int SEMANTIC_ACTION_ARCHIVE = 0; + public static int SEMANTIC_ACTION_CALL = 0; + public static int SEMANTIC_ACTION_DELETE = 0; + public static int SEMANTIC_ACTION_MARK_AS_READ = 0; + public static int SEMANTIC_ACTION_MARK_AS_UNREAD = 0; + public static int SEMANTIC_ACTION_MUTE = 0; + public static int SEMANTIC_ACTION_NONE = 0; + public static int SEMANTIC_ACTION_REPLY = 0; + public static int SEMANTIC_ACTION_THUMBS_DOWN = 0; + public static int SEMANTIC_ACTION_THUMBS_UP = 0; + public static int SEMANTIC_ACTION_UNMUTE = 0; + + static public class Builder { + protected Builder() {} + + public Builder(IconCompat p0, CharSequence p1, PendingIntent p2) {} + + public Builder(NotificationCompat.Action p0) {} + + public Builder(int p0, CharSequence p1, PendingIntent p2) {} + + public Bundle getExtras() { + return null; + } + + public NotificationCompat.Action build() { + return null; + } + + public NotificationCompat.Action.Builder addExtras(Bundle p0) { + return null; + } + + public NotificationCompat.Action.Builder addRemoteInput(RemoteInput p0) { + return null; + } + + public NotificationCompat.Action.Builder extend(NotificationCompat.Action.Extender p0) { + return null; + } + + public NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean p0) { + return null; + } + + public NotificationCompat.Action.Builder setContextual(boolean p0) { + return null; + } + + public NotificationCompat.Action.Builder setSemanticAction(int p0) { + return null; + } + + public NotificationCompat.Action.Builder setShowsUserInterface(boolean p0) { + return null; + } + } + static public interface Extender { + NotificationCompat.Action.Builder extend(NotificationCompat.Action.Builder p0); + } + } + static public class BigPictureStyle extends NotificationCompat.Style { + public BigPictureStyle() {} + + public BigPictureStyle(NotificationCompat.Builder p0) {} + + public NotificationCompat.BigPictureStyle bigLargeIcon(Bitmap p0) { + return null; + } + + public NotificationCompat.BigPictureStyle bigPicture(Bitmap p0) { + return null; + } + + public NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence p0) { + return null; + } + + public NotificationCompat.BigPictureStyle setSummaryText(CharSequence p0) { + return null; + } + + public void apply(NotificationBuilderWithBuilderAccessor p0) {} + } + static public class BigTextStyle extends NotificationCompat.Style { + public BigTextStyle() {} + + public BigTextStyle(NotificationCompat.Builder p0) {} + + public NotificationCompat.BigTextStyle bigText(CharSequence p0) { + return null; + } + + public NotificationCompat.BigTextStyle setBigContentTitle(CharSequence p0) { + return null; + } + + public NotificationCompat.BigTextStyle setSummaryText(CharSequence p0) { + return null; + } + + public void apply(NotificationBuilderWithBuilderAccessor p0) {} + } + static public class BubbleMetadata { + protected BubbleMetadata() {} + + public IconCompat getIcon() { + return null; + } + + public PendingIntent getDeleteIntent() { + return null; + } + + public PendingIntent getIntent() { + return null; + } + + public boolean getAutoExpandBubble() { + return false; + } + + public boolean isNotificationSuppressed() { + return false; + } + + public int getDesiredHeight() { + return 0; + } + + public int getDesiredHeightResId() { + return 0; + } + + public static Notification.BubbleMetadata toPlatform(NotificationCompat.BubbleMetadata p0) { + return null; + } + + public static NotificationCompat.BubbleMetadata fromPlatform( + Notification.BubbleMetadata p0) { + return null; + } + } + static public class Builder { + protected Builder() {} + + protected static CharSequence limitCharSequenceLength(CharSequence p0) { + return null; + } + + public ArrayList mActions = null; + public ArrayList mPeople = null; + + public Builder(Context p0) {} + + public Builder(Context p0, String p1) {} + + public Bundle getExtras() { + return null; + } + + public Context mContext = null; + + public Notification build() { + return null; + } + + public Notification getNotification() { + return null; + } + + public NotificationCompat.BubbleMetadata getBubbleMetadata() { + return null; + } + + public NotificationCompat.Builder addAction(NotificationCompat.Action p0) { + return null; + } + + public NotificationCompat.Builder addAction(int p0, CharSequence p1, PendingIntent p2) { + return null; + } + + public NotificationCompat.Builder addExtras(Bundle p0) { + return null; + } + + public NotificationCompat.Builder addInvisibleAction(NotificationCompat.Action p0) { + return null; + } + + public NotificationCompat.Builder addInvisibleAction(int p0, CharSequence p1, + PendingIntent p2) { + return null; + } + + public NotificationCompat.Builder addPerson(String p0) { + return null; + } + + public NotificationCompat.Builder extend(NotificationCompat.Extender p0) { + return null; + } + + public NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean p0) { + return null; + } + + public NotificationCompat.Builder setAutoCancel(boolean p0) { + return null; + } + + public NotificationCompat.Builder setBadgeIconType(int p0) { + return null; + } + + public NotificationCompat.Builder setBubbleMetadata(NotificationCompat.BubbleMetadata p0) { + return null; + } + + public NotificationCompat.Builder setCategory(String p0) { + return null; + } + + public NotificationCompat.Builder setChannelId(String p0) { + return null; + } + + public NotificationCompat.Builder setChronometerCountDown(boolean p0) { + return null; + } + + public NotificationCompat.Builder setColor(int p0) { + return null; + } + + public NotificationCompat.Builder setColorized(boolean p0) { + return null; + } + + public NotificationCompat.Builder setContent(RemoteViews p0) { + return null; + } + + public NotificationCompat.Builder setContentInfo(CharSequence p0) { + return null; + } + + public NotificationCompat.Builder setContentIntent(PendingIntent p0) { + return null; + } + + public NotificationCompat.Builder setContentText(CharSequence p0) { + return null; + } + + public NotificationCompat.Builder setContentTitle(CharSequence p0) { + return null; + } + + public NotificationCompat.Builder setCustomBigContentView(RemoteViews p0) { + return null; + } + + public NotificationCompat.Builder setCustomContentView(RemoteViews p0) { + return null; + } + + public NotificationCompat.Builder setCustomHeadsUpContentView(RemoteViews p0) { + return null; + } + + public NotificationCompat.Builder setDefaults(int p0) { + return null; + } + + public NotificationCompat.Builder setDeleteIntent(PendingIntent p0) { + return null; + } + + public NotificationCompat.Builder setExtras(Bundle p0) { + return null; + } + + public NotificationCompat.Builder setFullScreenIntent(PendingIntent p0, boolean p1) { + return null; + } + + public NotificationCompat.Builder setGroup(String p0) { + return null; + } + + public NotificationCompat.Builder setGroupAlertBehavior(int p0) { + return null; + } + + public NotificationCompat.Builder setGroupSummary(boolean p0) { + return null; + } + + public NotificationCompat.Builder setLargeIcon(Bitmap p0) { + return null; + } + + public NotificationCompat.Builder setLights(int p0, int p1, int p2) { + return null; + } + + public NotificationCompat.Builder setLocalOnly(boolean p0) { + return null; + } + + public NotificationCompat.Builder setNotificationSilent() { + return null; + } + + public NotificationCompat.Builder setNumber(int p0) { + return null; + } + + public NotificationCompat.Builder setOngoing(boolean p0) { + return null; + } + + public NotificationCompat.Builder setOnlyAlertOnce(boolean p0) { + return null; + } + + public NotificationCompat.Builder setPriority(int p0) { + return null; + } + + public NotificationCompat.Builder setProgress(int p0, int p1, boolean p2) { + return null; + } + + public NotificationCompat.Builder setPublicVersion(Notification p0) { + return null; + } + + public NotificationCompat.Builder setRemoteInputHistory(CharSequence[] p0) { + return null; + } + + public NotificationCompat.Builder setShortcutId(String p0) { + return null; + } + + public NotificationCompat.Builder setShowWhen(boolean p0) { + return null; + } + + public NotificationCompat.Builder setSmallIcon(int p0) { + return null; + } + + public NotificationCompat.Builder setSmallIcon(int p0, int p1) { + return null; + } + + public NotificationCompat.Builder setSortKey(String p0) { + return null; + } + + public NotificationCompat.Builder setSound(Uri p0) { + return null; + } + + public NotificationCompat.Builder setSound(Uri p0, int p1) { + return null; + } + + public NotificationCompat.Builder setStyle(NotificationCompat.Style p0) { + return null; + } + + public NotificationCompat.Builder setSubText(CharSequence p0) { + return null; + } + + public NotificationCompat.Builder setTicker(CharSequence p0) { + return null; + } + + public NotificationCompat.Builder setTicker(CharSequence p0, RemoteViews p1) { + return null; + } + + public NotificationCompat.Builder setTimeoutAfter(long p0) { + return null; + } + + public NotificationCompat.Builder setUsesChronometer(boolean p0) { + return null; + } + + public NotificationCompat.Builder setVibrate(long[] p0) { + return null; + } + + public NotificationCompat.Builder setVisibility(int p0) { + return null; + } + + public NotificationCompat.Builder setWhen(long p0) { + return null; + } + + public RemoteViews getBigContentView() { + return null; + } + + public RemoteViews getContentView() { + return null; + } + + public RemoteViews getHeadsUpContentView() { + return null; + } + + public int getColor() { + return 0; + } + + public int getPriority() { + return 0; + } + + public long getWhenIfShowing() { + return 0; + } + } + static public class InboxStyle extends NotificationCompat.Style { + public InboxStyle() {} + + public InboxStyle(NotificationCompat.Builder p0) {} + + public NotificationCompat.InboxStyle addLine(CharSequence p0) { + return null; + } + + public NotificationCompat.InboxStyle setBigContentTitle(CharSequence p0) { + return null; + } + + public NotificationCompat.InboxStyle setSummaryText(CharSequence p0) { + return null; + } + + public void apply(NotificationBuilderWithBuilderAccessor p0) {} + } + static public interface Extender { + NotificationCompat.Builder extend(NotificationCompat.Builder p0); + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/RemoteInput.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/RemoteInput.java new file mode 100644 index 00000000000..8f684095110 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/RemoteInput.java @@ -0,0 +1,71 @@ +// Generated automatically from androidx.core.app.RemoteInput for testing purposes + +package androidx.core.app; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import java.util.Map; +import java.util.Set; + +public class RemoteInput { + protected RemoteInput() {} + + public Bundle getExtras() { + return null; + } + + public CharSequence getLabel() { + return null; + } + + public CharSequence[] getChoices() { + return null; + } + + public Set getAllowedDataTypes() { + return null; + } + + public String getResultKey() { + return null; + } + + public boolean getAllowFreeFormInput() { + return false; + } + + public boolean isDataOnly() { + return false; + } + + public int getEditChoicesBeforeSending() { + return 0; + } + + public static Bundle getResultsFromIntent(Intent p0) { + return null; + } + + public static Map getDataResultsFromIntent(Intent p0, String p1) { + return null; + } + + public static String EXTRA_RESULTS_DATA = null; + public static String RESULTS_CLIP_LABEL = null; + public static int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; + public static int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 0; + public static int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 0; + public static int SOURCE_CHOICE = 0; + public static int SOURCE_FREE_FORM_INPUT = 0; + + public static int getResultsSource(Intent p0) { + return 0; + } + + public static void addDataResultToIntent(RemoteInput p0, Intent p1, Map p2) {} + + public static void addResultsToIntent(RemoteInput[] p0, Intent p1, Bundle p2) {} + + public static void setResultsSource(Intent p0, int p1) {} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/CustomVersionedParcelable.java b/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/CustomVersionedParcelable.java new file mode 100644 index 00000000000..8ffcfef8989 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/CustomVersionedParcelable.java @@ -0,0 +1,14 @@ +// Generated automatically from androidx.versionedparcelable.CustomVersionedParcelable for testing +// purposes + +package androidx.versionedparcelable; + +import androidx.versionedparcelable.VersionedParcelable; + +abstract public class CustomVersionedParcelable implements VersionedParcelable { + public CustomVersionedParcelable() {} + + public void onPostParceling() {} + + public void onPreParceling(boolean p0) {} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/VersionedParcelable.java b/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/VersionedParcelable.java new file mode 100644 index 00000000000..866f2e392ab --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/versionedparcelable/VersionedParcelable.java @@ -0,0 +1,8 @@ +// Generated automatically from androidx.versionedparcelable.VersionedParcelable for testing +// purposes + +package androidx.versionedparcelable; + + +public interface VersionedParcelable { +} From 0a83cedeb799780f587db8ab27299c3c1e1cffde Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 6 Sep 2022 13:52:43 -0400 Subject: [PATCH 047/203] Unit tests for android:allowBackup query --- .../CWE-312/AllowBackupEnabledTest.expected | 0 .../CWE-312/AllowBackupEnabledTest.java | 3 +++ .../CWE-312/AllowBackupEnabledTest.ql | 21 +++++++++++++++++++ .../security/CWE-312/AndroidManifest.xml | 2 +- 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.expected create mode 100644 java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java create mode 100644 java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.expected b/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java b/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java new file mode 100644 index 00000000000..f409a442f06 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java @@ -0,0 +1,3 @@ +class AllowBackupEnabledTest { + +} diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql b/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql new file mode 100644 index 00000000000..604f50dffa7 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql @@ -0,0 +1,21 @@ +import java +import semmle.code.xml.AndroidManifest +import TestUtilities.InlineExpectationsTest + +class AllowBackupEnabledTest extends InlineExpectationsTest { + AllowBackupEnabledTest() { this = "AllowBackupEnabledTest" } + + override string getARelevantTag() { result = "hasAllowBackupEnabled" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasAllowedBackupEnabled" and + exists(AndroidApplicationXmlElement androidAppElem | + androidAppElem.allowsBackup() and + not androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() + | + androidAppElem.getAttribute("allowBackup").getLocation() = location and + element = androidAppElem.getAttribute("debuggable").toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml index d8af1947bd7..8cf208d0a48 100644 --- a/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml +++ b/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml @@ -4,7 +4,7 @@ android:versionCode="1" android:versionName="0.1" > - + From dca4cd221a38200d0be54f5911002b4151986269 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 6 Sep 2022 14:35:11 -0400 Subject: [PATCH 048/203] Documentation cleanup for allowBackup query --- java/ql/lib/semmle/code/xml/AndroidManifest.qll | 2 +- .../src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index 155213212fc..0965025b969 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -74,7 +74,7 @@ class AndroidApplicationXmlElement extends XmlElement { predicate requiresPermissions() { this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull() } /** - * Holds if this application element enables the `android:allowBackup` attribute. + * Holds if this application element does not disable the `android:allowBackup` attribute. * * https://developer.android.com/guide/topics/data/autobackup */ diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index e8bd3487b00..42163f4107a 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -1,6 +1,6 @@ /** * @name Android allowBackup attribute enabled - * @description + * @description Android manifests which do not disable the `android:allowBackup` attribute allow backups, which can store sensitive information. * @kind problem * @problem.severity recommendation * @security-severity 7.5 @@ -17,8 +17,11 @@ from AndroidApplicationXmlElement androidAppElem where not androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() and ( + // explicitly sets android:allowBackup=true androidAppElem.allowsBackupExplicitly() or + // Manifest providing the main intent for an application, and does not explicitly + // disallow the allowBackup attribute androidAppElem.providesMainIntent() and androidAppElem.allowsBackup() ) From 46b7aa92aeca2f7f7c816b8f3a19e637c729d58a Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Sep 2022 13:19:05 +0200 Subject: [PATCH 049/203] deprecate predicates in `protocols.qll` that were only retained for backwards compatibility --- python/ql/lib/semmle/python/protocols.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/ql/lib/semmle/python/protocols.qll b/python/ql/lib/semmle/python/protocols.qll index f1f7e6a3ed7..fc341dadc33 100644 --- a/python/ql/lib/semmle/python/protocols.qll +++ b/python/ql/lib/semmle/python/protocols.qll @@ -1,19 +1,19 @@ import python /** Retained for backwards compatibility use ClassObject.isIterator() instead. */ -predicate is_iterator(ClassObject c) { c.isIterator() } +deprecated predicate is_iterator(ClassObject c) { c.isIterator() } /** Retained for backwards compatibility use ClassObject.isIterable() instead. */ -predicate is_iterable(ClassObject c) { c.isIterable() } +deprecated predicate is_iterable(ClassObject c) { c.isIterable() } /** Retained for backwards compatibility use ClassObject.isCollection() instead. */ -predicate is_collection(ClassObject c) { c.isCollection() } +deprecated predicate is_collection(ClassObject c) { c.isCollection() } /** Retained for backwards compatibility use ClassObject.isMapping() instead. */ -predicate is_mapping(ClassObject c) { c.isMapping() } +deprecated predicate is_mapping(ClassObject c) { c.isMapping() } /** Retained for backwards compatibility use ClassObject.isSequence() instead. */ -predicate is_sequence(ClassObject c) { c.isSequence() } +deprecated predicate is_sequence(ClassObject c) { c.isSequence() } /** Retained for backwards compatibility use ClassObject.isContextManager() instead. */ -predicate is_context_manager(ClassObject c) { c.isContextManager() } +deprecated predicate is_context_manager(ClassObject c) { c.isContextManager() } From 1cbf28358c07a0aaab4bd9d0054a6d82bc49af95 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Sep 2022 13:19:59 +0200 Subject: [PATCH 050/203] deprecate unused code inside the points-to library --- .../ql/lib/semmle/python/objects/TObject.qll | 6 ++- python/ql/lib/semmle/python/pointsto/Base.qll | 52 +++++++++++-------- .../ql/lib/semmle/python/pointsto/Filters.qll | 4 +- .../python/pointsto/PointsToContext.qll | 2 +- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/python/ql/lib/semmle/python/objects/TObject.qll b/python/ql/lib/semmle/python/objects/TObject.qll index ee6bcb8340d..58be33ddd91 100644 --- a/python/ql/lib/semmle/python/objects/TObject.qll +++ b/python/ql/lib/semmle/python/objects/TObject.qll @@ -334,7 +334,7 @@ predicate call3( } bindingset[self, function] -predicate method_binding( +deprecated predicate method_binding( AttrNode instantiation, ObjectInternal self, CallableObjectInternal function, PointsToContext context ) { @@ -357,7 +357,9 @@ predicate method_binding( /** Helper for method_binding */ pragma[noinline] -predicate receiver(AttrNode instantiation, PointsToContext context, ObjectInternal obj, string name) { +deprecated predicate receiver( + AttrNode instantiation, PointsToContext context, ObjectInternal obj, string name +) { PointsToInternal::pointsTo(instantiation.getObject(name), context, obj, _) } diff --git a/python/ql/lib/semmle/python/pointsto/Base.qll b/python/ql/lib/semmle/python/pointsto/Base.qll index adc2abedaa0..a3407419da2 100644 --- a/python/ql/lib/semmle/python/pointsto/Base.qll +++ b/python/ql/lib/semmle/python/pointsto/Base.qll @@ -13,7 +13,7 @@ import semmle.python.essa.SsaDefinitions private import semmle.python.types.Builtins private import semmle.python.internal.CachedStages -module BasePointsTo { +deprecated module BasePointsTo { /** INTERNAL -- Use n.refersTo(value, _, origin) instead */ pragma[noinline] predicate points_to(ControlFlowNode f, Object value, ControlFlowNode origin) { @@ -27,13 +27,13 @@ module BasePointsTo { } /** Gets the kwargs parameter (`**kwargs`). In a function definition this is always a dict. */ -predicate kwargs_points_to(ControlFlowNode f, ClassObject cls) { +deprecated predicate kwargs_points_to(ControlFlowNode f, ClassObject cls) { exists(Function func | func.getKwarg() = f.getNode()) and cls = theDictType() } /** Gets the varargs parameter (`*varargs`). In a function definition this is always a tuple. */ -predicate varargs_points_to(ControlFlowNode f, ClassObject cls) { +deprecated predicate varargs_points_to(ControlFlowNode f, ClassObject cls) { exists(Function func | func.getVararg() = f.getNode()) and cls = theTupleType() } @@ -45,7 +45,7 @@ predicate varargs_points_to(ControlFlowNode f, ClassObject cls) { * This exists primarily for internal use. Use getAnInferredType() instead. */ pragma[noinline] -ClassObject simple_types(Object obj) { +deprecated ClassObject simple_types(Object obj) { result = comprehension(obj.getOrigin()) or result = collection_literal(obj.getOrigin()) @@ -59,7 +59,7 @@ ClassObject simple_types(Object obj) { obj = unknownValue() and result = theUnknownType() } -private ClassObject comprehension(Expr e) { +deprecated private ClassObject comprehension(Expr e) { e instanceof ListComp and result = theListType() or e instanceof SetComp and result = theSetType() @@ -69,7 +69,7 @@ private ClassObject comprehension(Expr e) { e instanceof GeneratorExp and result = theGeneratorType() } -private ClassObject collection_literal(Expr e) { +deprecated private ClassObject collection_literal(Expr e) { e instanceof List and result = theListType() or e instanceof Set and result = theSetType() @@ -79,7 +79,7 @@ private ClassObject collection_literal(Expr e) { e instanceof Tuple and result = theTupleType() } -private int tuple_index_value(Object t, int i) { +deprecated private int tuple_index_value(Object t, int i) { result = t.(TupleNode).getElement(i).getNode().(Num).getN().toInt() or exists(Object item | @@ -89,7 +89,7 @@ private int tuple_index_value(Object t, int i) { } pragma[noinline] -int version_tuple_value(Object t) { +deprecated int version_tuple_value(Object t) { not exists(tuple_index_value(t, 1)) and result = tuple_index_value(t, 0) * 10 or not exists(tuple_index_value(t, 2)) and @@ -102,7 +102,7 @@ int version_tuple_value(Object t) { } /** Choose a version numbers that represent the extreme of supported versions. */ -private int major_minor() { +deprecated private int major_minor() { if major_version() = 3 then ( result = 33 or result = 37 @@ -113,7 +113,7 @@ private int major_minor() { } /** Compares the given tuple object to both the maximum and minimum possible sys.version_info values */ -int version_tuple_compare(Object t) { +deprecated int version_tuple_compare(Object t) { version_tuple_value(t) < major_minor() and result = -1 or version_tuple_value(t) = major_minor() and result = 0 @@ -122,7 +122,7 @@ int version_tuple_compare(Object t) { } /** Holds if `cls` is a new-style class if it were to have no explicit base classes */ -predicate baseless_is_new_style(ClassObject cls) { +deprecated predicate baseless_is_new_style(ClassObject cls) { cls.isBuiltin() or major_version() = 3 and exists(cls) @@ -160,7 +160,7 @@ private predicate class_defines_name(Class cls, string name) { } /** Gets a return value CFG node, provided that is safe to track across returns */ -ControlFlowNode safe_return_node(PyFunctionObject func) { +deprecated ControlFlowNode safe_return_node(PyFunctionObject func) { result = func.getAReturnedNode() and // Not a parameter not exists(Parameter p, SsaVariable pvar | @@ -172,7 +172,7 @@ ControlFlowNode safe_return_node(PyFunctionObject func) { } /** Holds if it can be determined from the control flow graph alone that this function can never return */ -predicate function_can_never_return(FunctionObject func) { +deprecated predicate function_can_never_return(FunctionObject func) { /* * A Python function never returns if it has no normal exits that are not dominated by a * call to a function which itself never returns. @@ -188,7 +188,9 @@ predicate function_can_never_return(FunctionObject func) { /** Hold if outer contains inner, both are contained within a test and inner is a use is a plain use or an attribute lookup */ pragma[noinline] -predicate contains_interesting_expression_within_test(ControlFlowNode outer, ControlFlowNode inner) { +deprecated predicate contains_interesting_expression_within_test( + ControlFlowNode outer, ControlFlowNode inner +) { inner.isLoad() and exists(ControlFlowNode test | outer.getAChild*() = inner and @@ -208,7 +210,7 @@ predicate test_contains(ControlFlowNode expr, ControlFlowNode use) { } /** Holds if `test` is a test (a branch), `use` is within that test and `def` is an edge from that test with `sense` */ -predicate refinement_test( +deprecated predicate refinement_test( ControlFlowNode test, ControlFlowNode use, boolean sense, PyEdgeRefinement def ) { /* @@ -224,7 +226,7 @@ predicate refinement_test( /** Holds if `f` is an import of the form `from .[...] import name` and the enclosing scope is an __init__ module */ pragma[noinline] -predicate live_import_from_dot_in_init(ImportMemberNode f, EssaVariable var) { +deprecated predicate live_import_from_dot_in_init(ImportMemberNode f, EssaVariable var) { exists(string name | import_from_dot_in_init(f.getModule(name)) and var.getSourceVariable().getName() = name and @@ -249,13 +251,13 @@ Object undefinedVariable() { py_special_objects(result, "_semmle_undefined_value /** Gets the pseudo-object representing an unknown value */ Object unknownValue() { result.asBuiltin() = Builtin::unknown() } -BuiltinCallable theTypeNewMethod() { +deprecated BuiltinCallable theTypeNewMethod() { result.asBuiltin() = theTypeType().asBuiltin().getMember("__new__") } /** Gets the `value, cls, origin` that `f` would refer to if it has not been assigned some other value */ pragma[noinline] -predicate potential_builtin_points_to( +deprecated predicate potential_builtin_points_to( NameNode f, Object value, ClassObject cls, ControlFlowNode origin ) { f.isGlobal() and @@ -269,7 +271,7 @@ predicate potential_builtin_points_to( } pragma[noinline] -predicate builtin_name_points_to(string name, Object value, ClassObject cls) { +deprecated predicate builtin_name_points_to(string name, Object value, ClassObject cls) { value = Object::builtin(name) and cls.asBuiltin() = value.asBuiltin().getClass() } @@ -331,7 +333,9 @@ module BaseFlow { } /** Points-to for syntactic elements where context is not relevant */ -predicate simple_points_to(ControlFlowNode f, Object value, ClassObject cls, ControlFlowNode origin) { +deprecated predicate simple_points_to( + ControlFlowNode f, Object value, ClassObject cls, ControlFlowNode origin +) { kwargs_points_to(f, cls) and value = f and origin = f or varargs_points_to(f, cls) and value = f and origin = f @@ -347,7 +351,9 @@ predicate simple_points_to(ControlFlowNode f, Object value, ClassObject cls, Con * Holds if `bit` is a binary expression node with a bitwise operator. * Helper for `this_binary_expr_points_to`. */ -predicate bitwise_expression_node(BinaryExprNode bit, ControlFlowNode left, ControlFlowNode right) { +deprecated predicate bitwise_expression_node( + BinaryExprNode bit, ControlFlowNode left, ControlFlowNode right +) { exists(Operator op | op = bit.getNode().getOp() | op instanceof BitAnd or op instanceof BitOr or @@ -357,13 +363,13 @@ predicate bitwise_expression_node(BinaryExprNode bit, ControlFlowNode left, Cont right = bit.getRight() } -private Module theCollectionsAbcModule() { +deprecated private Module theCollectionsAbcModule() { result.getName() = "_abcoll" or result.getName() = "_collections_abc" } -ClassObject collectionsAbcClass(string name) { +deprecated ClassObject collectionsAbcClass(string name) { exists(Class cls | result.getPyClass() = cls and cls.getName() = name and diff --git a/python/ql/lib/semmle/python/pointsto/Filters.qll b/python/ql/lib/semmle/python/pointsto/Filters.qll index 117845d3c7f..dbf9baf5279 100644 --- a/python/ql/lib/semmle/python/pointsto/Filters.qll +++ b/python/ql/lib/semmle/python/pointsto/Filters.qll @@ -13,7 +13,7 @@ predicate hasattr(CallNode c, ControlFlowNode obj, string attr) { } /** Holds if `c` is a call to `callable(obj)`. */ -predicate is_callable(CallNode c, ControlFlowNode obj) { +deprecated predicate is_callable(CallNode c, ControlFlowNode obj) { c.getFunction().(NameNode).getId() = "callable" and obj = c.getArg(0) } @@ -26,7 +26,7 @@ predicate isinstance(CallNode fc, ControlFlowNode cls, ControlFlowNode use) { } /** Holds if `c` is a call to `issubclass(use, cls)`. */ -predicate issubclass(CallNode fc, ControlFlowNode cls, ControlFlowNode use) { +deprecated predicate issubclass(CallNode fc, ControlFlowNode cls, ControlFlowNode use) { fc.getFunction().(NameNode).getId() = "issubclass" and fc.getArg(0) = use and cls = fc.getArg(1) diff --git a/python/ql/lib/semmle/python/pointsto/PointsToContext.qll b/python/ql/lib/semmle/python/pointsto/PointsToContext.qll index ad86a49ba6f..a63381e5e20 100644 --- a/python/ql/lib/semmle/python/pointsto/PointsToContext.qll +++ b/python/ql/lib/semmle/python/pointsto/PointsToContext.qll @@ -122,7 +122,7 @@ private newtype TPointsToContext = } or TObjectContext(SelfInstanceInternal object) -module Context { +deprecated module Context { PointsToContext forObject(ObjectInternal object) { result = TObjectContext(object) } } From 283c711de9f1449142012deac3daccef9a54cd6b Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 6 Sep 2022 13:21:48 +0200 Subject: [PATCH 051/203] deprecate unused predicate inside the `essa` module --- python/ql/lib/semmle/python/essa/SsaDefinitions.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/essa/SsaDefinitions.qll b/python/ql/lib/semmle/python/essa/SsaDefinitions.qll index 810afc3179a..4896016eb78 100644 --- a/python/ql/lib/semmle/python/essa/SsaDefinitions.qll +++ b/python/ql/lib/semmle/python/essa/SsaDefinitions.qll @@ -78,7 +78,9 @@ module SsaSource { /** Holds if `v` is defined by a `for` statement, the definition being `defn` */ cached - predicate iteration_defined_variable(Variable v, ControlFlowNode defn, ControlFlowNode sequence) { + deprecated predicate iteration_defined_variable( + Variable v, ControlFlowNode defn, ControlFlowNode sequence + ) { exists(ForNode for | for.iterates(defn, sequence)) and defn.(NameNode).defines(v) } From 0cfb49102bd72d48378a20256143054f9dc80f69 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 7 Sep 2022 09:30:42 +0200 Subject: [PATCH 052/203] Python: fix non-US spelling --- python/ql/src/Exceptions/UnguardedNextInGenerator.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql index 890df3374d9..0bd49f2c8c8 100644 --- a/python/ql/src/Exceptions/UnguardedNextInGenerator.ql +++ b/python/ql/src/Exceptions/UnguardedNextInGenerator.ql @@ -70,7 +70,7 @@ where // PEP 479 removes this concern from 3.7 onwards // see: https://peps.python.org/pep-0479/ // - // However, we do not know the minor version of the analysed code (only of the extractor), + // However, we do not know the minor version of the analyzed code (only of the extractor), // so we only alert on Python 2. major_version() = 2 select call, "Call to next() in a generator" From 07038d0b3a91ab2715de278732071fb7ff728683 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 7 Sep 2022 10:48:22 +0200 Subject: [PATCH 053/203] Fix QL formatting --- java/ql/test/kotlin/library-tests/vararg/args.ql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/vararg/args.ql b/java/ql/test/kotlin/library-tests/vararg/args.ql index 510ea0c2682..4173094463b 100644 --- a/java/ql/test/kotlin/library-tests/vararg/args.ql +++ b/java/ql/test/kotlin/library-tests/vararg/args.ql @@ -1,9 +1,7 @@ import java import semmle.code.java.Diagnostics -query predicate diag(Diagnostic d) { - d.getMessage() = "Unexpected IrVararg" -} +query predicate diag(Diagnostic d) { d.getMessage() = "Unexpected IrVararg" } query predicate varargsParams(Parameter p, Type t) { p.getCallable().fromSource() and From 8e0b4892eec1462098984ea2757ad036713c4c6a Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 7 Sep 2022 10:48:44 +0200 Subject: [PATCH 054/203] Add Implicit PendingIntents sinks for Compat classes --- ...07-implicit-pendingintents-compat-sinks.md | 5 ++ .../java/security/ImplicitPendingIntents.qll | 6 +++ .../CWE-927/ImplicitPendingIntentsTest.java | 31 ++++++++++-- .../android/app/AppComponentFactory.java | 22 +++++++++ .../android/app/AutomaticZenRule.java | 37 +++++++++++++++ .../service/notification/Condition.java | 41 ++++++++++++++++ .../notification/StatusBarNotification.java | 37 +++++++++++++++ .../service/notification/ZenPolicy.java | 47 +++++++++++++++++++ .../androidx/core/app/AlarmManagerCompat.java | 15 ++++++ .../core/app/CoreComponentFactory.java | 25 ++++++++++ .../core/app/NotificationManagerCompat.java | 43 +++++++++++++++++ .../remotecallback/CallbackReceiver.java | 10 ++++ .../androidx/slice/Clock.java | 9 ++++ .../builders/impl/TemplateBuilderImpl.java | 23 +++++++++ .../slice/compat/CompatPermissionManager.java | 16 +++++++ 15 files changed, 363 insertions(+), 4 deletions(-) create mode 100644 java/ql/lib/change-notes/2022-09-07-implicit-pendingintents-compat-sinks.md create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/app/AppComponentFactory.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/app/AutomaticZenRule.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/service/notification/Condition.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/service/notification/StatusBarNotification.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/service/notification/ZenPolicy.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/AlarmManagerCompat.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/CoreComponentFactory.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationManagerCompat.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/remotecallback/CallbackReceiver.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/slice/Clock.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/slice/builders/impl/TemplateBuilderImpl.java create mode 100644 java/ql/test/stubs/google-android-9.0.0/androidx/slice/compat/CompatPermissionManager.java diff --git a/java/ql/lib/change-notes/2022-09-07-implicit-pendingintents-compat-sinks.md b/java/ql/lib/change-notes/2022-09-07-implicit-pendingintents-compat-sinks.md new file mode 100644 index 00000000000..a1ae10ac7d5 --- /dev/null +++ b/java/ql/lib/change-notes/2022-09-07-implicit-pendingintents-compat-sinks.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Added new sinks to the query `java/android/implict-pendingintents` to take into account the classes `androidx.core.app.NotificationManagerCompat` and `androidx.core.app.AlarmManagerCompat`. + \ No newline at end of file diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 540b28445e5..3441cfaef18 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -102,6 +102,8 @@ private class PendingIntentSentSinkModels extends SinkModelCsv { "android.app;NotificationManager;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", "android.app;NotificationManager;true;notifyAsPackage;(String,String,int,Notification);;Argument[3];pending-intent-sent;manual", "android.app;NotificationManager;true;notifyAsUser;(String,int,Notification,UserHandle);;Argument[2];pending-intent-sent;manual", + "androidx.core.app;NotificationManagerCompat;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual", + "androidx.core.app;NotificationManagerCompat;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual", "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String,Bundle);;Argument[2];pending-intent-sent;manual", "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String);;Argument[2];pending-intent-sent;manual", "android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler);;Argument[2];pending-intent-sent;manual", @@ -115,6 +117,10 @@ private class PendingIntentSentSinkModels extends SinkModelCsv { "android.app;AlarmManager;true;setInexactRepeating;;;Argument[3];pending-intent-sent;manual", "android.app;AlarmManager;true;setRepeating;;;Argument[3];pending-intent-sent;manual", "android.app;AlarmManager;true;setWindow;(int,long,long,PendingIntent);;Argument[3];pending-intent-sent;manual", + "androidx.core.app;AlarmManagerCompat;true;setAlarmClock;;;Argument[2..3];pending-intent-sent;manual", + "androidx.core.app;AlarmManagerCompat;true;setAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", + "androidx.core.app;AlarmManagerCompat;true;setExact;;;Argument[3];pending-intent-sent;manual", + "androidx.core.app;AlarmManagerCompat;true;setExactAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual", ] } } diff --git a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java index 3896a20799e..9c8f098d467 100644 --- a/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java +++ b/java/ql/test/query-tests/security/CWE-927/ImplicitPendingIntentsTest.java @@ -14,6 +14,8 @@ import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; import android.os.RemoteException; +import androidx.core.app.AlarmManagerCompat; +import androidx.core.app.NotificationManagerCompat; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceProvider; @@ -182,7 +184,7 @@ public class ImplicitPendingIntentsTest { Notification.Builder nBuilder = new Notification.Builder(ctx).addAction(aBuilder.build()); Notification notification = nBuilder.build(); - NotificationManager nManager = new NotificationManager(); + NotificationManager nManager = null; nManager.notifyAsPackage("targetPackage", "tag", 0, notification); // $hasImplicitPendingIntent nManager.notify(0, notification); // $hasImplicitPendingIntent nManager.notifyAsUser("", 0, notification, null); // $hasImplicitPendingIntent @@ -195,7 +197,7 @@ public class ImplicitPendingIntentsTest { Notification.Builder nBuilder = new Notification.Builder(ctx).addAction(aBuilder.build()); Notification notification = nBuilder.build(); - NotificationManager nManager = new NotificationManager(); + NotificationManager nManager = null; nManager.notify(0, notification); // Safe } { @@ -212,10 +214,21 @@ public class ImplicitPendingIntentsTest { Notification.Action action = new Notification.Action(0, "", pi2); Notification.Builder nBuilder = new Notification.Builder(ctx).addAction(action); Notification notification = nBuilder.build(); - NotificationManager noMan = new NotificationManager(); + NotificationManager noMan = null; noMan.notify(0, notification); // Safe } - + // Compat sinks + { + Intent baseIntent = new Intent(); + PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, 0); + Notification.Action.Builder aBuilder = new Notification.Action.Builder(0, "", pi); + Notification.Builder nBuilder = + new Notification.Builder(ctx).addAction(aBuilder.build()); + Notification notification = nBuilder.build(); + NotificationManagerCompat nManager = null; + nManager.notify(0, notification); // $hasImplicitPendingIntent + nManager.notify("", 0, notification); // $hasImplicitPendingIntent + } } public static void testPendingIntentInAnAlarm(Context ctx) { @@ -238,6 +251,16 @@ public class ImplicitPendingIntentsTest { PendingIntent.getActivity(ctx, 0, baseIntent, PendingIntent.FLAG_IMMUTABLE); // Sanitizer aManager.set(0, 0, pi); // Safe } + // Compat sinks + { + Intent baseIntent = new Intent(); + PendingIntent pi = PendingIntent.getActivity(ctx, 0, baseIntent, 0); + AlarmManagerCompat.setAlarmClock(aManager, 0, pi, null); // $hasImplicitPendingIntent + AlarmManagerCompat.setAlarmClock(aManager, 0, null, pi); // $hasImplicitPendingIntent + AlarmManagerCompat.setAndAllowWhileIdle(aManager, 0, 0, pi); // $hasImplicitPendingIntent + AlarmManagerCompat.setExact(aManager, 0, 0, pi); // $hasImplicitPendingIntent + AlarmManagerCompat.setExactAndAllowWhileIdle(aManager, 0, 0, pi); // $hasImplicitPendingIntent + } } static class TestActivity extends Activity { diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/AppComponentFactory.java b/java/ql/test/stubs/google-android-9.0.0/android/app/AppComponentFactory.java new file mode 100644 index 00000000000..284510fc655 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/AppComponentFactory.java @@ -0,0 +1,22 @@ +// Generated automatically from android.app.AppComponentFactory for testing purposes + +package android.app; + +import android.app.Activity; +import android.app.Application; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.ContentProvider; +import android.content.Intent; +import android.content.pm.ApplicationInfo; + +public class AppComponentFactory +{ + public Activity instantiateActivity(ClassLoader p0, String p1, Intent p2){ return null; } + public AppComponentFactory(){} + public Application instantiateApplication(ClassLoader p0, String p1){ return null; } + public BroadcastReceiver instantiateReceiver(ClassLoader p0, String p1, Intent p2){ return null; } + public ClassLoader instantiateClassLoader(ClassLoader p0, ApplicationInfo p1){ return null; } + public ContentProvider instantiateProvider(ClassLoader p0, String p1){ return null; } + public Service instantiateService(ClassLoader p0, String p1, Intent p2){ return null; } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/AutomaticZenRule.java b/java/ql/test/stubs/google-android-9.0.0/android/app/AutomaticZenRule.java new file mode 100644 index 00000000000..3b97a1eca2d --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/AutomaticZenRule.java @@ -0,0 +1,37 @@ +// Generated automatically from android.app.AutomaticZenRule for testing purposes + +package android.app; + +import android.content.ComponentName; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.service.notification.ZenPolicy; + +public class AutomaticZenRule implements Parcelable +{ + protected AutomaticZenRule() {} + public AutomaticZenRule(Parcel p0){} + public AutomaticZenRule(String p0, ComponentName p1, ComponentName p2, Uri p3, ZenPolicy p4, int p5, boolean p6){} + public AutomaticZenRule(String p0, ComponentName p1, Uri p2, int p3, boolean p4){} + public ComponentName getConfigurationActivity(){ return null; } + public ComponentName getOwner(){ return null; } + public String getName(){ return null; } + public String toString(){ return null; } + public Uri getConditionId(){ return null; } + public ZenPolicy getZenPolicy(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isEnabled(){ return false; } + public int describeContents(){ return 0; } + public int getInterruptionFilter(){ return 0; } + public int hashCode(){ return 0; } + public long getCreationTime(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void setConditionId(Uri p0){} + public void setConfigurationActivity(ComponentName p0){} + public void setEnabled(boolean p0){} + public void setInterruptionFilter(int p0){} + public void setName(String p0){} + public void setZenPolicy(ZenPolicy p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/service/notification/Condition.java b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/Condition.java new file mode 100644 index 00000000000..a7f94f23c42 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/Condition.java @@ -0,0 +1,41 @@ +// Generated automatically from android.service.notification.Condition for testing purposes + +package android.service.notification; + +import android.content.Context; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; + +public class Condition implements Parcelable +{ + protected Condition() {} + public Condition copy(){ return null; } + public Condition(Parcel p0){} + public Condition(Uri p0, String p1, String p2, String p3, int p4, int p5, int p6){} + public Condition(Uri p0, String p1, int p2){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public final String line1 = null; + public final String line2 = null; + public final String summary = null; + public final Uri id = null; + public final int flags = 0; + public final int icon = 0; + public final int state = 0; + public int describeContents(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static String SCHEME = null; + public static String relevanceToString(int p0){ return null; } + public static String stateToString(int p0){ return null; } + public static Uri.Builder newId(Context p0){ return null; } + public static boolean isValidId(Uri p0, String p1){ return false; } + public static int FLAG_RELEVANT_ALWAYS = 0; + public static int FLAG_RELEVANT_NOW = 0; + public static int STATE_ERROR = 0; + public static int STATE_FALSE = 0; + public static int STATE_TRUE = 0; + public static int STATE_UNKNOWN = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/service/notification/StatusBarNotification.java b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/StatusBarNotification.java new file mode 100644 index 00000000000..e360a5ad3f1 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/StatusBarNotification.java @@ -0,0 +1,37 @@ +// Generated automatically from android.service.notification.StatusBarNotification for testing purposes + +package android.service.notification; + +import android.app.Notification; +import android.os.Parcel; +import android.os.Parcelable; +import android.os.UserHandle; + +public class StatusBarNotification implements Parcelable +{ + protected StatusBarNotification() {} + public Notification getNotification(){ return null; } + public StatusBarNotification clone(){ return null; } + public StatusBarNotification(Parcel p0){} + public StatusBarNotification(String p0, String p1, int p2, String p3, int p4, int p5, int p6, Notification p7, UserHandle p8, long p9){} + public String getGroupKey(){ return null; } + public String getKey(){ return null; } + public String getOpPkg(){ return null; } + public String getOverrideGroupKey(){ return null; } + public String getPackageName(){ return null; } + public String getTag(){ return null; } + public String toString(){ return null; } + public UserHandle getUser(){ return null; } + public boolean isAppGroup(){ return false; } + public boolean isClearable(){ return false; } + public boolean isGroup(){ return false; } + public boolean isOngoing(){ return false; } + public int describeContents(){ return 0; } + public int getId(){ return 0; } + public int getUid(){ return 0; } + public int getUserId(){ return 0; } + public long getPostTime(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public void setOverrideGroupKey(String p0){} + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/service/notification/ZenPolicy.java b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/ZenPolicy.java new file mode 100644 index 00000000000..81c52b0c18a --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/service/notification/ZenPolicy.java @@ -0,0 +1,47 @@ +// Generated automatically from android.service.notification.ZenPolicy for testing purposes + +package android.service.notification; + +import android.os.Parcel; +import android.os.Parcelable; + +public class ZenPolicy implements Parcelable +{ + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int describeContents(){ return 0; } + public int getPriorityCallSenders(){ return 0; } + public int getPriorityCategoryAlarms(){ return 0; } + public int getPriorityCategoryCalls(){ return 0; } + public int getPriorityCategoryConversations(){ return 0; } + public int getPriorityCategoryEvents(){ return 0; } + public int getPriorityCategoryMedia(){ return 0; } + public int getPriorityCategoryMessages(){ return 0; } + public int getPriorityCategoryReminders(){ return 0; } + public int getPriorityCategoryRepeatCallers(){ return 0; } + public int getPriorityCategorySystem(){ return 0; } + public int getPriorityConversationSenders(){ return 0; } + public int getPriorityMessageSenders(){ return 0; } + public int getVisualEffectAmbient(){ return 0; } + public int getVisualEffectBadge(){ return 0; } + public int getVisualEffectFullScreenIntent(){ return 0; } + public int getVisualEffectLights(){ return 0; } + public int getVisualEffectNotificationList(){ return 0; } + public int getVisualEffectPeek(){ return 0; } + public int getVisualEffectStatusBar(){ return 0; } + public int hashCode(){ return 0; } + public static Parcelable.Creator CREATOR = null; + public static int CONVERSATION_SENDERS_ANYONE = 0; + public static int CONVERSATION_SENDERS_IMPORTANT = 0; + public static int CONVERSATION_SENDERS_NONE = 0; + public static int CONVERSATION_SENDERS_UNSET = 0; + public static int PEOPLE_TYPE_ANYONE = 0; + public static int PEOPLE_TYPE_CONTACTS = 0; + public static int PEOPLE_TYPE_NONE = 0; + public static int PEOPLE_TYPE_STARRED = 0; + public static int PEOPLE_TYPE_UNSET = 0; + public static int STATE_ALLOW = 0; + public static int STATE_DISALLOW = 0; + public static int STATE_UNSET = 0; + public void writeToParcel(Parcel p0, int p1){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/AlarmManagerCompat.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/AlarmManagerCompat.java new file mode 100644 index 00000000000..adaf14a156b --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/AlarmManagerCompat.java @@ -0,0 +1,15 @@ +// Generated automatically from androidx.core.app.AlarmManagerCompat for testing purposes + +package androidx.core.app; + +import android.app.AlarmManager; +import android.app.PendingIntent; + +public class AlarmManagerCompat +{ + protected AlarmManagerCompat() {} + public static void setAlarmClock(AlarmManager p0, long p1, PendingIntent p2, PendingIntent p3){} + public static void setAndAllowWhileIdle(AlarmManager p0, int p1, long p2, PendingIntent p3){} + public static void setExact(AlarmManager p0, int p1, long p2, PendingIntent p3){} + public static void setExactAndAllowWhileIdle(AlarmManager p0, int p1, long p2, PendingIntent p3){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/CoreComponentFactory.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/CoreComponentFactory.java new file mode 100644 index 00000000000..699156f3441 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/CoreComponentFactory.java @@ -0,0 +1,25 @@ +// Generated automatically from androidx.core.app.CoreComponentFactory for testing purposes + +package androidx.core.app; + +import android.app.Activity; +import android.app.AppComponentFactory; +import android.app.Application; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.ContentProvider; +import android.content.Intent; + +public class CoreComponentFactory extends AppComponentFactory +{ + public Activity instantiateActivity(ClassLoader p0, String p1, Intent p2){ return null; } + public Application instantiateApplication(ClassLoader p0, String p1){ return null; } + public BroadcastReceiver instantiateReceiver(ClassLoader p0, String p1, Intent p2){ return null; } + public ContentProvider instantiateProvider(ClassLoader p0, String p1){ return null; } + public CoreComponentFactory(){} + public Service instantiateService(ClassLoader p0, String p1, Intent p2){ return null; } + static public interface CompatWrapped + { + Object getWrapper(); + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationManagerCompat.java b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationManagerCompat.java new file mode 100644 index 00000000000..184c3cd25c7 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/core/app/NotificationManagerCompat.java @@ -0,0 +1,43 @@ +// Generated automatically from androidx.core.app.NotificationManagerCompat for testing purposes + +package androidx.core.app; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationChannelGroup; +import android.content.Context; +import java.util.List; +import java.util.Set; + +public class NotificationManagerCompat +{ + protected NotificationManagerCompat() {} + public List getNotificationChannels(){ return null; } + public List getNotificationChannelGroups(){ return null; } + public NotificationChannel getNotificationChannel(String p0){ return null; } + public NotificationChannelGroup getNotificationChannelGroup(String p0){ return null; } + public boolean areNotificationsEnabled(){ return false; } + public int getImportance(){ return 0; } + public static NotificationManagerCompat from(Context p0){ return null; } + public static Set getEnabledListenerPackages(Context p0){ return null; } + public static String ACTION_BIND_SIDE_CHANNEL = null; + public static String EXTRA_USE_SIDE_CHANNEL = null; + public static int IMPORTANCE_DEFAULT = 0; + public static int IMPORTANCE_HIGH = 0; + public static int IMPORTANCE_LOW = 0; + public static int IMPORTANCE_MAX = 0; + public static int IMPORTANCE_MIN = 0; + public static int IMPORTANCE_NONE = 0; + public static int IMPORTANCE_UNSPECIFIED = 0; + public void cancel(String p0, int p1){} + public void cancel(int p0){} + public void cancelAll(){} + public void createNotificationChannel(NotificationChannel p0){} + public void createNotificationChannelGroup(NotificationChannelGroup p0){} + public void createNotificationChannelGroups(List p0){} + public void createNotificationChannels(List p0){} + public void deleteNotificationChannel(String p0){} + public void deleteNotificationChannelGroup(String p0){} + public void notify(String p0, int p1, Notification p2){} + public void notify(int p0, Notification p1){} +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/remotecallback/CallbackReceiver.java b/java/ql/test/stubs/google-android-9.0.0/androidx/remotecallback/CallbackReceiver.java new file mode 100644 index 00000000000..3215fe270d8 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/remotecallback/CallbackReceiver.java @@ -0,0 +1,10 @@ +// Generated automatically from androidx.remotecallback.CallbackReceiver for testing purposes + +package androidx.remotecallback; + +import android.content.Context; + +public interface CallbackReceiver +{ + T createRemoteCallback(Context p0); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/slice/Clock.java b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/Clock.java new file mode 100644 index 00000000000..4aed87209c6 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/Clock.java @@ -0,0 +1,9 @@ +// Generated automatically from androidx.slice.Clock for testing purposes + +package androidx.slice; + + +public interface Clock +{ + long currentTimeMillis(); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/slice/builders/impl/TemplateBuilderImpl.java b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/builders/impl/TemplateBuilderImpl.java new file mode 100644 index 00000000000..073ce2604c9 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/builders/impl/TemplateBuilderImpl.java @@ -0,0 +1,23 @@ +// Generated automatically from androidx.slice.builders.impl.TemplateBuilderImpl for testing purposes + +package androidx.slice.builders.impl; + +import androidx.slice.Clock; +import androidx.slice.Slice; +import androidx.slice.SliceSpec; +import java.util.ArrayList; + +abstract public class TemplateBuilderImpl +{ + protected TemplateBuilderImpl() {} + protected ArrayList parseImageMode(int p0, boolean p1){ return null; } + protected TemplateBuilderImpl(Slice.Builder p0, SliceSpec p1){} + protected TemplateBuilderImpl(Slice.Builder p0, SliceSpec p1, Clock p2){} + protected void setBuilder(Slice.Builder p0){} + public Clock getClock(){ return null; } + public Slice build(){ return null; } + public Slice.Builder createChildBuilder(){ return null; } + public Slice.Builder getBuilder(){ return null; } + public SliceSpec getSpec(){ return null; } + public abstract void apply(Slice.Builder p0); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/slice/compat/CompatPermissionManager.java b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/compat/CompatPermissionManager.java new file mode 100644 index 00000000000..a04e2c809cd --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/slice/compat/CompatPermissionManager.java @@ -0,0 +1,16 @@ +// Generated automatically from androidx.slice.compat.CompatPermissionManager for testing purposes + +package androidx.slice.compat; + +import android.content.Context; +import android.net.Uri; + +public class CompatPermissionManager +{ + protected CompatPermissionManager() {} + public CompatPermissionManager(Context p0, String p1, int p2, String[] p3){} + public int checkSlicePermission(Uri p0, int p1, int p2){ return 0; } + public static String ALL_SUFFIX = null; + public void grantSlicePermission(Uri p0, String p1){} + public void revokeSlicePermission(Uri p0, String p1){} +} From 9ddfcf935bf28f5a9c91c351fae0c07b5ca64644 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Wed, 7 Sep 2022 09:46:16 -0400 Subject: [PATCH 055/203] Update java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md Co-authored-by: Tony Torralba --- .../ql/src/change-notes/2022-08-18-android-allowbackup-query.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md b/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md index b7bfd85ac8c..e37abd0d755 100644 --- a/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md +++ b/java/ql/src/change-notes/2022-08-18-android-allowbackup-query.md @@ -1,4 +1,4 @@ --- category: newQuery --- -* Added a new query, `java/android/allowBackup-attribute-enabled`, to detect if the `android:allowBackup` attribute is enabled in the Android manifest. +* Added a new query, `java/android/backup-enabled`, to detect if Android applications allow backups. From f6c8144eed5a2e3af9b5ad1e4c5074b803a9fb13 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Wed, 7 Sep 2022 09:46:36 -0400 Subject: [PATCH 056/203] Update java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql Co-authored-by: Tony Torralba --- java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 42163f4107a..97f4ec82982 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -4,7 +4,7 @@ * @kind problem * @problem.severity recommendation * @security-severity 7.5 - * @id java/android/allowbackup-enabled + * @id java/android/backup-enabled * @tags security * external/cwe/cwe-312 * @precision very-high From 19b13ee4e377e58054fdf1683bc60fc3198438da Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 7 Sep 2022 15:58:35 +0200 Subject: [PATCH 057/203] Swift: first draft of query targeting weak hashing --- .../ql/lib/codeql/swift/elements/AstNode.qll | 29 ++++-- .../CWE-328/WeakSensitiveDataHashing.qhelp | 89 +++++++++++++++++++ .../CWE-328/WeakSensitiveDataHashing.ql | 57 ++++++++++++ .../CWE-328/WeakSensitiveDataHashingBad.swift | 5 ++ .../WeakSensitiveDataHashingGood.swift | 4 + .../CWE-328/WeakSensitiveDataHashing.expected | 28 ++++++ .../CWE-328/WeakSensitiveDataHashing.qlref | 1 + .../Security/CWE-328/testCrypto.swift | 68 ++++++++++++++ 8 files changed, 273 insertions(+), 8 deletions(-) create mode 100755 swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp create mode 100755 swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql create mode 100755 swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift create mode 100755 swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.qlref create mode 100644 swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift diff --git a/swift/ql/lib/codeql/swift/elements/AstNode.qll b/swift/ql/lib/codeql/swift/elements/AstNode.qll index 01f0fedb710..33b4da963b7 100644 --- a/swift/ql/lib/codeql/swift/elements/AstNode.qll +++ b/swift/ql/lib/codeql/swift/elements/AstNode.qll @@ -1,17 +1,30 @@ private import codeql.swift.generated.AstNode private import codeql.swift.elements.decl.AbstractFunctionDecl +private import codeql.swift.elements.decl.Decl private import codeql.swift.generated.ParentChild -private Element getEnclosingFunctionStep(Element e) { - not e instanceof AbstractFunctionDecl and - result = getImmediateParent(e) -} +private module Cached { + private Element getEnclosingDeclStep(Element e) { + not e instanceof Decl and + result = getImmediateParent(e) + } -cached -private AbstractFunctionDecl getEnclosingFunctionCached(AstNode ast) { - result = getEnclosingFunctionStep*(getImmediateParent(ast)) + cached + Decl getEnclosingDecl(AstNode ast) { result = getEnclosingDeclStep*(getImmediateParent(ast)) } + + private Element getEnclosingFunctionStep(Element e) { + not e instanceof AbstractFunctionDecl and + result = getEnclosingDecl(e) + } + + cached + AbstractFunctionDecl getEnclosingFunction(AstNode ast) { + result = getEnclosingFunctionStep*(getEnclosingDecl(ast)) + } } class AstNode extends AstNodeBase { - final AbstractFunctionDecl getEnclosingFunction() { result = getEnclosingFunctionCached(this) } + final AbstractFunctionDecl getEnclosingFunction() { result = Cached::getEnclosingFunction(this) } + + final Decl getEnclosingDecl() { result = Cached::getEnclosingDecl(this) } } diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp new file mode 100755 index 00000000000..0fc07271f8e --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp @@ -0,0 +1,89 @@ + + + +

    + Using a broken or weak cryptographic hash function can leave data + vulnerable, and should not be used in security related code. +

    + +

    + A strong cryptographic hash function should be resistant to: +

    +
      +
    • + pre-image attacks: if you know a hash value h(x), + you should not be able to easily find the input x. +
    • +
    • + collision attacks: if you know a hash value h(x), + you should not be able to easily find a different input + y + with the same hash value h(x) = h(y). +
    • +
    + + +

    + As an example, both MD5 and SHA-1 are known to be vulnerable to collision attacks. +

    + +

    + Since it's OK to use a weak cryptographic hash function in a non-security + context, this query only alerts when these are used to hash sensitive + data (such as passwords, certificates, usernames). +

    + + + + +

    + Ensure that you use a strong, modern cryptographic hash function: +

    + +
      +
    • + such as Argon2, scrypt, bcrypt, or PBKDF2 for passwords and other data with limited input space. +
    • +
    • + such as SHA-2, or SHA-3 in other cases. +
    • +
    + +
    + + +

    + The following examples show a function for checking whether the hash + of a certificate matches a known value -- to prevent tampering. + + In the first case the MD5 hashing algorithm is used that is known to be vulnerable to collision attacks. +

    + +

    + + Here is the same function using SHA-512 that is a strong cryptographic hashing function. +

    + + +
    + +
  • + OWASP: + Password Storage + Cheat Sheet + + and + + Transport Layer Protection Cheat Sheet + +
  • + + + diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql new file mode 100755 index 00000000000..8aa80028957 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql @@ -0,0 +1,57 @@ +/** + * @name Use of a broken or weak cryptographic hashing algorithm on sensitive data + * @description Using broken or weak cryptographic hashing algorithms can compromise security. + * @kind path-problem + * @problem.severity warning + * @security-severity 7.5 + * @precision high + * @id py/weak-sensitive-data-hashing + * @tags security + * external/cwe/cwe-327 + * external/cwe/cwe-328 + */ + +import swift +import codeql.swift.security.SensitiveExprs +import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.TaintTracking +import DataFlow::PathGraph + +class WeakHashingConfig extends TaintTracking::Configuration { + WeakHashingConfig() { this = "WeakHashingConfig" } + + override predicate isSource(DataFlow::Node node) { + exists(SensitiveExpr e | + node.asExpr() = e and + not e.isProbablySafe() + ) + } + + override predicate isSink(DataFlow::Node node) { node instanceof WeakHashingConfig::Sink } +} + +module WeakHashingConfig { + class Sink extends DataFlow::Node { + string algorithm; + + Sink() { + exists(ApplyExpr call, FuncDecl func | + call.getAnArgument().getExpr() = this.asExpr() and + call.getStaticTarget() = func and + func.getName().matches(["hash(%", "update(%"]) and + algorithm = func.getEnclosingDecl().(StructDecl).getName() and + algorithm = ["MD5", "SHA1"] + ) + } + + string getAlgorithm() { result = algorithm } + } +} + +from WeakHashingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, string algorithm +where + config.hasFlowPath(source, sink) and + algorithm = sink.getNode().(WeakHashingConfig::Sink).getAlgorithm() +select sink.getNode(), source, sink, + "Insecure hashing algorithm (" + algorithm + ") depends on $@.", source.getNode(), + "sensitive data" diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift new file mode 100755 index 00000000000..a39dd47edce --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingBad.swift @@ -0,0 +1,5 @@ +typealias Hasher = Crypto.Insecure.MD5 + +func checkCertificate(cert: Array[UInt8], hash: Array[UInt8]) -> Bool + return Hasher.hash(data: cert) == hash // BAD +} diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift new file mode 100755 index 00000000000..7345b2ea49c --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashingGood.swift @@ -0,0 +1,4 @@ +typealias Hasher = Crypto.SHA512 + +func checkCertificate(cert: Array[UInt8], hash: Array[UInt8]) -> Bool + return Hasher.hash(data: cert) == hash // GOOD diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected new file mode 100644 index 00000000000..0422d561ca8 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -0,0 +1,28 @@ +edges +nodes +| testCrypto.swift:25:47:25:47 | passwd | semmle.label | passwd | +| testCrypto.swift:28:43:28:43 | credit_card_no | semmle.label | credit_card_no | +| testCrypto.swift:32:48:32:48 | passwd | semmle.label | passwd | +| testCrypto.swift:35:44:35:44 | credit_card_no | semmle.label | credit_card_no | +| testCrypto.swift:40:23:40:23 | passwd | semmle.label | passwd | +| testCrypto.swift:43:23:43:23 | credit_card_no | semmle.label | credit_card_no | +| testCrypto.swift:48:23:48:23 | passwd | semmle.label | passwd | +| testCrypto.swift:51:23:51:23 | credit_card_no | semmle.label | credit_card_no | +| testCrypto.swift:56:32:56:32 | passwd | semmle.label | passwd | +| testCrypto.swift:59:32:59:32 | credit_card_no | semmle.label | credit_card_no | +| testCrypto.swift:64:32:64:32 | passwd | semmle.label | passwd | +| testCrypto.swift:67:32:67:32 | credit_card_no | semmle.label | credit_card_no | +subpaths +#select +| testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:25:47:25:47 | passwd | sensitive data | +| testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:28:43:28:43 | credit_card_no | sensitive data | +| testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:32:48:32:48 | passwd | sensitive data | +| testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:35:44:35:44 | credit_card_no | sensitive data | +| testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:40:23:40:23 | passwd | sensitive data | +| testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:43:23:43:23 | credit_card_no | sensitive data | +| testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:48:23:48:23 | passwd | sensitive data | +| testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:51:23:51:23 | credit_card_no | sensitive data | +| testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:56:32:56:32 | passwd | sensitive data | +| testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:59:32:59:32 | credit_card_no | sensitive data | +| testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:64:32:64:32 | passwd | sensitive data | +| testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:67:32:67:32 | credit_card_no | sensitive data | diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.qlref b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.qlref new file mode 100644 index 00000000000..85270fde299 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.qlref @@ -0,0 +1 @@ +queries/Security/CWE-328/WeakSensitiveDataHashing.ql diff --git a/swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift b/swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift new file mode 100644 index 00000000000..9994aeb5008 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-328/testCrypto.swift @@ -0,0 +1,68 @@ +//codeql-extractor-options: -module-name Crypto + +enum Insecure { + struct MD5 { + static func hash(data: D) -> [UInt8] { + return [] + } + + func update(data: D) {} + func update(bufferPointer: UnsafeRawBufferPointer) {} + func finalize() -> [UInt8] { return [] } + } + struct SHA1 { + static func hash(data: D) -> [UInt8] { + return [] + } + + func update(data: D) {} + func update(bufferPointer: UnsafeRawBufferPointer) {} + func finalize() -> [UInt8] { return [] } + } +} + +func test1(passwd : UnsafeRawBufferPointer, encrypted_passwd : String, account_no : String, credit_card_no : String) { + var hash = Crypto.Insecure.MD5.hash(data: passwd) // BAD + hash = Crypto.Insecure.MD5.hash(data: encrypted_passwd) // GOOD (not sensitive) + hash = Crypto.Insecure.MD5.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.MD5.hash(data: credit_card_no) // BAD +} + +func test2(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { + var hash = Crypto.Insecure.SHA1.hash(data: passwd) // BAD + hash = Crypto.Insecure.SHA1.hash(data: encrypted_passwd) // GOOD (not sensitive) + hash = Crypto.Insecure.SHA1.hash(data: account_no) // BAD [NOT DETECTED] + hash = Crypto.Insecure.SHA1.hash(data: credit_card_no) // BAD +} + +func test3(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { + var hash = Crypto.Insecure.MD5() + hash.update(data: passwd) // BAD + hash.update(data: encrypted_passwd) // GOOD (not sensitive) + hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: credit_card_no) // BAD +} + +func test4(passwd : String, encrypted_passwd : String, account_no : String, credit_card_no : String) { + var hash = Crypto.Insecure.SHA1() + hash.update(data: passwd) // BAD + hash.update(data: encrypted_passwd) // GOOD (not sensitive) + hash.update(data: account_no) // BAD [NOT DETECTED] + hash.update(data: credit_card_no) // BAD +} + +func test5(passwd : UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) { + var hash = Crypto.Insecure.MD5() + hash.update(bufferPointer: passwd) // BAD + hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) + hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: credit_card_no) // BAD +} + +func test6(passwd : UnsafeRawBufferPointer, encrypted_passwd : UnsafeRawBufferPointer, account_no : UnsafeRawBufferPointer, credit_card_no : UnsafeRawBufferPointer) { + var hash = Crypto.Insecure.SHA1() + hash.update(bufferPointer: passwd) // BAD + hash.update(bufferPointer: encrypted_passwd) // GOOD (not sensitive) + hash.update(bufferPointer: account_no) // BAD [NOT DETECTED] + hash.update(bufferPointer: credit_card_no) // BAD +} From a5233c0d01c3e9c18a987f5994b69f8eb607edd1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 7 Sep 2022 16:17:45 +0200 Subject: [PATCH 058/203] Swift: fix `@id` --- .../ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql index 8aa80028957..5eb711434fa 100755 --- a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql @@ -5,7 +5,7 @@ * @problem.severity warning * @security-severity 7.5 * @precision high - * @id py/weak-sensitive-data-hashing + * @id swift/weak-sensitive-data-hashing * @tags security * external/cwe/cwe-327 * external/cwe/cwe-328 From 5206c792b099ce65cd41bc47ff66aadfab85aa9a Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 7 Sep 2022 12:07:48 -0400 Subject: [PATCH 059/203] Additional Unit tests for the allowBackup query --- .../security/CWE-312/AndroidManifest.xml | 2 +- .../backup}/AllowBackupEnabledTest.expected | 0 .../backup}/AllowBackupEnabledTest.java | 0 .../backup}/AllowBackupEnabledTest.ql | 3 +- .../TestEmptyManifest/AndroidManifest.xml | 3 ++ .../AndroidManifest.xml | 29 +++++++++++++++++++ .../TestExplicitlyEnabled/AndroidManifest.xml | 29 +++++++++++++++++++ .../backup/TestLibrary/AndroidManifest.xml | 6 ++++ .../backup/TestMissing/AndroidManifest.xml | 29 +++++++++++++++++++ .../backup/Testbuild/AndroidManifest.xml | 29 +++++++++++++++++++ 10 files changed, 127 insertions(+), 3 deletions(-) rename java/ql/test/query-tests/security/CWE-312/{ => android/backup}/AllowBackupEnabledTest.expected (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/backup}/AllowBackupEnabledTest.java (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/backup}/AllowBackupEnabledTest.ql (84%) create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/TestEmptyManifest/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyDisabled/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/TestLibrary/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/TestMissing/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/Testbuild/AndroidManifest.xml diff --git a/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml index 8cf208d0a48..d8af1947bd7 100644 --- a/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml +++ b/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml @@ -4,7 +4,7 @@ android:versionCode="1" android:versionName="0.1" > - + diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.expected b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.expected rename to java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.java rename to java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.java diff --git a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql similarity index 84% rename from java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql rename to java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql index 604f50dffa7..2ec9c6a0cd8 100644 --- a/java/ql/test/query-tests/security/CWE-312/AllowBackupEnabledTest.ql +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql @@ -10,8 +10,7 @@ class AllowBackupEnabledTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasAllowedBackupEnabled" and exists(AndroidApplicationXmlElement androidAppElem | - androidAppElem.allowsBackup() and - not androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() + androidAppElem.allowsBackup() | androidAppElem.getAttribute("allowBackup").getLocation() = location and element = androidAppElem.getAttribute("debuggable").toString() and diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestEmptyManifest/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestEmptyManifest/AndroidManifest.xml new file mode 100644 index 00000000000..306f3852be8 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestEmptyManifest/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyDisabled/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyDisabled/AndroidManifest.xml new file mode 100644 index 00000000000..5f35eb615d5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyDisabled/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml new file mode 100644 index 00000000000..959c14c8507 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestLibrary/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestLibrary/AndroidManifest.xml new file mode 100644 index 00000000000..e83d18d59e9 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestLibrary/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestMissing/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestMissing/AndroidManifest.xml new file mode 100644 index 00000000000..43a966ac28e --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestMissing/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/Testbuild/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/Testbuild/AndroidManifest.xml new file mode 100644 index 00000000000..097e7ed2b51 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/Testbuild/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + From c69a2be9767b012bfd578308406e8856bb7b5a35 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 7 Sep 2022 12:08:25 -0400 Subject: [PATCH 060/203] Moved allowBackup query logic to allowsBackup pred --- .../lib/semmle/code/xml/AndroidManifest.qll | 22 ++++++++++++++----- .../CWE-312/AllowBackupAttributeEnabled.ql | 12 +--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/java/ql/lib/semmle/code/xml/AndroidManifest.qll b/java/ql/lib/semmle/code/xml/AndroidManifest.qll index 0965025b969..f53da67a650 100644 --- a/java/ql/lib/semmle/code/xml/AndroidManifest.qll +++ b/java/ql/lib/semmle/code/xml/AndroidManifest.qll @@ -79,10 +79,20 @@ class AndroidApplicationXmlElement extends XmlElement { * https://developer.android.com/guide/topics/data/autobackup */ predicate allowsBackup() { - not exists(AndroidXmlAttribute attr | - this.getAnAttribute() = attr and - attr.getName() = "allowBackup" and - attr.getValue() = "false" + not this.getFile().(AndroidManifestXmlFile).isInBuildDirectory() and + ( + // explicitly sets android:allowBackup="true" + this.allowsBackupExplicitly() + or + // Manifest providing the main intent for an application, and does not explicitly + // disallow the allowBackup attribute + this.providesMainIntent() and + // Check that android:allowBackup="false" is not present + not exists(AndroidXmlAttribute attr | + this.getAnAttribute() = attr and + attr.getName() = "allowBackup" and + attr.getValue() = "false" + ) ) } @@ -91,7 +101,7 @@ class AndroidApplicationXmlElement extends XmlElement { * * https://developer.android.com/guide/topics/data/autobackup */ - predicate allowsBackupExplicitly() { + private predicate allowsBackupExplicitly() { exists(AndroidXmlAttribute attr | this.getAnAttribute() = attr and attr.getName() = "allowBackup" and @@ -103,7 +113,7 @@ class AndroidApplicationXmlElement extends XmlElement { * Holds if the application element contains a child element which provides the * `android.intent.action.MAIN` intent. */ - predicate providesMainIntent() { + private predicate providesMainIntent() { exists(AndroidActivityXmlElement activity | activity = this.getAChild() and exists(AndroidIntentFilterXmlElement intentFilter | diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 97f4ec82982..89421289765 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -14,15 +14,5 @@ import java import semmle.code.xml.AndroidManifest from AndroidApplicationXmlElement androidAppElem -where - not androidAppElem.getFile().(AndroidManifestXmlFile).isInBuildDirectory() and - ( - // explicitly sets android:allowBackup=true - androidAppElem.allowsBackupExplicitly() - or - // Manifest providing the main intent for an application, and does not explicitly - // disallow the allowBackup attribute - androidAppElem.providesMainIntent() and - androidAppElem.allowsBackup() - ) +where androidAppElem.allowsBackup() select androidAppElem, "The 'android:allowBackup' attribute is enabled." From 09b723fc6d345dff3343bc31759f0b05bc2a5928 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 7 Sep 2022 13:30:19 -0400 Subject: [PATCH 061/203] Formatting fixes for allowBackup tests --- .../security/CWE-312/android/backup/AllowBackupEnabledTest.ql | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql index 2ec9c6a0cd8..c79276402fe 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql @@ -9,9 +9,7 @@ class AllowBackupEnabledTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasAllowedBackupEnabled" and - exists(AndroidApplicationXmlElement androidAppElem | - androidAppElem.allowsBackup() - | + exists(AndroidApplicationXmlElement androidAppElem | androidAppElem.allowsBackup() | androidAppElem.getAttribute("allowBackup").getLocation() = location and element = androidAppElem.getAttribute("debuggable").toString() and value = "" From d18ad665b61f86cb002bccccd0727c17c97b161b Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 12 Aug 2022 17:20:28 +0200 Subject: [PATCH 062/203] Swift: CWE-757: Insecure TLS configuration --- .../Security/CWE-757/InsecureTLS.qhelp | 29 +++ .../queries/Security/CWE-757/InsecureTLS.ql | 55 ++++++ .../queries/Security/CWE-757/SecureTLS.swift | 12 ++ .../Security/CWE-757/InsecureTLS.expected | 86 +++++++++ .../Security/CWE-757/InsecureTLS.qlref | 1 + .../Security/CWE-757/InsecureTLS.swift | 173 ++++++++++++++++++ 6 files changed, 356 insertions(+) create mode 100644 swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp create mode 100644 swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql create mode 100644 swift/ql/src/queries/Security/CWE-757/SecureTLS.swift create mode 100644 swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected create mode 100644 swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.qlref create mode 100644 swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.swift diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp new file mode 100644 index 00000000000..673d17b7b23 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp @@ -0,0 +1,29 @@ + + + +

    TLS v1.0 and v1.1 versions are known to be vulnerable.

    +
    + + +

    Use tls_protocol_version_t.TLSv12 or tls_protocol_version_t.TLSv13 when configuring URLSession.

    + +
    + + +

    Consider specifying newer tls_protocol_version_t explicitly, or omitting it completely as the OS will use secure defaults.

    + + + +
    + + +
  • + Apple Platform Security - TLS security + Preventing Insecure Network Connections + CWE-757: Selection of Less-Secure Algorithm During Negotiation +
  • + +
    +
    diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql new file mode 100644 index 00000000000..3f0c1511136 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql @@ -0,0 +1,55 @@ +/** + * @name Insecure TLS configuration + * @description TLS v1.0 and v1.1 versions are known to be vulnerable.. TLS v1.2 or v1.3 should be used instead. + * @kind path-problem + * @problem.severity error + * @security-severity TODO + * @precision high + * @id swift/insecure-tls + * @tags security + * external/cwe/cwe-757 + */ + +import swift +import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.TaintTracking +import codeql.swift.dataflow.FlowSources +import DataFlow::PathGraph + +/** + * A taint config to detect insecure configuration of `NSURLSessionConfiguration` + */ +class InsecureTlsConfig extends TaintTracking::Configuration { + InsecureTlsConfig() { this = "InsecureTLSConfig" } + + /** + * Holds for enum values that represent an insecure version of TLS + */ + override predicate isSource(DataFlow::Node node) { + exists(MethodRefExpr expr, EnumElementDecl enum, string enumName | + node.asExpr() = expr and + expr.getMember() = enum and + enumName = enum.getName() and + enumName in ["TLSv10", "TLSv11", "tlsProtocol10", "tlsProtocol11"] + ) + } + + /** + * Holds for assignment of TLS-related properties of `NSURLSessionConfiguration` + */ + override predicate isSink(DataFlow::Node node) { + exists(AssignExpr assign, MemberRefExpr member, string memberName | + assign.getSource() = node.asExpr() and + assign.getDest() = member and + memberName = member.getMember().(ConcreteVarDecl).getName() and + memberName in [ + "tlsMinimumSupportedProtocolVersion", "tlsMinimumSupportedProtocol", + "tlsMaximumSupportedProtocolVersion", "tlsMaximumSupportedProtocol" + ] + ) + } +} + +from InsecureTlsConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode +where config.hasFlowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, "Insecure TLS configuration" diff --git a/swift/ql/src/queries/Security/CWE-757/SecureTLS.swift b/swift/ql/src/queries/Security/CWE-757/SecureTLS.swift new file mode 100644 index 00000000000..0254638e824 --- /dev/null +++ b/swift/ql/src/queries/Security/CWE-757/SecureTLS.swift @@ -0,0 +1,12 @@ +// Set TLS version explicitly +func createURLSession() -> URLSession { + let config = URLSessionConfiguration.default + config.tlsMinimumSupportedProtocolVersion = tls_protocol_version_t.TLSv13 + return URLSession(configuration: config) +} + +// Use the secure OS defaults +func createURLSession() -> URLSession { + let config = URLSessionConfiguration.default + return URLSession(configuration: config) +} diff --git a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected new file mode 100644 index 00000000000..b42d6fbedf3 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected @@ -0,0 +1,86 @@ +edges +| InsecureTLS.swift:19:7:19:7 | value : | file://:0:0:0:0 | value | +| InsecureTLS.swift:20:7:20:7 | value : | file://:0:0:0:0 | value | +| InsecureTLS.swift:22:7:22:7 | value : | file://:0:0:0:0 | value | +| InsecureTLS.swift:23:7:23:7 | value : | file://:0:0:0:0 | value | +| InsecureTLS.swift:40:47:40:70 | .TLSv10 : | InsecureTLS.swift:19:7:19:7 | value : | +| InsecureTLS.swift:45:47:45:70 | .TLSv11 : | InsecureTLS.swift:19:7:19:7 | value : | +| InsecureTLS.swift:57:47:57:70 | .TLSv10 : | InsecureTLS.swift:20:7:20:7 | value : | +| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 : | InsecureTLS.swift:22:7:22:7 | value : | +| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 : | InsecureTLS.swift:23:7:23:7 | value : | +| InsecureTLS.swift:102:10:102:33 | .TLSv10 : | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | +| InsecureTLS.swift:102:10:102:33 | .TLSv10 : | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() : | +| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() : | InsecureTLS.swift:19:7:19:7 | value : | +| InsecureTLS.swift:121:55:121:66 | version : | InsecureTLS.swift:122:47:122:47 | version | +| InsecureTLS.swift:121:55:121:66 | version : | InsecureTLS.swift:122:47:122:47 | version : | +| InsecureTLS.swift:122:47:122:47 | version : | InsecureTLS.swift:19:7:19:7 | value : | +| InsecureTLS.swift:127:25:127:48 | .TLSv11 : | InsecureTLS.swift:121:55:121:66 | version : | +| InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | file://:0:0:0:0 | self [TLSVersion] : | +| InsecureTLS.swift:158:7:158:7 | value : | file://:0:0:0:0 | value : | +| InsecureTLS.swift:163:3:163:3 | [post] def [TLSVersion] : | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | +| InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:158:7:158:7 | value : | +| InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:163:3:163:3 | [post] def [TLSVersion] : | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:165:47:165:51 | .TLSVersion : | +| InsecureTLS.swift:165:47:165:51 | .TLSVersion : | InsecureTLS.swift:19:7:19:7 | value : | +| file://:0:0:0:0 | self [TLSVersion] : | file://:0:0:0:0 | .TLSVersion : | +| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [TLSVersion] : | +nodes +| InsecureTLS.swift:19:7:19:7 | value : | semmle.label | value : | +| InsecureTLS.swift:20:7:20:7 | value : | semmle.label | value : | +| InsecureTLS.swift:22:7:22:7 | value : | semmle.label | value : | +| InsecureTLS.swift:23:7:23:7 | value : | semmle.label | value : | +| InsecureTLS.swift:40:47:40:70 | .TLSv10 | semmle.label | .TLSv10 | +| InsecureTLS.swift:40:47:40:70 | .TLSv10 : | semmle.label | .TLSv10 : | +| InsecureTLS.swift:45:47:45:70 | .TLSv11 | semmle.label | .TLSv11 | +| InsecureTLS.swift:45:47:45:70 | .TLSv11 : | semmle.label | .TLSv11 : | +| InsecureTLS.swift:57:47:57:70 | .TLSv10 | semmle.label | .TLSv10 | +| InsecureTLS.swift:57:47:57:70 | .TLSv10 : | semmle.label | .TLSv10 : | +| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | semmle.label | .tlsProtocol10 | +| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 : | semmle.label | .tlsProtocol10 : | +| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | semmle.label | .tlsProtocol10 | +| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 : | semmle.label | .tlsProtocol10 : | +| InsecureTLS.swift:102:10:102:33 | .TLSv10 : | semmle.label | .TLSv10 : | +| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | semmle.label | call to getBadTLSVersion() | +| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() : | semmle.label | call to getBadTLSVersion() : | +| InsecureTLS.swift:121:55:121:66 | version : | semmle.label | version : | +| InsecureTLS.swift:122:47:122:47 | version | semmle.label | version | +| InsecureTLS.swift:122:47:122:47 | version : | semmle.label | version : | +| InsecureTLS.swift:127:25:127:48 | .TLSv11 : | semmle.label | .TLSv11 : | +| InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | semmle.label | self [TLSVersion] : | +| InsecureTLS.swift:158:7:158:7 | value : | semmle.label | value : | +| InsecureTLS.swift:163:3:163:3 | [post] def [TLSVersion] : | semmle.label | [post] def [TLSVersion] : | +| InsecureTLS.swift:163:20:163:43 | .TLSv10 : | semmle.label | .TLSv10 : | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | semmle.label | def [TLSVersion] : | +| InsecureTLS.swift:165:47:165:51 | .TLSVersion | semmle.label | .TLSVersion | +| InsecureTLS.swift:165:47:165:51 | .TLSVersion : | semmle.label | .TLSVersion : | +| file://:0:0:0:0 | .TLSVersion : | semmle.label | .TLSVersion : | +| file://:0:0:0:0 | [post] self [TLSVersion] : | semmle.label | [post] self [TLSVersion] : | +| file://:0:0:0:0 | self [TLSVersion] : | semmle.label | self [TLSVersion] : | +| file://:0:0:0:0 | value | semmle.label | value | +| file://:0:0:0:0 | value | semmle.label | value | +| file://:0:0:0:0 | value | semmle.label | value | +| file://:0:0:0:0 | value | semmle.label | value | +| file://:0:0:0:0 | value : | semmle.label | value : | +subpaths +| InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:158:7:158:7 | value : | file://:0:0:0:0 | [post] self [TLSVersion] : | InsecureTLS.swift:163:3:163:3 | [post] def [TLSVersion] : | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | file://:0:0:0:0 | .TLSVersion : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | +| InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | file://:0:0:0:0 | .TLSVersion : | InsecureTLS.swift:165:47:165:51 | .TLSVersion : | +#select +| InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | Insecure TLS configuration | +| InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | Insecure TLS configuration | +| InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | Insecure TLS configuration | +| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | Insecure TLS configuration | +| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | Insecure TLS configuration | +| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | Insecure TLS configuration | +| InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | InsecureTLS.swift:122:47:122:47 | version | Insecure TLS configuration | +| InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:40:47:40:70 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:45:47:45:70 | .TLSv11 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:57:47:57:70 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| file://:0:0:0:0 | value | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | diff --git a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.qlref b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.qlref new file mode 100644 index 00000000000..af89770b496 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.qlref @@ -0,0 +1 @@ +queries/Security/CWE-757/InsecureTLS.ql diff --git a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.swift b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.swift new file mode 100644 index 00000000000..d06c9614ac3 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.swift @@ -0,0 +1,173 @@ +// Stubs + +enum tls_protocol_version_t : UInt16 { + case TLSv10 + case TLSv11 + case TLSv12 + case TLSv13 +} + +enum SSLProtocol { + case tlsProtocol10 + case tlsProtocol11 + case tlsProtocol12 + case tlsProtocol13 +} + +class URLSessionConfiguration { + init() {} + var tlsMinimumSupportedProtocolVersion: tls_protocol_version_t = tls_protocol_version_t.TLSv12 + var tlsMaximumSupportedProtocolVersion: tls_protocol_version_t = tls_protocol_version_t.TLSv13 + + var tlsMinimumSupportedProtocol: SSLProtocol = SSLProtocol.tlsProtocol12 + var tlsMaximumSupportedProtocol: SSLProtocol = SSLProtocol.tlsProtocol13 +} + +/// tlsMinimumSupportedProtocolVersion + +func case_0() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = tls_protocol_version_t.TLSv12 // GOOD +} + +func case_1() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = tls_protocol_version_t.TLSv13 // GOOD +} + +func case_2() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = tls_protocol_version_t.TLSv10 // BAD +} + +func case_3() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = tls_protocol_version_t.TLSv11 // BAD +} + +/// tlsMaximumSupportedProtocolVersion + +func case_4() { + let config = URLSessionConfiguration() + config.tlsMaximumSupportedProtocolVersion = tls_protocol_version_t.TLSv12 // GOOD +} + +func case_5() { + let config = URLSessionConfiguration() + config.tlsMaximumSupportedProtocolVersion = tls_protocol_version_t.TLSv10 // BAD +} + +/// tlsMinimumSupportedProtocol + +func case_6() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocol = SSLProtocol.tlsProtocol10 // BAD +} + +func case_7() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocol = SSLProtocol.tlsProtocol12 // GOOD +} + +/// tlsMaximumSupportedProtocol + +func case_8() { + let config = URLSessionConfiguration() + config.tlsMaximumSupportedProtocol = SSLProtocol.tlsProtocol10 // BAD +} + +func case_9() { + let config = URLSessionConfiguration() + config.tlsMaximumSupportedProtocol = SSLProtocol.tlsProtocol12 // GOOD +} + +/// Indirect assignment (global vars) + +let badGlobalVersion = tls_protocol_version_t.TLSv10 +let goodGlobalVersion = tls_protocol_version_t.TLSv12 + +func case_10() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = badGlobalVersion // BAD [not detected] +} + +func case_11() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = goodGlobalVersion // GOOD +} + +/// Indirect assignment (function calls) + +func getBadTLSVersion() -> tls_protocol_version_t { + return tls_protocol_version_t.TLSv10 +} + +func getGoodTLSVersion() -> tls_protocol_version_t { + return tls_protocol_version_t.TLSv13 +} + +func case_12() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = getBadTLSVersion() // BAD +} + +func case_13() { + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = getGoodTLSVersion() // GOOD +} + +/// Indirect assignment (via call arguments) + +func setTLSVersion(_ config: URLSessionConfiguration, _ version: tls_protocol_version_t) { + config.tlsMinimumSupportedProtocolVersion = version +} + +func case_14() { + let config = URLSessionConfiguration() + setTLSVersion(config, tls_protocol_version_t.TLSv11) // BAD +} + +func case_15() { + let config = URLSessionConfiguration() + setTLSVersion(config, tls_protocol_version_t.TLSv13) // GOOD +} + +/// Indirect assignment (via external entity) + +struct BadDefault { + let TLSVersion: tls_protocol_version_t = tls_protocol_version_t.TLSv11 +} + +func case_16() { + let def = BadDefault() + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = def.TLSVersion // BAD [not detected] +} + +struct GoodDefault { + let TLSVersion: tls_protocol_version_t = tls_protocol_version_t.TLSv12 +} + +func case_17() { + let def = GoodDefault() + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = def.TLSVersion // GOOD +} + +struct VarDefault { + var TLSVersion: tls_protocol_version_t = tls_protocol_version_t.TLSv12 +} + +func case_18() { + var def = VarDefault() + def.TLSVersion = tls_protocol_version_t.TLSv10 + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = def.TLSVersion // BAD +} + +func case_19() { + var def = VarDefault() + def.TLSVersion = tls_protocol_version_t.TLSv13 + let config = URLSessionConfiguration() + config.tlsMinimumSupportedProtocolVersion = def.TLSVersion // GOOD +} From d455a557be2d3348ed20b7ab2771f2123b05002d Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 8 Sep 2022 10:31:23 +0200 Subject: [PATCH 063/203] Swift: CWE-757: update docs and user facing text --- .../Security/CWE-757/InsecureTLS.qhelp | 3 +- .../queries/Security/CWE-757/InsecureTLS.ql | 4 +-- .../Security/CWE-757/InsecureTLS.expected | 32 +++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp index 673d17b7b23..b0450580131 100644 --- a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.qhelp @@ -12,7 +12,7 @@ -

    Consider specifying newer tls_protocol_version_t explicitly, or omitting it completely as the OS will use secure defaults.

    +

    Specify newer tls_protocol_version_t explicitly, or omit it completely as the OS will use secure defaults.

    @@ -22,7 +22,6 @@
  • Apple Platform Security - TLS security Preventing Insecure Network Connections - CWE-757: Selection of Less-Secure Algorithm During Negotiation
  • diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql index 3f0c1511136..91bcf61c337 100644 --- a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql @@ -1,6 +1,6 @@ /** * @name Insecure TLS configuration - * @description TLS v1.0 and v1.1 versions are known to be vulnerable.. TLS v1.2 or v1.3 should be used instead. + * @description TLS v1.0 and v1.1 versions are known to be vulnerable. TLS v1.2 or v1.3 should be used instead. * @kind path-problem * @problem.severity error * @security-severity TODO @@ -52,4 +52,4 @@ class InsecureTlsConfig extends TaintTracking::Configuration { from InsecureTlsConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode where config.hasFlowPath(sourceNode, sinkNode) -select sinkNode.getNode(), sourceNode, sinkNode, "Insecure TLS configuration" +select sinkNode.getNode(), sourceNode, sinkNode, "This TLS configuration is insecure." diff --git a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected index b42d6fbedf3..c6d2599be5e 100644 --- a/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected +++ b/swift/ql/test/query-tests/Security/CWE-757/InsecureTLS.expected @@ -68,19 +68,19 @@ subpaths | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | file://:0:0:0:0 | .TLSVersion : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | | InsecureTLS.swift:165:47:165:47 | def [TLSVersion] : | InsecureTLS.swift:158:7:158:7 | self [TLSVersion] : | file://:0:0:0:0 | .TLSVersion : | InsecureTLS.swift:165:47:165:51 | .TLSVersion : | #select -| InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | Insecure TLS configuration | -| InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | Insecure TLS configuration | -| InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | Insecure TLS configuration | -| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | Insecure TLS configuration | -| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | Insecure TLS configuration | -| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | Insecure TLS configuration | -| InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | InsecureTLS.swift:122:47:122:47 | version | Insecure TLS configuration | -| InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:40:47:40:70 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:45:47:45:70 | .TLSv11 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:57:47:57:70 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | file://:0:0:0:0 | value | Insecure TLS configuration | -| file://:0:0:0:0 | value | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | file://:0:0:0:0 | value | Insecure TLS configuration | +| InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | InsecureTLS.swift:40:47:40:70 | .TLSv10 | This TLS configuration is insecure. | +| InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | InsecureTLS.swift:45:47:45:70 | .TLSv11 | This TLS configuration is insecure. | +| InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | InsecureTLS.swift:57:47:57:70 | .TLSv10 | This TLS configuration is insecure. | +| InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 | This TLS configuration is insecure. | +| InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 | This TLS configuration is insecure. | +| InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | InsecureTLS.swift:111:47:111:64 | call to getBadTLSVersion() | This TLS configuration is insecure. | +| InsecureTLS.swift:122:47:122:47 | version | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | InsecureTLS.swift:122:47:122:47 | version | This TLS configuration is insecure. | +| InsecureTLS.swift:165:47:165:51 | .TLSVersion | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | InsecureTLS.swift:165:47:165:51 | .TLSVersion | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:40:47:40:70 | .TLSv10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:45:47:45:70 | .TLSv11 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:57:47:57:70 | .TLSv10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:64:40:64:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:76:40:76:52 | .tlsProtocol10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:102:10:102:33 | .TLSv10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:127:25:127:48 | .TLSv11 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | +| file://:0:0:0:0 | value | InsecureTLS.swift:163:20:163:43 | .TLSv10 : | file://:0:0:0:0 | value | This TLS configuration is insecure. | From a8a2c9e212a7890a105f2bc343d52ef639dc112f Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 8 Sep 2022 10:40:16 +0200 Subject: [PATCH 064/203] Swift: CWE-757: update severity --- swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql index 91bcf61c337..375da521dc0 100644 --- a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql @@ -3,7 +3,7 @@ * @description TLS v1.0 and v1.1 versions are known to be vulnerable. TLS v1.2 or v1.3 should be used instead. * @kind path-problem * @problem.severity error - * @security-severity TODO + * @security-severity 7.5 * @precision high * @id swift/insecure-tls * @tags security From fdf348850077cf3436658177f13b91083134e71e Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 7 Sep 2022 10:29:44 +0200 Subject: [PATCH 065/203] Kotlin: Add test with extraction error due to missing base class of `KFunctionX` --- .../kotlin/kotlin_kfunction/app/build.gradle | 25 +++++++++++++++++++ .../app/src/main/kotlin/testProject/App.kt | 10 ++++++++ .../kotlin_kfunction/diagnostics.expected | 1 + .../kotlin/kotlin_kfunction/diagnostics.ql | 4 +++ .../kotlin/kotlin_kfunction/settings.gradle | 11 ++++++++ .../kotlin/kotlin_kfunction/test.py | 5 ++++ 6 files changed, 56 insertions(+) create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/build.gradle create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.ql create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/settings.gradle create mode 100644 java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/test.py diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/build.gradle b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/build.gradle new file mode 100644 index 00000000000..924524190cf --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/build.gradle @@ -0,0 +1,25 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Kotlin application project to get you started. + * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle + * User Manual available at https://docs.gradle.org/7.0.2/userguide/building_java_projects.html + */ + +plugins { + // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. + id 'org.jetbrains.kotlin.jvm' version '1.6.20' + + // Apply the application plugin to add support for building a CLI application in Java. + id 'application' +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +application { + // Define the main class for the application. + mainClass = 'testProject.AppKt' +} diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt new file mode 100644 index 00000000000..283f9270626 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/app/src/main/kotlin/testProject/App.kt @@ -0,0 +1,10 @@ +import kotlin.reflect.* + +fun fn() { + val ref: KFunction2 = Ccc::m + ref.invoke(Ccc(), 1) +} + +class Ccc { + fun m(i:Int):Double = 5.0 +} diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected new file mode 100644 index 00000000000..ba9c677f304 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected @@ -0,0 +1 @@ +| app/src/main/kotlin/testProject/App.kt:0:0:0:0 | Failed to find a class declaring invoke starting at KFunction2 | diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.ql b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.ql new file mode 100644 index 00000000000..071cbb1b6ec --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.ql @@ -0,0 +1,4 @@ +import java +import semmle.code.java.Diagnostics + +query predicate diag(Diagnostic d) { any() } diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/settings.gradle b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/settings.gradle new file mode 100644 index 00000000000..a56fb7dd11c --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/settings.gradle @@ -0,0 +1,11 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/7.0.2/userguide/multi_project_builds.html + */ + +rootProject.name = 'testProject' +include('app') diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/test.py b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/test.py new file mode 100644 index 00000000000..3a4f9d2032e --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/test.py @@ -0,0 +1,5 @@ +from create_database_utils import * + +run_codeql_database_create( + ["gradle build --no-daemon --no-build-cache --rerun-tasks"], lang="java") +runSuccessfully(["gradle", "clean"]) From 56ef1739a36af0316d113b96b65980042a7ddf4c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 8 Sep 2022 10:48:21 +0200 Subject: [PATCH 066/203] Kotlin: fix `KFunctionX.invoke` extraction --- .../src/main/kotlin/KotlinFileExtractor.kt | 8 ++++++++ .../kotlin/kotlin_kfunction/diagnostics.expected | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index fe88f8a2de4..dc6dc28c98f 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1318,6 +1318,14 @@ open class KotlinFileExtractor( val receiverClass = receiverType.classifier.owner as? IrClass ?: return listOf() val ancestorTypes = ArrayList() + // KFunctionX doesn't implement FunctionX on versions before 1.7.0: + if ((callTarget.name.asString() == "invoke") && + (receiverClass.fqNameWhenAvailable?.asString()?.startsWith("kotlin.reflect.KFunction") == true) && + (callTarget.parentClassOrNull?.fqNameWhenAvailable?.asString()?.startsWith("kotlin.Function") == true) + ) { + return receiverType.arguments + } + // Populate ancestorTypes with the path from receiverType's class to its ancestor, callTarget's declaring type. fun walkFrom(c: IrClass): Boolean { if(declaringType == c) diff --git a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected index ba9c677f304..e69de29bb2d 100644 --- a/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected +++ b/java/ql/integration-tests/posix-only/kotlin/kotlin_kfunction/diagnostics.expected @@ -1 +0,0 @@ -| app/src/main/kotlin/testProject/App.kt:0:0:0:0 | Failed to find a class declaring invoke starting at KFunction2 | From 88f295fbb101a3fe16965cb570250fc2a44f87dd Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Thu, 8 Sep 2022 15:49:34 +0200 Subject: [PATCH 067/203] make a shared library of the typo database --- javascript/ql/src/Expressions/Misspelling.qll | 2 +- .../ql/src/Expressions/TypoDatabase.qll | 9039 +---------------- javascript/ql/src/qlpack.yml | 1 + .../src/codeql_ql/style/MisspellingQuery.qll | 2 +- ql/ql/src/codeql_ql/style/TypoDatabase.qll | 9039 +---------------- ql/ql/src/qlpack.yml | 2 + shared/typos/codeql/typos/TypoDatabase.qll | 9035 ++++++++++++++++ shared/typos/qlpack.yml | 4 + 8 files changed, 9052 insertions(+), 18072 deletions(-) create mode 100644 shared/typos/codeql/typos/TypoDatabase.qll create mode 100644 shared/typos/qlpack.yml diff --git a/javascript/ql/src/Expressions/Misspelling.qll b/javascript/ql/src/Expressions/Misspelling.qll index e7c35260edb..966e3d5e996 100644 --- a/javascript/ql/src/Expressions/Misspelling.qll +++ b/javascript/ql/src/Expressions/Misspelling.qll @@ -4,7 +4,7 @@ import javascript // import typo database (generated from Wikipedia, licensed under CC BY-SA 3.0) -import TypoDatabase +import codeql.typos.TypoDatabase /** * Holds if `wrong` is a misspelling of `right` that might be intentional or diff --git a/javascript/ql/src/Expressions/TypoDatabase.qll b/javascript/ql/src/Expressions/TypoDatabase.qll index a41f003a8c0..f480b9ebc8b 100644 --- a/javascript/ql/src/Expressions/TypoDatabase.qll +++ b/javascript/ql/src/Expressions/TypoDatabase.qll @@ -1,9035 +1,4 @@ -/** - * Holds if `wrong` is a common misspelling of `right`. - * - * This predicate was automatically generated by - * python buildutils-internal/scripts/generate-typos.py - * which uses http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines (with custom additions) on 2018-01-19. - * - * This file is available under the Creative Commons Attribution-ShareAlike License - * (https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License). - */ -predicate typos(string wrong, string right) { - wrong = "abandonned" and right = "abandoned" - or - wrong = "abbout" and right = "about" - or - wrong = "aberation" and right = "aberration" - or - wrong = "abilityes" and right = "abilities" - or - wrong = "abilties" and right = "abilities" - or - wrong = "abilty" and right = "ability" - or - wrong = "abondon" and right = "abandon" - or - wrong = "abondoned" and right = "abandoned" - or - wrong = "abondoning" and right = "abandoning" - or - wrong = "abondons" and right = "abandons" - or - wrong = "aborigene" and right = "aborigine" - or - wrong = "abortificant" and right = "abortifacient" - or - wrong = "abotu" and right = "about" - or - wrong = "abreviate" and right = "abbreviate" - or - wrong = "abreviated" and right = "abbreviated" - or - wrong = "abreviation" and right = "abbreviation" - or - wrong = "abritrary" and right = "arbitrary" - or - wrong = "absail" and right = "abseil" - or - wrong = "absailing" and right = "abseiling" - or - wrong = "abscence" and right = "absence" - or - wrong = "absense" and right = "absence" - or - wrong = "absolutly" and right = "absolutely" - or - wrong = "absorbsion" and right = "absorption" - or - wrong = "absorbtion" and right = "absorption" - or - wrong = "abudance" and right = "abundance" - or - wrong = "abundacies" and right = "abundances" - or - wrong = "abundancies" and right = "abundances" - or - wrong = "abundunt" and right = "abundant" - or - wrong = "abutts" and right = "abuts" - or - wrong = "acadamy" and right = "academy" - or - wrong = "acadmic" and right = "academic" - or - wrong = "accademic" and right = "academic" - or - wrong = "accademy" and right = "academy" - or - wrong = "acccess" and right = "access" - or - wrong = "acccused" and right = "accused" - or - wrong = "accelleration" and right = "acceleration" - or - wrong = "accension" and right = "accession" - or - wrong = "accension" and right = "ascension" - or - wrong = "acceptence" and right = "acceptance" - or - wrong = "acceptible" and right = "acceptable" - or - wrong = "accesories" and right = "accessories" - or - wrong = "accessable" and right = "accessible" - or - wrong = "accidant" and right = "accident" - or - wrong = "accidentaly" and right = "accidentally" - or - wrong = "accidently" and right = "accidentally" - or - wrong = "acclimitization" and right = "acclimatization" - or - wrong = "accomadate" and right = "accommodate" - or - wrong = "accomadated" and right = "accommodated" - or - wrong = "accomadates" and right = "accommodates" - or - wrong = "accomadating" and right = "accommodating" - or - wrong = "accomadation" and right = "accommodation" - or - wrong = "accomadations" and right = "accommodations" - or - wrong = "accomdate" and right = "accommodate" - or - wrong = "accomodate" and right = "accommodate" - or - wrong = "accomodated" and right = "accommodated" - or - wrong = "accomodates" and right = "accommodates" - or - wrong = "accomodating" and right = "accommodating" - or - wrong = "accomodation" and right = "accommodation" - or - wrong = "accomodations" and right = "accommodations" - or - wrong = "accompanyed" and right = "accompanied" - or - wrong = "accordeon" and right = "accordion" - or - wrong = "accordian" and right = "accordion" - or - wrong = "accoring" and right = "according" - or - wrong = "accoustic" and right = "acoustic" - or - wrong = "accquainted" and right = "acquainted" - or - wrong = "accrediation" and right = "accreditation" - or - wrong = "accredidation" and right = "accreditation" - or - wrong = "accross" and right = "across" - or - wrong = "accussed" and right = "accused" - or - wrong = "acedemic" and right = "academic" - or - wrong = "acheive" and right = "achieve" - or - wrong = "acheived" and right = "achieved" - or - wrong = "acheivement" and right = "achievement" - or - wrong = "acheivements" and right = "achievements" - or - wrong = "acheives" and right = "achieves" - or - wrong = "acheiving" and right = "achieving" - or - wrong = "acheivment" and right = "achievement" - or - wrong = "acheivments" and right = "achievements" - or - wrong = "achievment" and right = "achievement" - or - wrong = "achievments" and right = "achievements" - or - wrong = "achive" and right = "achieve" - or - wrong = "achive" and right = "archive" - or - wrong = "achived" and right = "achieved" - or - wrong = "achived" and right = "archived" - or - wrong = "achivement" and right = "achievement" - or - wrong = "achivements" and right = "achievements" - or - wrong = "acident" and right = "accident" - or - wrong = "acknowldeged" and right = "acknowledged" - or - wrong = "acknowledgeing" and right = "acknowledging" - or - wrong = "ackward" and right = "awkward" - or - wrong = "ackward" and right = "backward" - or - wrong = "acommodate" and right = "accommodate" - or - wrong = "acomplish" and right = "accomplish" - or - wrong = "acomplished" and right = "accomplished" - or - wrong = "acomplishment" and right = "accomplishment" - or - wrong = "acomplishments" and right = "accomplishments" - or - wrong = "acording" and right = "according" - or - wrong = "acordingly" and right = "accordingly" - or - wrong = "acquaintence" and right = "acquaintance" - or - wrong = "acquaintences" and right = "acquaintances" - or - wrong = "acquiantence" and right = "acquaintance" - or - wrong = "acquiantences" and right = "acquaintances" - or - wrong = "acquited" and right = "acquitted" - or - wrong = "activites" and right = "activities" - or - wrong = "activly" and right = "actively" - or - wrong = "actualy" and right = "actually" - or - wrong = "acuracy" and right = "accuracy" - or - wrong = "acused" and right = "accused" - or - wrong = "acustom" and right = "accustom" - or - wrong = "acustommed" and right = "accustomed" - or - wrong = "adapater" and right = "adapter" - or - wrong = "adavanced" and right = "advanced" - or - wrong = "adbandon" and right = "abandon" - or - wrong = "addional" and right = "additional" - or - wrong = "addionally" and right = "additionally" - or - wrong = "additinally" and right = "additionally" - or - wrong = "additionaly" and right = "additionally" - or - wrong = "additonal" and right = "additional" - or - wrong = "additonally" and right = "additionally" - or - wrong = "addmission" and right = "admission" - or - wrong = "addopt" and right = "adopt" - or - wrong = "addopted" and right = "adopted" - or - wrong = "addoptive" and right = "adoptive" - or - wrong = "addres" and right = "adders" - or - wrong = "addres" and right = "address" - or - wrong = "addresable" and right = "addressable" - or - wrong = "addresed" and right = "addressed" - or - wrong = "addresing" and right = "addressing" - or - wrong = "addressess" and right = "addresses" - or - wrong = "addtion" and right = "addition" - or - wrong = "addtional" and right = "additional" - or - wrong = "adecuate" and right = "adequate" - or - wrong = "adequit" and right = "adequate" - or - wrong = "adhearing" and right = "adhering" - or - wrong = "adherance" and right = "adherence" - or - wrong = "admendment" and right = "amendment" - or - wrong = "admininistrative" and right = "administrative" - or - wrong = "adminstered" and right = "administered" - or - wrong = "adminstrate" and right = "administrate" - or - wrong = "adminstration" and right = "administration" - or - wrong = "adminstrative" and right = "administrative" - or - wrong = "adminstrator" and right = "administrator" - or - wrong = "admissability" and right = "admissibility" - or - wrong = "admissable" and right = "admissible" - or - wrong = "admited" and right = "admitted" - or - wrong = "admitedly" and right = "admittedly" - or - wrong = "adn" and right = "and" - or - wrong = "adolecent" and right = "adolescent" - or - wrong = "adquire" and right = "acquire" - or - wrong = "adquired" and right = "acquired" - or - wrong = "adquires" and right = "acquires" - or - wrong = "adquiring" and right = "acquiring" - or - wrong = "adres" and right = "address" - or - wrong = "adresable" and right = "addressable" - or - wrong = "adresing" and right = "addressing" - or - wrong = "adress" and right = "address" - or - wrong = "adressable" and right = "addressable" - or - wrong = "adressed" and right = "addressed" - or - wrong = "adressing" and right = "addressing" - or - wrong = "adressing" and right = "dressing" - or - wrong = "adventrous" and right = "adventurous" - or - wrong = "advertisment" and right = "advertisement" - or - wrong = "advertisments" and right = "advertisements" - or - wrong = "advesary" and right = "adversary" - or - wrong = "adviced" and right = "advised" - or - wrong = "aeriel" and right = "aerial" - or - wrong = "aeriels" and right = "aerials" - or - wrong = "afair" and right = "affair" - or - wrong = "afficianados" and right = "aficionados" - or - wrong = "afficionado" and right = "aficionado" - or - wrong = "afficionados" and right = "aficionados" - or - wrong = "affilate" and right = "affiliate" - or - wrong = "affilliate" and right = "affiliate" - or - wrong = "affort" and right = "afford" - or - wrong = "affort" and right = "effort" - or - wrong = "aforememtioned" and right = "aforementioned" - or - wrong = "againnst" and right = "against" - or - wrong = "agains" and right = "against" - or - wrong = "agaisnt" and right = "against" - or - wrong = "aganist" and right = "against" - or - wrong = "aggaravates" and right = "aggravates" - or - wrong = "aggreed" and right = "agreed" - or - wrong = "aggreement" and right = "agreement" - or - wrong = "aggregious" and right = "egregious" - or - wrong = "aggresive" and right = "aggressive" - or - wrong = "agian" and right = "again" - or - wrong = "agianst" and right = "against" - or - wrong = "agin" and right = "again" - or - wrong = "agina" and right = "again" - or - wrong = "agina" and right = "angina" - or - wrong = "aginst" and right = "against" - or - wrong = "agravate" and right = "aggravate" - or - wrong = "agre" and right = "agree" - or - wrong = "agred" and right = "agreed" - or - wrong = "agreeement" and right = "agreement" - or - wrong = "agreemnt" and right = "agreement" - or - wrong = "agregate" and right = "aggregate" - or - wrong = "agregates" and right = "aggregates" - or - wrong = "agreing" and right = "agreeing" - or - wrong = "agression" and right = "aggression" - or - wrong = "agressive" and right = "aggressive" - or - wrong = "agressively" and right = "aggressively" - or - wrong = "agressor" and right = "aggressor" - or - wrong = "agricultue" and right = "agriculture" - or - wrong = "agriculure" and right = "agriculture" - or - wrong = "agricuture" and right = "agriculture" - or - wrong = "agrieved" and right = "aggrieved" - or - wrong = "agrument" and right = "argument" - or - wrong = "agruments" and right = "arguments" - or - wrong = "ahev" and right = "have" - or - wrong = "ahppen" and right = "happen" - or - wrong = "ahve" and right = "have" - or - wrong = "aicraft" and right = "aircraft" - or - wrong = "aiport" and right = "airport" - or - wrong = "airbourne" and right = "airborne" - or - wrong = "aircaft" and right = "aircraft" - or - wrong = "aircrafts" and right = "aircraft" - or - wrong = "airporta" and right = "airports" - or - wrong = "airrcraft" and right = "aircraft" - or - wrong = "aisian" and right = "asian" - or - wrong = "albiet" and right = "albeit" - or - wrong = "alchohol" and right = "alcohol" - or - wrong = "alchoholic" and right = "alcoholic" - or - wrong = "alchol" and right = "alcohol" - or - wrong = "alcholic" and right = "alcoholic" - or - wrong = "alcohal" and right = "alcohol" - or - wrong = "alcoholical" and right = "alcoholic" - or - wrong = "aledge" and right = "allege" - or - wrong = "aledged" and right = "alleged" - or - wrong = "aledges" and right = "alleges" - or - wrong = "alege" and right = "allege" - or - wrong = "aleged" and right = "alleged" - or - wrong = "alegience" and right = "allegiance" - or - wrong = "algebraical" and right = "algebraic" - or - wrong = "algorhitms" and right = "algorithms" - or - wrong = "algoritm" and right = "algorithm" - or - wrong = "algoritms" and right = "algorithms" - or - wrong = "alientating" and right = "alienating" - or - wrong = "alledge" and right = "allege" - or - wrong = "alledged" and right = "alleged" - or - wrong = "alledgedly" and right = "allegedly" - or - wrong = "alledges" and right = "alleges" - or - wrong = "allegedely" and right = "allegedly" - or - wrong = "allegedy" and right = "allegedly" - or - wrong = "allegely" and right = "allegedly" - or - wrong = "allegence" and right = "allegiance" - or - wrong = "allegience" and right = "allegiance" - or - wrong = "allign" and right = "align" - or - wrong = "alligned" and right = "aligned" - or - wrong = "alliviate" and right = "alleviate" - or - wrong = "allopone" and right = "allophone" - or - wrong = "allopones" and right = "allophones" - or - wrong = "allready" and right = "already" - or - wrong = "allthough" and right = "although" - or - wrong = "alltogether" and right = "altogether" - or - wrong = "almsot" and right = "almost" - or - wrong = "alochol" and right = "alcohol" - or - wrong = "alomst" and right = "almost" - or - wrong = "alot" and right = "allot" - or - wrong = "alotted" and right = "allotted" - or - wrong = "alowed" and right = "allowed" - or - wrong = "alowing" and right = "allowing" - or - wrong = "alreayd" and right = "already" - or - wrong = "alse" and right = "else" - or - wrong = "alsot" and right = "also" - or - wrong = "alternitives" and right = "alternatives" - or - wrong = "altho" and right = "although" - or - wrong = "althought" and right = "although" - or - wrong = "altough" and right = "although" - or - wrong = "alusion" and right = "allusion" - or - wrong = "alusion" and right = "illusion" - or - wrong = "alwasy" and right = "always" - or - wrong = "alwyas" and right = "always" - or - wrong = "amalgomated" and right = "amalgamated" - or - wrong = "amatuer" and right = "amateur" - or - wrong = "amature" and right = "amateur" - or - wrong = "amature" and right = "armature" - or - wrong = "amendmant" and right = "amendment" - or - wrong = "amercia" and right = "america" - or - wrong = "amerliorate" and right = "ameliorate" - or - wrong = "amke" and right = "make" - or - wrong = "amking" and right = "making" - or - wrong = "ammend" and right = "amend" - or - wrong = "ammended" and right = "amended" - or - wrong = "ammendment" and right = "amendment" - or - wrong = "ammendments" and right = "amendments" - or - wrong = "ammount" and right = "amount" - or - wrong = "ammused" and right = "amused" - or - wrong = "amoung" and right = "among" - or - wrong = "amoungst" and right = "amongst" - or - wrong = "amung" and right = "among" - or - wrong = "amunition" and right = "ammunition" - or - wrong = "analagous" and right = "analogous" - or - wrong = "analitic" and right = "analytic" - or - wrong = "analogeous" and right = "analogous" - or - wrong = "anarchim" and right = "anarchism" - or - wrong = "anarchistm" and right = "anarchism" - or - wrong = "anbd" and right = "and" - or - wrong = "ancestory" and right = "ancestry" - or - wrong = "ancilliary" and right = "ancillary" - or - wrong = "andd" and right = "and" - or - wrong = "androgenous" and right = "androgynous" - or - wrong = "androgeny" and right = "androgyny" - or - wrong = "anihilation" and right = "annihilation" - or - wrong = "aniversary" and right = "anniversary" - or - wrong = "annoint" and right = "anoint" - or - wrong = "annointed" and right = "anointed" - or - wrong = "annointing" and right = "anointing" - or - wrong = "annoints" and right = "anoints" - or - wrong = "annouced" and right = "announced" - or - wrong = "annualy" and right = "annually" - or - wrong = "annuled" and right = "annulled" - or - wrong = "anohter" and right = "another" - or - wrong = "anomolies" and right = "anomalies" - or - wrong = "anomolous" and right = "anomalous" - or - wrong = "anomoly" and right = "anomaly" - or - wrong = "anonimity" and right = "anonymity" - or - wrong = "anounced" and right = "announced" - or - wrong = "anouncement" and right = "announcement" - or - wrong = "ansalisation" and right = "nasalisation" - or - wrong = "ansalization" and right = "nasalization" - or - wrong = "ansestors" and right = "ancestors" - or - wrong = "antartic" and right = "antarctic" - or - wrong = "anthromorphization" and right = "anthropomorphization" - or - wrong = "anthropolgist" and right = "anthropologist" - or - wrong = "anthropolgy" and right = "anthropology" - or - wrong = "anual" and right = "annual" - or - wrong = "anulled" and right = "annulled" - or - wrong = "anwsered" and right = "answered" - or - wrong = "anyhwere" and right = "anywhere" - or - wrong = "anytying" and right = "anything" - or - wrong = "aparent" and right = "apparent" - or - wrong = "aparment" and right = "apartment" - or - wrong = "apenines" and right = "apennines" - or - wrong = "aplication" and right = "application" - or - wrong = "aplied" and right = "applied" - or - wrong = "apolegetics" and right = "apologetics" - or - wrong = "apon" and right = "apron" - or - wrong = "apon" and right = "upon" - or - wrong = "apparant" and right = "apparent" - or - wrong = "apparantly" and right = "apparently" - or - wrong = "appart" and right = "apart" - or - wrong = "appartment" and right = "apartment" - or - wrong = "appartments" and right = "apartments" - or - wrong = "appealling" and right = "appalling" - or - wrong = "appealling" and right = "appealing" - or - wrong = "appeareance" and right = "appearance" - or - wrong = "appearence" and right = "appearance" - or - wrong = "appearences" and right = "appearances" - or - wrong = "appenines" and right = "apennines" - or - wrong = "apperance" and right = "appearance" - or - wrong = "apperances" and right = "appearances" - or - wrong = "appereance" and right = "appearance" - or - wrong = "appereances" and right = "appearances" - or - wrong = "applicaiton" and right = "application" - or - wrong = "applicaitons" and right = "applications" - or - wrong = "appologies" and right = "apologies" - or - wrong = "appology" and right = "apology" - or - wrong = "apprearance" and right = "appearance" - or - wrong = "apprieciate" and right = "appreciate" - or - wrong = "approachs" and right = "approaches" - or - wrong = "appropiate" and right = "appropriate" - or - wrong = "appropraite" and right = "appropriate" - or - wrong = "appropropiate" and right = "appropriate" - or - wrong = "approproximate" and right = "approximate" - or - wrong = "approxamately" and right = "approximately" - or - wrong = "approxiately" and right = "approximately" - or - wrong = "approximitely" and right = "approximately" - or - wrong = "aprehensive" and right = "apprehensive" - or - wrong = "apropriate" and right = "appropriate" - or - wrong = "aproval" and right = "approval" - or - wrong = "aproximate" and right = "approximate" - or - wrong = "aproximately" and right = "approximately" - or - wrong = "aquaduct" and right = "aqueduct" - or - wrong = "aquaintance" and right = "acquaintance" - or - wrong = "aquainted" and right = "acquainted" - or - wrong = "aquiantance" and right = "acquaintance" - or - wrong = "aquire" and right = "acquire" - or - wrong = "aquired" and right = "acquired" - or - wrong = "aquiring" and right = "acquiring" - or - wrong = "aquisition" and right = "acquisition" - or - wrong = "aquitted" and right = "acquitted" - or - wrong = "aranged" and right = "arranged" - or - wrong = "arangement" and right = "arrangement" - or - wrong = "arbitarily" and right = "arbitrarily" - or - wrong = "arbitary" and right = "arbitrary" - or - wrong = "archaelogical" and right = "archaeological" - or - wrong = "archaelogists" and right = "archaeologists" - or - wrong = "archaelogy" and right = "archaeology" - or - wrong = "archaoelogy" and right = "archaeology" - or - wrong = "archaoelogy" and right = "archeology" - or - wrong = "archaology" and right = "archaeology" - or - wrong = "archaology" and right = "archeology" - or - wrong = "archeaologist" and right = "archaeologist" - or - wrong = "archeaologist" and right = "archeologist" - or - wrong = "archeaologists" and right = "archaeologists" - or - wrong = "archeaologists" and right = "archeologists" - or - wrong = "archetect" and right = "architect" - or - wrong = "archetects" and right = "architects" - or - wrong = "archetectural" and right = "architectural" - or - wrong = "archetecturally" and right = "architecturally" - or - wrong = "archetecture" and right = "architecture" - or - wrong = "archiac" and right = "archaic" - or - wrong = "archictect" and right = "architect" - or - wrong = "archimedian" and right = "archimedean" - or - wrong = "architecht" and right = "architect" - or - wrong = "architechturally" and right = "architecturally" - or - wrong = "architechture" and right = "architecture" - or - wrong = "architechtures" and right = "architectures" - or - wrong = "architectual" and right = "architectural" - or - wrong = "archtype" and right = "archetype" - or - wrong = "archtypes" and right = "archetypes" - or - wrong = "aready" and right = "already" - or - wrong = "areodynamics" and right = "aerodynamics" - or - wrong = "argubly" and right = "arguably" - or - wrong = "arguement" and right = "argument" - or - wrong = "arguements" and right = "arguments" - or - wrong = "arised" and right = "arose" - or - wrong = "arival" and right = "arrival" - or - wrong = "armamant" and right = "armament" - or - wrong = "armistace" and right = "armistice" - or - wrong = "arogant" and right = "arrogant" - or - wrong = "arogent" and right = "arrogant" - or - wrong = "aroud" and right = "around" - or - wrong = "arrangment" and right = "arrangement" - or - wrong = "arrangments" and right = "arrangements" - or - wrong = "arrengement" and right = "arrangement" - or - wrong = "arrengements" and right = "arrangements" - or - wrong = "arround" and right = "around" - or - wrong = "artcile" and right = "article" - or - wrong = "artical" and right = "article" - or - wrong = "artice" and right = "article" - or - wrong = "articel" and right = "article" - or - wrong = "artifical" and right = "artificial" - or - wrong = "artifically" and right = "artificially" - or - wrong = "artillary" and right = "artillery" - or - wrong = "arund" and right = "around" - or - wrong = "asetic" and right = "ascetic" - or - wrong = "asign" and right = "assign" - or - wrong = "aslo" and right = "also" - or - wrong = "asnyc" and right = "async" - or - wrong = "asociated" and right = "associated" - or - wrong = "asorbed" and right = "absorbed" - or - wrong = "asphyxation" and right = "asphyxiation" - or - wrong = "assasin" and right = "assassin" - or - wrong = "assasinate" and right = "assassinate" - or - wrong = "assasinated" and right = "assassinated" - or - wrong = "assasinates" and right = "assassinates" - or - wrong = "assasination" and right = "assassination" - or - wrong = "assasinations" and right = "assassinations" - or - wrong = "assasined" and right = "assassinated" - or - wrong = "assasins" and right = "assassins" - or - wrong = "assassintation" and right = "assassination" - or - wrong = "assemple" and right = "assemble" - or - wrong = "assertation" and right = "assertion" - or - wrong = "asside" and right = "aside" - or - wrong = "assisnate" and right = "assassinate" - or - wrong = "assit" and right = "assist" - or - wrong = "assitant" and right = "assistant" - or - wrong = "assocation" and right = "association" - or - wrong = "assoicate" and right = "associate" - or - wrong = "assoicated" and right = "associated" - or - wrong = "assoicates" and right = "associates" - or - wrong = "assosication" and right = "assassination" - or - wrong = "asssassans" and right = "assassins" - or - wrong = "assualt" and right = "assault" - or - wrong = "assualted" and right = "assaulted" - or - wrong = "assymetric" and right = "asymmetric" - or - wrong = "assymetrical" and right = "asymmetrical" - or - wrong = "asteriod" and right = "asteroid" - or - wrong = "asthetic" and right = "aesthetic" - or - wrong = "asthetical" and right = "aesthetical" - or - wrong = "asthetically" and right = "aesthetically" - or - wrong = "asume" and right = "assume" - or - wrong = "atain" and right = "attain" - or - wrong = "atempting" and right = "attempting" - or - wrong = "atheistical" and right = "atheistic" - or - wrong = "athenean" and right = "athenian" - or - wrong = "atheneans" and right = "athenians" - or - wrong = "athiesm" and right = "atheism" - or - wrong = "athiest" and right = "atheist" - or - wrong = "atorney" and right = "attorney" - or - wrong = "atribute" and right = "attribute" - or - wrong = "atributed" and right = "attributed" - or - wrong = "atributes" and right = "attributes" - or - wrong = "attaindre" and right = "attainder" - or - wrong = "attaindre" and right = "attained" - or - wrong = "attemp" and right = "attempt" - or - wrong = "attemped" and right = "attempted" - or - wrong = "attemt" and right = "attempt" - or - wrong = "attemted" and right = "attempted" - or - wrong = "attemting" and right = "attempting" - or - wrong = "attemts" and right = "attempts" - or - wrong = "attendence" and right = "attendance" - or - wrong = "attendent" and right = "attendant" - or - wrong = "attendents" and right = "attendants" - or - wrong = "attened" and right = "attended" - or - wrong = "attension" and right = "attention" - or - wrong = "attitide" and right = "attitude" - or - wrong = "attributred" and right = "attributed" - or - wrong = "attrocities" and right = "atrocities" - or - wrong = "audeince" and right = "audience" - or - wrong = "auromated" and right = "automated" - or - wrong = "austrailia" and right = "australia" - or - wrong = "austrailian" and right = "australian" - or - wrong = "auther" and right = "author" - or - wrong = "authobiographic" and right = "autobiographic" - or - wrong = "authobiography" and right = "autobiography" - or - wrong = "authorative" and right = "authoritative" - or - wrong = "authorites" and right = "authorities" - or - wrong = "authorithy" and right = "authority" - or - wrong = "authoritiers" and right = "authorities" - or - wrong = "authoritive" and right = "authoritative" - or - wrong = "authrorities" and right = "authorities" - or - wrong = "autochtonous" and right = "autochthonous" - or - wrong = "autoctonous" and right = "autochthonous" - or - wrong = "automaticly" and right = "automatically" - or - wrong = "automibile" and right = "automobile" - or - wrong = "automonomous" and right = "autonomous" - or - wrong = "autor" and right = "author" - or - wrong = "autority" and right = "authority" - or - wrong = "auxilary" and right = "auxiliary" - or - wrong = "auxillaries" and right = "auxiliaries" - or - wrong = "auxillary" and right = "auxiliary" - or - wrong = "auxilliaries" and right = "auxiliaries" - or - wrong = "auxilliary" and right = "auxiliary" - or - wrong = "availabe" and right = "available" - or - wrong = "availablity" and right = "availability" - or - wrong = "availaible" and right = "available" - or - wrong = "availble" and right = "available" - or - wrong = "availiable" and right = "available" - or - wrong = "availible" and right = "available" - or - wrong = "avalable" and right = "available" - or - wrong = "avalance" and right = "avalanche" - or - wrong = "avaliable" and right = "available" - or - wrong = "avation" and right = "aviation" - or - wrong = "averageed" and right = "averaged" - or - wrong = "avilable" and right = "available" - or - wrong = "awared" and right = "awarded" - or - wrong = "awya" and right = "away" - or - wrong = "baceause" and right = "because" - or - wrong = "backgorund" and right = "background" - or - wrong = "backrounds" and right = "backgrounds" - or - wrong = "bakc" and right = "back" - or - wrong = "banannas" and right = "bananas" - or - wrong = "bandwith" and right = "bandwidth" - or - wrong = "bankrupcy" and right = "bankruptcy" - or - wrong = "banruptcy" and right = "bankruptcy" - or - wrong = "baout" and right = "about" - or - wrong = "baout" and right = "bout" - or - wrong = "basicaly" and right = "basically" - or - wrong = "basicly" and right = "basically" - or - wrong = "bcak" and right = "back" - or - wrong = "beachead" and right = "beachhead" - or - wrong = "beacuse" and right = "because" - or - wrong = "beastiality" and right = "bestiality" - or - wrong = "beatiful" and right = "beautiful" - or - wrong = "beaurocracy" and right = "bureaucracy" - or - wrong = "beaurocratic" and right = "bureaucratic" - or - wrong = "beautyfull" and right = "beautiful" - or - wrong = "becamae" and right = "became" - or - wrong = "becames" and right = "became" - or - wrong = "becames" and right = "becomes" - or - wrong = "becasue" and right = "because" - or - wrong = "beccause" and right = "because" - or - wrong = "becomeing" and right = "becoming" - or - wrong = "becomming" and right = "becoming" - or - wrong = "becouse" and right = "because" - or - wrong = "becuase" and right = "because" - or - wrong = "bedore" and right = "before" - or - wrong = "beeing" and right = "being" - or - wrong = "befoer" and right = "before" - or - wrong = "beggin" and right = "begging" - or - wrong = "beggin" and right = "begin" - or - wrong = "begginer" and right = "beginner" - or - wrong = "begginers" and right = "beginners" - or - wrong = "beggining" and right = "beginning" - or - wrong = "begginings" and right = "beginnings" - or - wrong = "beggins" and right = "begins" - or - wrong = "begining" and right = "beginning" - or - wrong = "beginnig" and right = "beginning" - or - wrong = "behavour" and right = "behavior" - or - wrong = "behavour" and right = "behaviour" - or - wrong = "beleagured" and right = "beleaguered" - or - wrong = "beleif" and right = "belief" - or - wrong = "beleive" and right = "believe" - or - wrong = "beleived" and right = "believed" - or - wrong = "beleives" and right = "believes" - or - wrong = "beleiving" and right = "believing" - or - wrong = "beligum" and right = "belgium" - or - wrong = "belive" and right = "believe" - or - wrong = "belived" and right = "believed" - or - wrong = "belived" and right = "beloved" - or - wrong = "belives" and right = "beliefs" - or - wrong = "belives" and right = "believes" - or - wrong = "belligerant" and right = "belligerent" - or - wrong = "bellweather" and right = "bellwether" - or - wrong = "bemusemnt" and right = "bemusement" - or - wrong = "beneficary" and right = "beneficiary" - or - wrong = "beng" and right = "being" - or - wrong = "benificial" and right = "beneficial" - or - wrong = "benifit" and right = "benefit" - or - wrong = "benifits" and right = "benefits" - or - wrong = "bergamont" and right = "bergamot" - or - wrong = "bernouilli" and right = "bernoulli" - or - wrong = "beseige" and right = "besiege" - or - wrong = "beseiged" and right = "besieged" - or - wrong = "beseiging" and right = "besieging" - or - wrong = "beteen" and right = "between" - or - wrong = "betwen" and right = "between" - or - wrong = "beween" and right = "between" - or - wrong = "bewteen" and right = "between" - or - wrong = "bigining" and right = "beginning" - or - wrong = "biginning" and right = "beginning" - or - wrong = "bilateraly" and right = "bilaterally" - or - wrong = "billingualism" and right = "bilingualism" - or - wrong = "binominal" and right = "binomial" - or - wrong = "bizzare" and right = "bizarre" - or - wrong = "blaim" and right = "blame" - or - wrong = "blaimed" and right = "blamed" - or - wrong = "blessure" and right = "blessing" - or - wrong = "blitzkreig" and right = "blitzkrieg" - or - wrong = "boaut" and right = "about" - or - wrong = "boaut" and right = "boat" - or - wrong = "boaut" and right = "bout" - or - wrong = "bodydbuilder" and right = "bodybuilder" - or - wrong = "bolean" and right = "boolean" - or - wrong = "bombardement" and right = "bombardment" - or - wrong = "bombarment" and right = "bombardment" - or - wrong = "bondary" and right = "boundary" - or - wrong = "bonnano" and right = "bonanno" - or - wrong = "boook" and right = "book" - or - wrong = "borke" and right = "broke" - or - wrong = "boundry" and right = "boundary" - or - wrong = "bouyancy" and right = "buoyancy" - or - wrong = "bouyant" and right = "buoyant" - or - wrong = "boyant" and right = "buoyant" - or - wrong = "bradcast" and right = "broadcast" - or - wrong = "brasillian" and right = "brazilian" - or - wrong = "breakthough" and right = "breakthrough" - or - wrong = "breakthroughts" and right = "breakthroughs" - or - wrong = "breif" and right = "brief" - or - wrong = "breifly" and right = "briefly" - or - wrong = "brethen" and right = "brethren" - or - wrong = "bretheren" and right = "brethren" - or - wrong = "briliant" and right = "brilliant" - or - wrong = "brillant" and right = "brilliant" - or - wrong = "brimestone" and right = "brimstone" - or - wrong = "britian" and right = "britain" - or - wrong = "brittish" and right = "british" - or - wrong = "broacasted" and right = "broadcast" - or - wrong = "broadacasting" and right = "broadcasting" - or - wrong = "broady" and right = "broadly" - or - wrong = "buddah" and right = "buddha" - or - wrong = "buddist" and right = "buddhist" - or - wrong = "buisness" and right = "business" - or - wrong = "buisnessman" and right = "businessman" - or - wrong = "buoancy" and right = "buoyancy" - or - wrong = "buring" and right = "burin" - or - wrong = "buring" and right = "burning" - or - wrong = "buring" and right = "burying" - or - wrong = "buring" and right = "during" - or - wrong = "burried" and right = "buried" - or - wrong = "busines" and right = "business" - or - wrong = "busineses" and right = "business" - or - wrong = "busineses" and right = "businesses" - or - wrong = "busness" and right = "business" - or - wrong = "bussiness" and right = "business" - or - wrong = "caculater" and right = "calculator" - or - wrong = "cacuses" and right = "caucuses" - or - wrong = "cahracters" and right = "characters" - or - wrong = "calaber" and right = "caliber" - or - wrong = "calander" and right = "calendar" - or - wrong = "calander" and right = "calender" - or - wrong = "calander" and right = "colander" - or - wrong = "calculater" and right = "calculator" - or - wrong = "calculs" and right = "calculus" - or - wrong = "calender" and right = "calendar" - or - wrong = "calenders" and right = "calendars" - or - wrong = "caligraphy" and right = "calligraphy" - or - wrong = "caluclate" and right = "calculate" - or - wrong = "caluclated" and right = "calculated" - or - wrong = "caluculate" and right = "calculate" - or - wrong = "caluculated" and right = "calculated" - or - wrong = "calulate" and right = "calculate" - or - wrong = "calulated" and right = "calculated" - or - wrong = "calulater" and right = "calculator" - or - wrong = "cambrige" and right = "cambridge" - or - wrong = "camoflage" and right = "camouflage" - or - wrong = "campagin" and right = "campaign" - or - wrong = "campain" and right = "campaign" - or - wrong = "campains" and right = "campaigns" - or - wrong = "candadate" and right = "candidate" - or - wrong = "candiate" and right = "candidate" - or - wrong = "candidiate" and right = "candidate" - or - wrong = "cannister" and right = "canister" - or - wrong = "cannisters" and right = "canisters" - or - wrong = "cannnot" and right = "cannot" - or - wrong = "cannonical" and right = "canonical" - or - wrong = "cannotation" and right = "connotation" - or - wrong = "cannotations" and right = "connotations" - or - wrong = "caost" and right = "coast" - or - wrong = "caperbility" and right = "capability" - or - wrong = "capible" and right = "capable" - or - wrong = "captial" and right = "capital" - or - wrong = "captued" and right = "captured" - or - wrong = "capturd" and right = "captured" - or - wrong = "carachter" and right = "character" - or - wrong = "caracterized" and right = "characterized" - or - wrong = "carcas" and right = "caracas" - or - wrong = "carcas" and right = "carcass" - or - wrong = "carefull" and right = "careful" - or - wrong = "careing" and right = "caring" - or - wrong = "carismatic" and right = "charismatic" - or - wrong = "carmalite" and right = "carmelite" - or - wrong = "carnagie" and right = "carnegie" - or - wrong = "carnege" and right = "carnage" - or - wrong = "carnege" and right = "carnegie" - or - wrong = "carnige" and right = "carnage" - or - wrong = "carnige" and right = "carnegie" - or - wrong = "carnigie" and right = "carnegie" - or - wrong = "carreer" and right = "career" - or - wrong = "carrers" and right = "careers" - or - wrong = "carribbean" and right = "caribbean" - or - wrong = "carribean" and right = "caribbean" - or - wrong = "carryng" and right = "carrying" - or - wrong = "cartdridge" and right = "cartridge" - or - wrong = "carthagian" and right = "carthaginian" - or - wrong = "carthographer" and right = "cartographer" - or - wrong = "cartilege" and right = "cartilage" - or - wrong = "cartilidge" and right = "cartilage" - or - wrong = "cartrige" and right = "cartridge" - or - wrong = "casette" and right = "cassette" - or - wrong = "casion" and right = "caisson" - or - wrong = "cassawory" and right = "cassowary" - or - wrong = "cassowarry" and right = "cassowary" - or - wrong = "casue" and right = "cause" - or - wrong = "casued" and right = "caused" - or - wrong = "casues" and right = "causes" - or - wrong = "casuing" and right = "causing" - or - wrong = "casulaties" and right = "casualties" - or - wrong = "casulaty" and right = "casualty" - or - wrong = "catagories" and right = "categories" - or - wrong = "catagorized" and right = "categorized" - or - wrong = "catagory" and right = "category" - or - wrong = "cataline" and right = "catalina" - or - wrong = "cataline" and right = "catiline" - or - wrong = "catapillar" and right = "caterpillar" - or - wrong = "catapillars" and right = "caterpillars" - or - wrong = "catapiller" and right = "caterpillar" - or - wrong = "catapillers" and right = "caterpillars" - or - wrong = "catepillar" and right = "caterpillar" - or - wrong = "catepillars" and right = "caterpillars" - or - wrong = "catergorize" and right = "categorize" - or - wrong = "catergorized" and right = "categorized" - or - wrong = "caterpilar" and right = "caterpillar" - or - wrong = "caterpilars" and right = "caterpillars" - or - wrong = "caterpiller" and right = "caterpillar" - or - wrong = "caterpillers" and right = "caterpillars" - or - wrong = "cathlic" and right = "catholic" - or - wrong = "catholocism" and right = "catholicism" - or - wrong = "catterpilar" and right = "caterpillar" - or - wrong = "catterpilars" and right = "caterpillars" - or - wrong = "catterpillar" and right = "caterpillar" - or - wrong = "catterpillars" and right = "caterpillars" - or - wrong = "cattleship" and right = "battleship" - or - wrong = "causalities" and right = "casualties" - or - wrong = "ceasar" and right = "caesar" - or - wrong = "celcius" and right = "celsius" - or - wrong = "cellpading" and right = "cellpadding" - or - wrong = "cementary" and right = "cemetery" - or - wrong = "cemetarey" and right = "cemetery" - or - wrong = "cemetaries" and right = "cemeteries" - or - wrong = "cemetary" and right = "cemetery" - or - wrong = "cencus" and right = "census" - or - wrong = "censur" and right = "censor" - or - wrong = "censur" and right = "censure" - or - wrong = "cententenial" and right = "centennial" - or - wrong = "centruies" and right = "centuries" - or - wrong = "centruy" and right = "century" - or - wrong = "centuties" and right = "centuries" - or - wrong = "centuty" and right = "century" - or - wrong = "ceratin" and right = "certain" - or - wrong = "ceratin" and right = "keratin" - or - wrong = "cerimonial" and right = "ceremonial" - or - wrong = "cerimonies" and right = "ceremonies" - or - wrong = "cerimonious" and right = "ceremonious" - or - wrong = "cerimony" and right = "ceremony" - or - wrong = "ceromony" and right = "ceremony" - or - wrong = "certainity" and right = "certainty" - or - wrong = "certian" and right = "certain" - or - wrong = "cervial" and right = "cervical" - or - wrong = "cervial" and right = "serval" - or - wrong = "cervial" and right = "servile" - or - wrong = "chalenging" and right = "challenging" - or - wrong = "challange" and right = "challenge" - or - wrong = "challanged" and right = "challenged" - or - wrong = "challege" and right = "challenge" - or - wrong = "champange" and right = "champagne" - or - wrong = "changable" and right = "changeable" - or - wrong = "charachter" and right = "character" - or - wrong = "charachters" and right = "characters" - or - wrong = "charactersistic" and right = "characteristic" - or - wrong = "charactor" and right = "character" - or - wrong = "charactors" and right = "characters" - or - wrong = "charasmatic" and right = "charismatic" - or - wrong = "charaterized" and right = "characterized" - or - wrong = "chariman" and right = "chairman" - or - wrong = "charistics" and right = "characteristics" - or - wrong = "chasr" and right = "chase" - or - wrong = "chasr" and right = "chaser" - or - wrong = "cheif" and right = "chief" - or - wrong = "cheifs" and right = "chiefs" - or - wrong = "chemcial" and right = "chemical" - or - wrong = "chemcially" and right = "chemically" - or - wrong = "chemestry" and right = "chemistry" - or - wrong = "chemicaly" and right = "chemically" - or - wrong = "childbird" and right = "childbirth" - or - wrong = "childen" and right = "children" - or - wrong = "choclate" and right = "chocolate" - or - wrong = "choosen" and right = "chosen" - or - wrong = "chracter" and right = "character" - or - wrong = "chuch" and right = "church" - or - wrong = "churchs" and right = "churches" - or - wrong = "cincinatti" and right = "cincinnati" - or - wrong = "cincinnatti" and right = "cincinnati" - or - wrong = "circulaton" and right = "circulation" - or - wrong = "circumsicion" and right = "circumcision" - or - wrong = "circut" and right = "circuit" - or - wrong = "ciricuit" and right = "circuit" - or - wrong = "ciriculum" and right = "curriculum" - or - wrong = "civillian" and right = "civilian" - or - wrong = "claer" and right = "clear" - or - wrong = "claerer" and right = "clearer" - or - wrong = "claerly" and right = "clearly" - or - wrong = "claimes" and right = "claims" - or - wrong = "clas" and right = "class" - or - wrong = "clasic" and right = "classic" - or - wrong = "clasical" and right = "classical" - or - wrong = "clasically" and right = "classically" - or - wrong = "cleareance" and right = "clearance" - or - wrong = "clera" and right = "clear" - or - wrong = "clera" and right = "sclera" - or - wrong = "clincial" and right = "clinical" - or - wrong = "clinicaly" and right = "clinically" - or - wrong = "cmo" and right = "com" - or - wrong = "cmoputer" and right = "computer" - or - wrong = "coctail" and right = "cocktail" - or - wrong = "coform" and right = "conform" - or - wrong = "cognizent" and right = "cognizant" - or - wrong = "coincedentally" and right = "coincidentally" - or - wrong = "colaborations" and right = "collaborations" - or - wrong = "colateral" and right = "collateral" - or - wrong = "colelctive" and right = "collective" - or - wrong = "collaberative" and right = "collaborative" - or - wrong = "collecton" and right = "collection" - or - wrong = "collegue" and right = "colleague" - or - wrong = "collegues" and right = "colleagues" - or - wrong = "collonade" and right = "colonnade" - or - wrong = "collonies" and right = "colonies" - or - wrong = "collony" and right = "colony" - or - wrong = "collosal" and right = "colossal" - or - wrong = "colonizators" and right = "colonizers" - or - wrong = "comander" and right = "commandeer" - or - wrong = "comander" and right = "commander" - or - wrong = "comando" and right = "commando" - or - wrong = "comandos" and right = "commandos" - or - wrong = "comany" and right = "company" - or - wrong = "comapany" and right = "company" - or - wrong = "comback" and right = "comeback" - or - wrong = "combanations" and right = "combinations" - or - wrong = "combinatins" and right = "combinations" - or - wrong = "combusion" and right = "combustion" - or - wrong = "comdemnation" and right = "condemnation" - or - wrong = "comemmorates" and right = "commemorates" - or - wrong = "comemoretion" and right = "commemoration" - or - wrong = "comision" and right = "commission" - or - wrong = "comisioned" and right = "commissioned" - or - wrong = "comisioner" and right = "commissioner" - or - wrong = "comisioning" and right = "commissioning" - or - wrong = "comisions" and right = "commissions" - or - wrong = "comission" and right = "commission" - or - wrong = "comissioned" and right = "commissioned" - or - wrong = "comissioner" and right = "commissioner" - or - wrong = "comissioning" and right = "commissioning" - or - wrong = "comissions" and right = "commissions" - or - wrong = "comited" and right = "committed" - or - wrong = "comiting" and right = "committing" - or - wrong = "comitted" and right = "committed" - or - wrong = "comittee" and right = "committee" - or - wrong = "comitting" and right = "committing" - or - wrong = "commandoes" and right = "commandos" - or - wrong = "commedic" and right = "comedic" - or - wrong = "commemerative" and right = "commemorative" - or - wrong = "commemmorate" and right = "commemorate" - or - wrong = "commemmorating" and right = "commemorating" - or - wrong = "commerical" and right = "commercial" - or - wrong = "commerically" and right = "commercially" - or - wrong = "commericial" and right = "commercial" - or - wrong = "commericially" and right = "commercially" - or - wrong = "commerorative" and right = "commemorative" - or - wrong = "comming" and right = "coming" - or - wrong = "comminication" and right = "communication" - or - wrong = "commision" and right = "commission" - or - wrong = "commisioned" and right = "commissioned" - or - wrong = "commisioner" and right = "commissioner" - or - wrong = "commisioning" and right = "commissioning" - or - wrong = "commisions" and right = "commissions" - or - wrong = "commited" and right = "committed" - or - wrong = "commitee" and right = "committee" - or - wrong = "commiting" and right = "committing" - or - wrong = "committe" and right = "committee" - or - wrong = "committment" and right = "commitment" - or - wrong = "committments" and right = "commitments" - or - wrong = "commmemorated" and right = "commemorated" - or - wrong = "commongly" and right = "commonly" - or - wrong = "commonweath" and right = "commonwealth" - or - wrong = "commuications" and right = "communications" - or - wrong = "commuinications" and right = "communications" - or - wrong = "communciation" and right = "communication" - or - wrong = "communiation" and right = "communication" - or - wrong = "communites" and right = "communities" - or - wrong = "compability" and right = "compatibility" - or - wrong = "comparision" and right = "comparison" - or - wrong = "comparisions" and right = "comparisons" - or - wrong = "comparitive" and right = "comparative" - or - wrong = "comparitively" and right = "comparatively" - or - wrong = "compatabilities" and right = "compatibilities" - or - wrong = "compatability" and right = "compatibility" - or - wrong = "compatable" and right = "compatible" - or - wrong = "compatablities" and right = "compatibilities" - or - wrong = "compatablity" and right = "compatibility" - or - wrong = "compatiable" and right = "compatible" - or - wrong = "compatiblities" and right = "compatibilities" - or - wrong = "compatiblity" and right = "compatibility" - or - wrong = "compeitions" and right = "competitions" - or - wrong = "compensantion" and right = "compensation" - or - wrong = "competance" and right = "competence" - or - wrong = "competant" and right = "competent" - or - wrong = "competative" and right = "competitive" - or - wrong = "competion" and right = "competition" - or - wrong = "competion" and right = "completion" - or - wrong = "competitiion" and right = "competition" - or - wrong = "competive" and right = "competitive" - or - wrong = "competiveness" and right = "competitiveness" - or - wrong = "comphrehensive" and right = "comprehensive" - or - wrong = "compitent" and right = "competent" - or - wrong = "completelyl" and right = "completely" - or - wrong = "completetion" and right = "completion" - or - wrong = "complier" and right = "compiler" - or - wrong = "componant" and right = "component" - or - wrong = "comprable" and right = "comparable" - or - wrong = "comprimise" and right = "compromise" - or - wrong = "compulsary" and right = "compulsory" - or - wrong = "compulsery" and right = "compulsory" - or - wrong = "computarized" and right = "computerized" - or - wrong = "concensus" and right = "consensus" - or - wrong = "concider" and right = "consider" - or - wrong = "concidered" and right = "considered" - or - wrong = "concidering" and right = "considering" - or - wrong = "conciders" and right = "considers" - or - wrong = "concieted" and right = "conceited" - or - wrong = "concieved" and right = "conceived" - or - wrong = "concious" and right = "conscious" - or - wrong = "conciously" and right = "consciously" - or - wrong = "conciousness" and right = "consciousness" - or - wrong = "condamned" and right = "condemned" - or - wrong = "condemmed" and right = "condemned" - or - wrong = "condidtion" and right = "condition" - or - wrong = "condidtions" and right = "conditions" - or - wrong = "conected" and right = "connected" - or - wrong = "conection" and right = "connection" - or - wrong = "conesencus" and right = "consensus" - or - wrong = "confidental" and right = "confidential" - or - wrong = "confidentally" and right = "confidentially" - or - wrong = "confids" and right = "confides" - or - wrong = "configureable" and right = "configurable" - or - wrong = "confortable" and right = "comfortable" - or - wrong = "congradulations" and right = "congratulations" - or - wrong = "congresional" and right = "congressional" - or - wrong = "conived" and right = "connived" - or - wrong = "conjecutre" and right = "conjecture" - or - wrong = "conjuction" and right = "conjunction" - or - wrong = "connectinos" and right = "connections" - or - wrong = "conneticut" and right = "connecticut" - or - wrong = "conotations" and right = "connotations" - or - wrong = "conquerd" and right = "conquered" - or - wrong = "conquerer" and right = "conqueror" - or - wrong = "conquerers" and right = "conquerors" - or - wrong = "conqured" and right = "conquered" - or - wrong = "conscent" and right = "consent" - or - wrong = "consciouness" and right = "consciousness" - or - wrong = "consdider" and right = "consider" - or - wrong = "consdidered" and right = "considered" - or - wrong = "consdiered" and right = "considered" - or - wrong = "consectutive" and right = "consecutive" - or - wrong = "consenquently" and right = "consequently" - or - wrong = "consentrate" and right = "concentrate" - or - wrong = "consentrated" and right = "concentrated" - or - wrong = "consentrates" and right = "concentrates" - or - wrong = "consept" and right = "concept" - or - wrong = "consequentually" and right = "consequently" - or - wrong = "consequeseces" and right = "consequences" - or - wrong = "consern" and right = "concern" - or - wrong = "conserned" and right = "concerned" - or - wrong = "conserning" and right = "concerning" - or - wrong = "conservitive" and right = "conservative" - or - wrong = "consiciousness" and right = "consciousness" - or - wrong = "consicousness" and right = "consciousness" - or - wrong = "considerd" and right = "considered" - or - wrong = "consideres" and right = "considered" - or - wrong = "consious" and right = "conscious" - or - wrong = "consistant" and right = "consistent" - or - wrong = "consistantly" and right = "consistently" - or - wrong = "consituencies" and right = "constituencies" - or - wrong = "consituency" and right = "constituency" - or - wrong = "consituted" and right = "constituted" - or - wrong = "consitution" and right = "constitution" - or - wrong = "consitutional" and right = "constitutional" - or - wrong = "consolodate" and right = "consolidate" - or - wrong = "consolodated" and right = "consolidated" - or - wrong = "consonent" and right = "consonant" - or - wrong = "consonents" and right = "consonants" - or - wrong = "consorcium" and right = "consortium" - or - wrong = "conspiracys" and right = "conspiracies" - or - wrong = "conspiriator" and right = "conspirator" - or - wrong = "consructor" and right = "constructor" - or - wrong = "constaints" and right = "constraints" - or - wrong = "constanly" and right = "constantly" - or - wrong = "constarnation" and right = "consternation" - or - wrong = "constatn" and right = "constant" - or - wrong = "constinually" and right = "continually" - or - wrong = "constituant" and right = "constituent" - or - wrong = "constituants" and right = "constituents" - or - wrong = "constituion" and right = "constitution" - or - wrong = "constituional" and right = "constitutional" - or - wrong = "consttruction" and right = "construction" - or - wrong = "constuction" and right = "construction" - or - wrong = "consulant" and right = "consultant" - or - wrong = "consumate" and right = "consummate" - or - wrong = "consumated" and right = "consummated" - or - wrong = "contaiminate" and right = "contaminate" - or - wrong = "containes" and right = "contains" - or - wrong = "contamporaries" and right = "contemporaries" - or - wrong = "contamporary" and right = "contemporary" - or - wrong = "contempoary" and right = "contemporary" - or - wrong = "contemporaneus" and right = "contemporaneous" - or - wrong = "contempory" and right = "contemporary" - or - wrong = "contendor" and right = "contender" - or - wrong = "contian" and right = "contain" - or - wrong = "contians" and right = "contains" - or - wrong = "contibute" and right = "contribute" - or - wrong = "contibuted" and right = "contributed" - or - wrong = "contibutes" and right = "contributes" - or - wrong = "contigent" and right = "contingent" - or - wrong = "contined" and right = "continued" - or - wrong = "continential" and right = "continental" - or - wrong = "continous" and right = "continuous" - or - wrong = "continously" and right = "continuously" - or - wrong = "continueing" and right = "continuing" - or - wrong = "contravercial" and right = "controversial" - or - wrong = "contraversy" and right = "controversy" - or - wrong = "contributer" and right = "contributor" - or - wrong = "contributers" and right = "contributors" - or - wrong = "contritutions" and right = "contributions" - or - wrong = "controled" and right = "controlled" - or - wrong = "controling" and right = "controlling" - or - wrong = "controll" and right = "control" - or - wrong = "controlls" and right = "controls" - or - wrong = "controvercial" and right = "controversial" - or - wrong = "controvercy" and right = "controversy" - or - wrong = "controveries" and right = "controversies" - or - wrong = "controversal" and right = "controversial" - or - wrong = "controversey" and right = "controversy" - or - wrong = "controvertial" and right = "controversial" - or - wrong = "controvery" and right = "controversy" - or - wrong = "contruction" and right = "construction" - or - wrong = "contructor" and right = "constructor" - or - wrong = "contstruction" and right = "construction" - or - wrong = "conveinent" and right = "convenient" - or - wrong = "convenant" and right = "covenant" - or - wrong = "convential" and right = "conventional" - or - wrong = "convertables" and right = "convertibles" - or - wrong = "convertion" and right = "conversion" - or - wrong = "conviced" and right = "convinced" - or - wrong = "convienient" and right = "convenient" - or - wrong = "coordiantion" and right = "coordination" - or - wrong = "coorperation" and right = "cooperation" - or - wrong = "coorperation" and right = "corporation" - or - wrong = "coorperations" and right = "corporations" - or - wrong = "copmetitors" and right = "competitors" - or - wrong = "coputer" and right = "computer" - or - wrong = "copywrite" and right = "copyright" - or - wrong = "coridal" and right = "cordial" - or - wrong = "cornmitted" and right = "committed" - or - wrong = "corosion" and right = "corrosion" - or - wrong = "corparate" and right = "corporate" - or - wrong = "corperations" and right = "corporations" - or - wrong = "correcters" and right = "correctors" - or - wrong = "correponding" and right = "corresponding" - or - wrong = "correposding" and right = "corresponding" - or - wrong = "correspondant" and right = "correspondent" - or - wrong = "correspondants" and right = "correspondents" - or - wrong = "corridoors" and right = "corridors" - or - wrong = "corrispond" and right = "correspond" - or - wrong = "corrispondant" and right = "correspondent" - or - wrong = "corrispondants" and right = "correspondents" - or - wrong = "corrisponded" and right = "corresponded" - or - wrong = "corrisponding" and right = "corresponding" - or - wrong = "corrisponds" and right = "corresponds" - or - wrong = "costitution" and right = "constitution" - or - wrong = "coucil" and right = "council" - or - wrong = "coudl" and right = "cloud" - or - wrong = "coudl" and right = "could" - or - wrong = "councellor" and right = "councillor" - or - wrong = "councellor" and right = "councilor" - or - wrong = "councellor" and right = "counselor" - or - wrong = "councellors" and right = "councillors" - or - wrong = "councellors" and right = "councilors" - or - wrong = "councellors" and right = "counselors" - or - wrong = "counries" and right = "countries" - or - wrong = "countains" and right = "contains" - or - wrong = "countires" and right = "countries" - or - wrong = "coururier" and right = "courier" - or - wrong = "coururier" and right = "couturier" - or - wrong = "coverted" and right = "converted" - or - wrong = "coverted" and right = "covered" - or - wrong = "coverted" and right = "coveted" - or - wrong = "cpoy" and right = "copy" - or - wrong = "cpoy" and right = "coy" - or - wrong = "creaeted" and right = "created" - or - wrong = "creedence" and right = "credence" - or - wrong = "critereon" and right = "criterion" - or - wrong = "criterias" and right = "criteria" - or - wrong = "criticists" and right = "critics" - or - wrong = "critising" and right = "criticising" - or - wrong = "critising" and right = "criticizing" - or - wrong = "critisising" and right = "criticising" - or - wrong = "critisism" and right = "criticism" - or - wrong = "critisisms" and right = "criticisms" - or - wrong = "critisize" and right = "criticise" - or - wrong = "critisize" and right = "criticize" - or - wrong = "critisized" and right = "criticised" - or - wrong = "critisized" and right = "criticized" - or - wrong = "critisizes" and right = "criticises" - or - wrong = "critisizes" and right = "criticizes" - or - wrong = "critisizing" and right = "criticising" - or - wrong = "critisizing" and right = "criticizing" - or - wrong = "critized" and right = "criticized" - or - wrong = "critizing" and right = "criticizing" - or - wrong = "crockodiles" and right = "crocodiles" - or - wrong = "crowm" and right = "crown" - or - wrong = "crtical" and right = "critical" - or - wrong = "crticised" and right = "criticised" - or - wrong = "crucifiction" and right = "crucifixion" - or - wrong = "crusies" and right = "cruises" - or - wrong = "crutial" and right = "crucial" - or - wrong = "crystalisation" and right = "crystallisation" - or - wrong = "culiminating" and right = "culminating" - or - wrong = "cumulatative" and right = "cumulative" - or - wrong = "curch" and right = "church" - or - wrong = "curcuit" and right = "circuit" - or - wrong = "currenly" and right = "currently" - or - wrong = "curriculem" and right = "curriculum" - or - wrong = "cxan" and right = "cyan" - or - wrong = "cyclinder" and right = "cylinder" - or - wrong = "dacquiri" and right = "daiquiri" - or - wrong = "daed" and right = "dead" - or - wrong = "dael" and right = "dahl" - or - wrong = "dael" and right = "deal" - or - wrong = "dael" and right = "dial" - or - wrong = "dalmation" and right = "dalmatian" - or - wrong = "damenor" and right = "demeanor" - or - wrong = "dammage" and right = "damage" - or - wrong = "dardenelles" and right = "dardanelles" - or - wrong = "daugher" and right = "daughter" - or - wrong = "deafult" and right = "default" - or - wrong = "debateable" and right = "debatable" - or - wrong = "decendant" and right = "descendant" - or - wrong = "decendants" and right = "descendants" - or - wrong = "decendent" and right = "descendant" - or - wrong = "decendents" and right = "descendants" - or - wrong = "decideable" and right = "decidable" - or - wrong = "decidely" and right = "decidedly" - or - wrong = "decieved" and right = "deceived" - or - wrong = "decison" and right = "decision" - or - wrong = "decomissioned" and right = "decommissioned" - or - wrong = "decomposit" and right = "decompose" - or - wrong = "decomposited" and right = "decomposed" - or - wrong = "decompositing" and right = "decomposing" - or - wrong = "decomposits" and right = "decomposes" - or - wrong = "decress" and right = "decrees" - or - wrong = "decribe" and right = "describe" - or - wrong = "decribed" and right = "described" - or - wrong = "decribes" and right = "describes" - or - wrong = "decribing" and right = "describing" - or - wrong = "dectect" and right = "detect" - or - wrong = "defendent" and right = "defendant" - or - wrong = "defendents" and right = "defendants" - or - wrong = "deffensively" and right = "defensively" - or - wrong = "deffine" and right = "define" - or - wrong = "deffined" and right = "defined" - or - wrong = "definance" and right = "defiance" - or - wrong = "definate" and right = "definite" - or - wrong = "definately" and right = "definitely" - or - wrong = "definatly" and right = "definitely" - or - wrong = "definetly" and right = "definitely" - or - wrong = "definining" and right = "defining" - or - wrong = "definit" and right = "definite" - or - wrong = "definitly" and right = "definitely" - or - wrong = "definiton" and right = "definition" - or - wrong = "defintion" and right = "definition" - or - wrong = "defualt" and right = "default" - or - wrong = "defult" and right = "default" - or - wrong = "degrate" and right = "degrade" - or - wrong = "delagates" and right = "delegates" - or - wrong = "delapidated" and right = "dilapidated" - or - wrong = "delerious" and right = "delirious" - or - wrong = "delevopment" and right = "development" - or - wrong = "deliberatly" and right = "deliberately" - or - wrong = "delusionally" and right = "delusively" - or - wrong = "demenor" and right = "demeanor" - or - wrong = "demographical" and right = "demographic" - or - wrong = "demolision" and right = "demolition" - or - wrong = "demorcracy" and right = "democracy" - or - wrong = "demostration" and right = "demonstration" - or - wrong = "denegrating" and right = "denigrating" - or - wrong = "densly" and right = "densely" - or - wrong = "deparment" and right = "department" - or - wrong = "deparmental" and right = "departmental" - or - wrong = "deparments" and right = "departments" - or - wrong = "dependance" and right = "dependence" - or - wrong = "dependancy" and right = "dependency" - or - wrong = "deram" and right = "dram" - or - wrong = "deram" and right = "dream" - or - wrong = "deriviated" and right = "derived" - or - wrong = "derivitive" and right = "derivative" - or - wrong = "derogitory" and right = "derogatory" - or - wrong = "descendands" and right = "descendants" - or - wrong = "descibed" and right = "described" - or - wrong = "desciptors" and right = "descriptors" - or - wrong = "descision" and right = "decision" - or - wrong = "descisions" and right = "decisions" - or - wrong = "descriibes" and right = "describes" - or - wrong = "descripters" and right = "descriptors" - or - wrong = "descripton" and right = "description" - or - wrong = "desctruction" and right = "destruction" - or - wrong = "descuss" and right = "discuss" - or - wrong = "desgined" and right = "designed" - or - wrong = "deside" and right = "decide" - or - wrong = "desigining" and right = "designing" - or - wrong = "desinations" and right = "destinations" - or - wrong = "desintegrated" and right = "disintegrated" - or - wrong = "desintegration" and right = "disintegration" - or - wrong = "desireable" and right = "desirable" - or - wrong = "desitned" and right = "destined" - or - wrong = "desktiop" and right = "desktop" - or - wrong = "desorder" and right = "disorder" - or - wrong = "desoriented" and right = "disoriented" - or - wrong = "desparate" and right = "desperate" - or - wrong = "desparate" and right = "disparate" - or - wrong = "despict" and right = "depict" - or - wrong = "despiration" and right = "desperation" - or - wrong = "dessicated" and right = "desiccated" - or - wrong = "dessigned" and right = "designed" - or - wrong = "destablized" and right = "destabilized" - or - wrong = "destory" and right = "destroy" - or - wrong = "desugered" and right = "desugared" - or - wrong = "detailled" and right = "detailed" - or - wrong = "detatched" and right = "detached" - or - wrong = "deteoriated" and right = "deteriorated" - or - wrong = "deteriate" and right = "deteriorate" - or - wrong = "deterioriating" and right = "deteriorating" - or - wrong = "determinining" and right = "determining" - or - wrong = "detremental" and right = "detrimental" - or - wrong = "devasted" and right = "devastated" - or - wrong = "develope" and right = "develop" - or - wrong = "developement" and right = "development" - or - wrong = "developped" and right = "developed" - or - wrong = "develpment" and right = "development" - or - wrong = "devels" and right = "delves" - or - wrong = "devestated" and right = "devastated" - or - wrong = "devestating" and right = "devastating" - or - wrong = "devide" and right = "divide" - or - wrong = "devided" and right = "divided" - or - wrong = "devistating" and right = "devastating" - or - wrong = "devolopement" and right = "development" - or - wrong = "diablical" and right = "diabolical" - or - wrong = "diamons" and right = "diamonds" - or - wrong = "diaster" and right = "disaster" - or - wrong = "dichtomy" and right = "dichotomy" - or - wrong = "diconnects" and right = "disconnects" - or - wrong = "dicover" and right = "discover" - or - wrong = "dicovered" and right = "discovered" - or - wrong = "dicovering" and right = "discovering" - or - wrong = "dicovers" and right = "discovers" - or - wrong = "dicovery" and right = "discovery" - or - wrong = "dictionarys" and right = "dictionaries" - or - wrong = "dicussed" and right = "discussed" - or - wrong = "diea" and right = "die" - or - wrong = "diea" and right = "idea" - or - wrong = "dieing" and right = "dyeing" - or - wrong = "dieing" and right = "dying" - or - wrong = "dieties" and right = "deities" - or - wrong = "diety" and right = "deity" - or - wrong = "diferent" and right = "different" - or - wrong = "diferrent" and right = "different" - or - wrong = "differentiatiations" and right = "differentiations" - or - wrong = "differnt" and right = "different" - or - wrong = "difficulity" and right = "difficulty" - or - wrong = "diffrent" and right = "different" - or - wrong = "dificulties" and right = "difficulties" - or - wrong = "dificulty" and right = "difficulty" - or - wrong = "dimenions" and right = "dimensions" - or - wrong = "dimention" and right = "dimension" - or - wrong = "dimentional" and right = "dimensional" - or - wrong = "dimentions" and right = "dimensions" - or - wrong = "dimesnional" and right = "dimensional" - or - wrong = "diminuitive" and right = "diminutive" - or - wrong = "dimunitive" and right = "diminutive" - or - wrong = "diosese" and right = "diocese" - or - wrong = "diphtong" and right = "diphthong" - or - wrong = "diphtongs" and right = "diphthongs" - or - wrong = "diplomancy" and right = "diplomacy" - or - wrong = "dipthong" and right = "diphthong" - or - wrong = "dipthongs" and right = "diphthongs" - or - wrong = "directoty" and right = "directory" - or - wrong = "dirived" and right = "derived" - or - wrong = "disagreeed" and right = "disagreed" - or - wrong = "disapeared" and right = "disappeared" - or - wrong = "disapointing" and right = "disappointing" - or - wrong = "disappearred" and right = "disappeared" - or - wrong = "disaproval" and right = "disapproval" - or - wrong = "disasterous" and right = "disastrous" - or - wrong = "disatisfaction" and right = "dissatisfaction" - or - wrong = "disatisfied" and right = "dissatisfied" - or - wrong = "disatrous" and right = "disastrous" - or - wrong = "discontentment" and right = "discontent" - or - wrong = "discribe" and right = "describe" - or - wrong = "discribed" and right = "described" - or - wrong = "discribes" and right = "describes" - or - wrong = "discribing" and right = "describing" - or - wrong = "disctinction" and right = "distinction" - or - wrong = "disctinctive" and right = "distinctive" - or - wrong = "disemination" and right = "dissemination" - or - wrong = "disenchanged" and right = "disenchanted" - or - wrong = "disiplined" and right = "disciplined" - or - wrong = "disobediance" and right = "disobedience" - or - wrong = "disobediant" and right = "disobedient" - or - wrong = "disolved" and right = "dissolved" - or - wrong = "disover" and right = "discover" - or - wrong = "dispair" and right = "despair" - or - wrong = "disparingly" and right = "disparagingly" - or - wrong = "dispence" and right = "dispense" - or - wrong = "dispenced" and right = "dispensed" - or - wrong = "dispencing" and right = "dispensing" - or - wrong = "dispicable" and right = "despicable" - or - wrong = "dispite" and right = "despite" - or - wrong = "dispostion" and right = "disposition" - or - wrong = "disproportiate" and right = "disproportionate" - or - wrong = "disputandem" and right = "disputandum" - or - wrong = "disricts" and right = "districts" - or - wrong = "dissagreement" and right = "disagreement" - or - wrong = "dissapear" and right = "disappear" - or - wrong = "dissapearance" and right = "disappearance" - or - wrong = "dissapeared" and right = "disappeared" - or - wrong = "dissapearing" and right = "disappearing" - or - wrong = "dissapears" and right = "disappears" - or - wrong = "dissappear" and right = "disappear" - or - wrong = "dissappears" and right = "disappears" - or - wrong = "dissappointed" and right = "disappointed" - or - wrong = "dissarray" and right = "disarray" - or - wrong = "dissobediance" and right = "disobedience" - or - wrong = "dissobediant" and right = "disobedient" - or - wrong = "dissobedience" and right = "disobedience" - or - wrong = "dissobedient" and right = "disobedient" - or - wrong = "distiction" and right = "distinction" - or - wrong = "distingish" and right = "distinguish" - or - wrong = "distingished" and right = "distinguished" - or - wrong = "distingishes" and right = "distinguishes" - or - wrong = "distingishing" and right = "distinguishing" - or - wrong = "distingquished" and right = "distinguished" - or - wrong = "distrubution" and right = "distribution" - or - wrong = "distruction" and right = "destruction" - or - wrong = "distructive" and right = "destructive" - or - wrong = "ditributed" and right = "distributed" - or - wrong = "diversed" and right = "diverged" - or - wrong = "diversed" and right = "diverse" - or - wrong = "divice" and right = "device" - or - wrong = "divinition" and right = "divination" - or - wrong = "divison" and right = "division" - or - wrong = "divisons" and right = "divisions" - or - wrong = "doccument" and right = "document" - or - wrong = "doccumented" and right = "documented" - or - wrong = "doccuments" and right = "documents" - or - wrong = "docrines" and right = "doctrines" - or - wrong = "doctines" and right = "doctrines" - or - wrong = "documenatry" and right = "documentary" - or - wrong = "doens" and right = "does" - or - wrong = "doign" and right = "doing" - or - wrong = "dominaton" and right = "domination" - or - wrong = "dominent" and right = "dominant" - or - wrong = "dominiant" and right = "dominant" - or - wrong = "donig" and right = "doing" - or - wrong = "doub" and right = "daub" - or - wrong = "doub" and right = "doubt" - or - wrong = "doulbe" and right = "double" - or - wrong = "dowloads" and right = "downloads" - or - wrong = "dramtic" and right = "dramatic" - or - wrong = "draughtman" and right = "draughtsman" - or - wrong = "dravadian" and right = "dravidian" - or - wrong = "dreasm" and right = "dreams" - or - wrong = "driectly" and right = "directly" - or - wrong = "drnik" and right = "drink" - or - wrong = "druming" and right = "drumming" - or - wrong = "drummless" and right = "drumless" - or - wrong = "dum" and right = "dumb" - or - wrong = "dupicate" and right = "duplicate" - or - wrong = "durig" and right = "during" - or - wrong = "durring" and right = "during" - or - wrong = "duting" and right = "during" - or - wrong = "dyas" and right = "dryas" - or - wrong = "eahc" and right = "each" - or - wrong = "ealier" and right = "earlier" - or - wrong = "earlies" and right = "earliest" - or - wrong = "earnt" and right = "earned" - or - wrong = "ecclectic" and right = "eclectic" - or - wrong = "eceonomy" and right = "economy" - or - wrong = "ecidious" and right = "deciduous" - or - wrong = "eclispe" and right = "eclipse" - or - wrong = "ecomonic" and right = "economic" - or - wrong = "ect" and right = "etc" - or - wrong = "editting" and right = "editing" - or - wrong = "eearly" and right = "early" - or - wrong = "efel" and right = "evil" - or - wrong = "effeciency" and right = "efficiency" - or - wrong = "effecient" and right = "efficient" - or - wrong = "effeciently" and right = "efficiently" - or - wrong = "efficency" and right = "efficiency" - or - wrong = "efficent" and right = "efficient" - or - wrong = "efficently" and right = "efficiently" - or - wrong = "efford" and right = "afford" - or - wrong = "efford" and right = "effort" - or - wrong = "effords" and right = "affords" - or - wrong = "effords" and right = "efforts" - or - wrong = "effulence" and right = "effluence" - or - wrong = "eigth" and right = "eight" - or - wrong = "eigth" and right = "eighth" - or - wrong = "eiter" and right = "either" - or - wrong = "elction" and right = "election" - or - wrong = "electic" and right = "eclectic" - or - wrong = "electic" and right = "electric" - or - wrong = "electon" and right = "election" - or - wrong = "electon" and right = "electron" - or - wrong = "electrial" and right = "electrical" - or - wrong = "electricly" and right = "electrically" - or - wrong = "electricty" and right = "electricity" - or - wrong = "elementay" and right = "elementary" - or - wrong = "eleminated" and right = "eliminated" - or - wrong = "eleminating" and right = "eliminating" - or - wrong = "eles" and right = "eels" - or - wrong = "eletricity" and right = "electricity" - or - wrong = "elicided" and right = "elicited" - or - wrong = "eligable" and right = "eligible" - or - wrong = "elimentary" and right = "elementary" - or - wrong = "ellected" and right = "elected" - or - wrong = "elphant" and right = "elephant" - or - wrong = "embarass" and right = "embarrass" - or - wrong = "embarassed" and right = "embarrassed" - or - wrong = "embarassing" and right = "embarrassing" - or - wrong = "embarassment" and right = "embarrassment" - or - wrong = "embargos" and right = "embargoes" - or - wrong = "embarras" and right = "embarrass" - or - wrong = "embarrased" and right = "embarrassed" - or - wrong = "embarrasing" and right = "embarrassing" - or - wrong = "embarrasment" and right = "embarrassment" - or - wrong = "embezelled" and right = "embezzled" - or - wrong = "emblamatic" and right = "emblematic" - or - wrong = "eminate" and right = "emanate" - or - wrong = "eminated" and right = "emanated" - or - wrong = "emision" and right = "emission" - or - wrong = "emited" and right = "emitted" - or - wrong = "emiting" and right = "emitting" - or - wrong = "emition" and right = "emission" - or - wrong = "emition" and right = "emotion" - or - wrong = "emmediately" and right = "immediately" - or - wrong = "emmigrated" and right = "emigrated" - or - wrong = "emmigrated" and right = "immigrated" - or - wrong = "emminent" and right = "eminent" - or - wrong = "emminent" and right = "imminent" - or - wrong = "emminently" and right = "eminently" - or - wrong = "emmisaries" and right = "emissaries" - or - wrong = "emmisarries" and right = "emissaries" - or - wrong = "emmisarry" and right = "emissary" - or - wrong = "emmisary" and right = "emissary" - or - wrong = "emmision" and right = "emission" - or - wrong = "emmisions" and right = "emissions" - or - wrong = "emmited" and right = "emitted" - or - wrong = "emmiting" and right = "emitting" - or - wrong = "emmitted" and right = "emitted" - or - wrong = "emmitting" and right = "emitting" - or - wrong = "emnity" and right = "enmity" - or - wrong = "emperical" and right = "empirical" - or - wrong = "emphaised" and right = "emphasised" - or - wrong = "emphsis" and right = "emphasis" - or - wrong = "emphysyma" and right = "emphysema" - or - wrong = "empirial" and right = "empirical" - or - wrong = "empirial" and right = "imperial" - or - wrong = "emporer" and right = "emperor" - or - wrong = "emprisoned" and right = "imprisoned" - or - wrong = "enameld" and right = "enameled" - or - wrong = "enchancement" and right = "enhancement" - or - wrong = "encouraing" and right = "encouraging" - or - wrong = "encryptiion" and right = "encryption" - or - wrong = "encylopedia" and right = "encyclopedia" - or - wrong = "endevors" and right = "endeavors" - or - wrong = "endevour" and right = "endeavour" - or - wrong = "endig" and right = "ending" - or - wrong = "endolithes" and right = "endoliths" - or - wrong = "enduce" and right = "induce" - or - wrong = "ened" and right = "need" - or - wrong = "enforceing" and right = "enforcing" - or - wrong = "engagment" and right = "engagement" - or - wrong = "engeneer" and right = "engineer" - or - wrong = "engeneering" and right = "engineering" - or - wrong = "engieneer" and right = "engineer" - or - wrong = "engieneers" and right = "engineers" - or - wrong = "enlargment" and right = "enlargement" - or - wrong = "enlargments" and right = "enlargements" - or - wrong = "enlish" and right = "english" - or - wrong = "enlish" and right = "enlist" - or - wrong = "enourmous" and right = "enormous" - or - wrong = "enourmously" and right = "enormously" - or - wrong = "ensconsed" and right = "ensconced" - or - wrong = "entaglements" and right = "entanglements" - or - wrong = "enteratinment" and right = "entertainment" - or - wrong = "enthusiatic" and right = "enthusiastic" - or - wrong = "entitity" and right = "entity" - or - wrong = "entitlied" and right = "entitled" - or - wrong = "entrepeneur" and right = "entrepreneur" - or - wrong = "entrepeneurs" and right = "entrepreneurs" - or - wrong = "enviorment" and right = "environment" - or - wrong = "enviormental" and right = "environmental" - or - wrong = "enviormentally" and right = "environmentally" - or - wrong = "enviorments" and right = "environments" - or - wrong = "enviornment" and right = "environment" - or - wrong = "enviornmental" and right = "environmental" - or - wrong = "enviornmentalist" and right = "environmentalist" - or - wrong = "enviornmentally" and right = "environmentally" - or - wrong = "enviornments" and right = "environments" - or - wrong = "enviroment" and right = "environment" - or - wrong = "enviromental" and right = "environmental" - or - wrong = "enviromentalist" and right = "environmentalist" - or - wrong = "enviromentally" and right = "environmentally" - or - wrong = "enviroments" and right = "environments" - or - wrong = "environemnt" and right = "environment" - or - wrong = "envolutionary" and right = "evolutionary" - or - wrong = "envrionments" and right = "environments" - or - wrong = "enxt" and right = "next" - or - wrong = "epidsodes" and right = "episodes" - or - wrong = "epsiode" and right = "episode" - or - wrong = "equialent" and right = "equivalent" - or - wrong = "equilibium" and right = "equilibrium" - or - wrong = "equilibrum" and right = "equilibrium" - or - wrong = "equiped" and right = "equipped" - or - wrong = "equippment" and right = "equipment" - or - wrong = "equitorial" and right = "equatorial" - or - wrong = "equivelant" and right = "equivalent" - or - wrong = "equivelent" and right = "equivalent" - or - wrong = "equivilant" and right = "equivalent" - or - wrong = "equivilent" and right = "equivalent" - or - wrong = "equivlalent" and right = "equivalent" - or - wrong = "erally" and right = "orally" - or - wrong = "erally" and right = "really" - or - wrong = "eratic" and right = "erratic" - or - wrong = "eratically" and right = "erratically" - or - wrong = "eraticly" and right = "erratically" - or - wrong = "erested" and right = "arrested" - or - wrong = "erested" and right = "erected" - or - wrong = "errupted" and right = "erupted" - or - wrong = "esential" and right = "essential" - or - wrong = "esitmated" and right = "estimated" - or - wrong = "esle" and right = "else" - or - wrong = "especialy" and right = "especially" - or - wrong = "essencial" and right = "essential" - or - wrong = "essense" and right = "essence" - or - wrong = "essentail" and right = "essential" - or - wrong = "essentialy" and right = "essentially" - or - wrong = "essentual" and right = "essential" - or - wrong = "essesital" and right = "essential" - or - wrong = "estabishes" and right = "establishes" - or - wrong = "establising" and right = "establishing" - or - wrong = "ethnocentricm" and right = "ethnocentrism" - or - wrong = "ethose" and right = "ethos" - or - wrong = "ethose" and right = "those" - or - wrong = "europian" and right = "european" - or - wrong = "europians" and right = "europeans" - or - wrong = "eurpean" and right = "european" - or - wrong = "eurpoean" and right = "european" - or - wrong = "evenhtually" and right = "eventually" - or - wrong = "eventally" and right = "eventually" - or - wrong = "eventially" and right = "eventually" - or - wrong = "eventualy" and right = "eventually" - or - wrong = "everthing" and right = "everything" - or - wrong = "everyting" and right = "everything" - or - wrong = "eveyr" and right = "every" - or - wrong = "evidentally" and right = "evidently" - or - wrong = "exagerate" and right = "exaggerate" - or - wrong = "exagerated" and right = "exaggerated" - or - wrong = "exagerates" and right = "exaggerates" - or - wrong = "exagerating" and right = "exaggerating" - or - wrong = "exagerrate" and right = "exaggerate" - or - wrong = "exagerrated" and right = "exaggerated" - or - wrong = "exagerrates" and right = "exaggerates" - or - wrong = "exagerrating" and right = "exaggerating" - or - wrong = "examinated" and right = "examined" - or - wrong = "exampt" and right = "exempt" - or - wrong = "exapansion" and right = "expansion" - or - wrong = "excact" and right = "exact" - or - wrong = "excange" and right = "exchange" - or - wrong = "excecute" and right = "execute" - or - wrong = "excecuted" and right = "executed" - or - wrong = "excecutes" and right = "executes" - or - wrong = "excecuting" and right = "executing" - or - wrong = "excecution" and right = "execution" - or - wrong = "excedded" and right = "exceeded" - or - wrong = "excelent" and right = "excellent" - or - wrong = "excell" and right = "excel" - or - wrong = "excellance" and right = "excellence" - or - wrong = "excellant" and right = "excellent" - or - wrong = "excells" and right = "excels" - or - wrong = "excercise" and right = "exercise" - or - wrong = "exchanching" and right = "exchanging" - or - wrong = "excisted" and right = "existed" - or - wrong = "exculsivly" and right = "exclusively" - or - wrong = "execising" and right = "exercising" - or - wrong = "exection" and right = "execution" - or - wrong = "exectued" and right = "executed" - or - wrong = "exeedingly" and right = "exceedingly" - or - wrong = "exelent" and right = "excellent" - or - wrong = "exellent" and right = "excellent" - or - wrong = "exemple" and right = "example" - or - wrong = "exept" and right = "except" - or - wrong = "exeptional" and right = "exceptional" - or - wrong = "exerbate" and right = "exacerbate" - or - wrong = "exerbated" and right = "exacerbated" - or - wrong = "exerciese" and right = "exercises" - or - wrong = "exerpt" and right = "excerpt" - or - wrong = "exerpts" and right = "excerpts" - or - wrong = "exersize" and right = "exercise" - or - wrong = "exerternal" and right = "external" - or - wrong = "exhalted" and right = "exalted" - or - wrong = "exhibtion" and right = "exhibition" - or - wrong = "exibition" and right = "exhibition" - or - wrong = "exibitions" and right = "exhibitions" - or - wrong = "exicting" and right = "exciting" - or - wrong = "exinct" and right = "extinct" - or - wrong = "existance" and right = "existence" - or - wrong = "existant" and right = "existent" - or - wrong = "existince" and right = "existence" - or - wrong = "exliled" and right = "exiled" - or - wrong = "exludes" and right = "excludes" - or - wrong = "exmaple" and right = "example" - or - wrong = "exonorate" and right = "exonerate" - or - wrong = "exoskelaton" and right = "exoskeleton" - or - wrong = "expalin" and right = "explain" - or - wrong = "expatriot" and right = "expatriate" - or - wrong = "expeced" and right = "expected" - or - wrong = "expecially" and right = "especially" - or - wrong = "expeditonary" and right = "expeditionary" - or - wrong = "expeiments" and right = "experiments" - or - wrong = "expell" and right = "expel" - or - wrong = "expells" and right = "expels" - or - wrong = "experiance" and right = "experience" - or - wrong = "experianced" and right = "experienced" - or - wrong = "expession" and right = "expression" - or - wrong = "expessions" and right = "expressions" - or - wrong = "expiditions" and right = "expeditions" - or - wrong = "expierence" and right = "experience" - or - wrong = "explaination" and right = "explanation" - or - wrong = "explaning" and right = "explaining" - or - wrong = "explictly" and right = "explicitly" - or - wrong = "exploititive" and right = "exploitative" - or - wrong = "explotation" and right = "exploitation" - or - wrong = "expropiated" and right = "expropriated" - or - wrong = "expropiation" and right = "expropriation" - or - wrong = "exressed" and right = "expressed" - or - wrong = "extemely" and right = "extremely" - or - wrong = "extened" and right = "extended" - or - wrong = "extention" and right = "extension" - or - wrong = "extentions" and right = "extensions" - or - wrong = "extered" and right = "exerted" - or - wrong = "extermist" and right = "extremist" - or - wrong = "extint" and right = "extant" - or - wrong = "extint" and right = "extinct" - or - wrong = "extracter" and right = "extractor" - or - wrong = "extradiction" and right = "extradition" - or - wrong = "extraterrestial" and right = "extraterrestrial" - or - wrong = "extraterrestials" and right = "extraterrestrials" - or - wrong = "extravagent" and right = "extravagant" - or - wrong = "extrememly" and right = "extremely" - or - wrong = "extremeophile" and right = "extremophile" - or - wrong = "extremly" and right = "extremely" - or - wrong = "extrordinarily" and right = "extraordinarily" - or - wrong = "extrordinary" and right = "extraordinary" - or - wrong = "eyar" and right = "eyas" - or - wrong = "eyar" and right = "year" - or - wrong = "eyars" and right = "eyas" - or - wrong = "eyars" and right = "years" - or - wrong = "eyasr" and right = "eyas" - or - wrong = "eyasr" and right = "years" - or - wrong = "faciliate" and right = "facilitate" - or - wrong = "faciliated" and right = "facilitated" - or - wrong = "faciliates" and right = "facilitates" - or - wrong = "facilites" and right = "facilities" - or - wrong = "facillitate" and right = "facilitate" - or - wrong = "facinated" and right = "fascinated" - or - wrong = "facist" and right = "fascist" - or - wrong = "familes" and right = "families" - or - wrong = "familliar" and right = "familiar" - or - wrong = "famoust" and right = "famous" - or - wrong = "fanatism" and right = "fanaticism" - or - wrong = "farenheit" and right = "fahrenheit" - or - wrong = "fatc" and right = "fact" - or - wrong = "faught" and right = "fought" - or - wrong = "favoutrable" and right = "favourable" - or - wrong = "feasable" and right = "feasible" - or - wrong = "febuary" and right = "february" - or - wrong = "feburary" and right = "february" - or - wrong = "fedreally" and right = "federally" - or - wrong = "femminist" and right = "feminist" - or - wrong = "feromone" and right = "pheromone" - or - wrong = "fertily" and right = "fertility" - or - wrong = "fianite" and right = "finite" - or - wrong = "fianlly" and right = "finally" - or - wrong = "ficticious" and right = "fictitious" - or - wrong = "fictious" and right = "fictitious" - or - wrong = "fidn" and right = "find" - or - wrong = "fiel" and right = "feel" - or - wrong = "fiel" and right = "field" - or - wrong = "fiel" and right = "file" - or - wrong = "fiel" and right = "phial" - or - wrong = "fiels" and right = "feels" - or - wrong = "fiels" and right = "fields" - or - wrong = "fiels" and right = "files" - or - wrong = "fiels" and right = "phials" - or - wrong = "fiercly" and right = "fiercely" - or - wrong = "fightings" and right = "fighting" - or - wrong = "filiament" and right = "filament" - or - wrong = "fimilies" and right = "families" - or - wrong = "finacial" and right = "financial" - or - wrong = "finaly" and right = "finally" - or - wrong = "financialy" and right = "financially" - or - wrong = "firends" and right = "friends" - or - wrong = "firts" and right = "first" - or - wrong = "firts" and right = "flirts" - or - wrong = "fisionable" and right = "fissionable" - or - wrong = "flamable" and right = "flammable" - or - wrong = "flawess" and right = "flawless" - or - wrong = "fleed" and right = "fled" - or - wrong = "fleed" and right = "freed" - or - wrong = "flemmish" and right = "flemish" - or - wrong = "florescent" and right = "fluorescent" - or - wrong = "flourescent" and right = "fluorescent" - or - wrong = "flourine" and right = "fluorine" - or - wrong = "flourishment" and right = "flourishing" - or - wrong = "fluorish" and right = "flourish" - or - wrong = "follwoing" and right = "following" - or - wrong = "folowing" and right = "following" - or - wrong = "fomed" and right = "formed" - or - wrong = "fomr" and right = "form" - or - wrong = "fomr" and right = "from" - or - wrong = "fonetic" and right = "phonetic" - or - wrong = "fontrier" and right = "fontier" - or - wrong = "foootball" and right = "football" - or - wrong = "forbad" and right = "forbade" - or - wrong = "forbiden" and right = "forbidden" - or - wrong = "foreward" and right = "foreword" - or - wrong = "forfiet" and right = "forfeit" - or - wrong = "forhead" and right = "forehead" - or - wrong = "foriegn" and right = "foreign" - or - wrong = "formalhaut" and right = "fomalhaut" - or - wrong = "formallize" and right = "formalize" - or - wrong = "formallized" and right = "formalized" - or - wrong = "formaly" and right = "formally" - or - wrong = "formaly" and right = "formerly" - or - wrong = "formelly" and right = "formerly" - or - wrong = "formidible" and right = "formidable" - or - wrong = "formost" and right = "foremost" - or - wrong = "forsaw" and right = "foresaw" - or - wrong = "forseeable" and right = "foreseeable" - or - wrong = "fortelling" and right = "foretelling" - or - wrong = "forunner" and right = "forerunner" - or - wrong = "foucs" and right = "focus" - or - wrong = "foudn" and right = "found" - or - wrong = "fougth" and right = "fought" - or - wrong = "foundaries" and right = "foundries" - or - wrong = "foundary" and right = "foundry" - or - wrong = "foundland" and right = "newfoundland" - or - wrong = "fourties" and right = "forties" - or - wrong = "fourty" and right = "forty" - or - wrong = "fouth" and right = "fourth" - or - wrong = "foward" and right = "forward" - or - wrong = "framwork" and right = "framework" - or - wrong = "fransiscan" and right = "franciscan" - or - wrong = "fransiscans" and right = "franciscans" - or - wrong = "freind" and right = "friend" - or - wrong = "freindly" and right = "friendly" - or - wrong = "frequentily" and right = "frequently" - or - wrong = "frome" and right = "from" - or - wrong = "fromed" and right = "formed" - or - wrong = "froniter" and right = "frontier" - or - wrong = "fucntion" and right = "function" - or - wrong = "fucntioning" and right = "functioning" - or - wrong = "fufill" and right = "fulfill" - or - wrong = "fufilled" and right = "fulfilled" - or - wrong = "fulfiled" and right = "fulfilled" - or - wrong = "fullfill" and right = "fulfill" - or - wrong = "fullfilled" and right = "fulfilled" - or - wrong = "funcion" and right = "function" - or - wrong = "fundametal" and right = "fundamental" - or - wrong = "fundametals" and right = "fundamentals" - or - wrong = "funguses" and right = "fungi" - or - wrong = "funtion" and right = "function" - or - wrong = "funtions" and right = "functions" - or - wrong = "furuther" and right = "further" - or - wrong = "futher" and right = "further" - or - wrong = "futhermore" and right = "furthermore" - or - wrong = "futhroc" and right = "futhark" - or - wrong = "futhroc" and right = "futhorc" - or - wrong = "gae" and right = "gael" - or - wrong = "gae" and right = "gale" - or - wrong = "gae" and right = "game" - or - wrong = "galatic" and right = "galactic" - or - wrong = "galations" and right = "galatians" - or - wrong = "gallaxies" and right = "galaxies" - or - wrong = "galvinized" and right = "galvanized" - or - wrong = "ganerate" and right = "generate" - or - wrong = "ganes" and right = "games" - or - wrong = "ganster" and right = "gangster" - or - wrong = "garantee" and right = "guarantee" - or - wrong = "garanteed" and right = "guaranteed" - or - wrong = "garantees" and right = "guarantees" - or - wrong = "garnison" and right = "garrison" - or - wrong = "gaurantee" and right = "guarantee" - or - wrong = "gauranteed" and right = "guaranteed" - or - wrong = "gaurantees" and right = "guarantees" - or - wrong = "gaurd" and right = "gourd" - or - wrong = "gaurd" and right = "guard" - or - wrong = "gaurentee" and right = "guarantee" - or - wrong = "gaurenteed" and right = "guaranteed" - or - wrong = "gaurentees" and right = "guarantees" - or - wrong = "geneological" and right = "genealogical" - or - wrong = "geneologies" and right = "genealogies" - or - wrong = "geneology" and right = "genealogy" - or - wrong = "generaly" and right = "generally" - or - wrong = "generatting" and right = "generating" - or - wrong = "genialia" and right = "genitalia" - or - wrong = "geographicial" and right = "geographical" - or - wrong = "geometrician" and right = "geometer" - or - wrong = "geometricians" and right = "geometers" - or - wrong = "gerat" and right = "great" - or - wrong = "ghandi" and right = "gandhi" - or - wrong = "glamourous" and right = "glamorous" - or - wrong = "glight" and right = "flight" - or - wrong = "gnawwed" and right = "gnawed" - or - wrong = "godess" and right = "goddess" - or - wrong = "godesses" and right = "goddesses" - or - wrong = "godounov" and right = "godunov" - or - wrong = "gogin" and right = "gauguin" - or - wrong = "gogin" and right = "going" - or - wrong = "goign" and right = "going" - or - wrong = "gonig" and right = "going" - or - wrong = "gothenberg" and right = "gothenburg" - or - wrong = "gottleib" and right = "gottlieb" - or - wrong = "gouvener" and right = "governor" - or - wrong = "govement" and right = "government" - or - wrong = "govenment" and right = "government" - or - wrong = "govenrment" and right = "government" - or - wrong = "goverance" and right = "governance" - or - wrong = "goverment" and right = "government" - or - wrong = "govermental" and right = "governmental" - or - wrong = "governer" and right = "governor" - or - wrong = "governmnet" and right = "government" - or - wrong = "govorment" and right = "government" - or - wrong = "govormental" and right = "governmental" - or - wrong = "govornment" and right = "government" - or - wrong = "gracefull" and right = "graceful" - or - wrong = "graet" and right = "great" - or - wrong = "grafitti" and right = "graffiti" - or - wrong = "gramatically" and right = "grammatically" - or - wrong = "grammaticaly" and right = "grammatically" - or - wrong = "grammer" and right = "grammar" - or - wrong = "grat" and right = "great" - or - wrong = "gratuitious" and right = "gratuitous" - or - wrong = "greatful" and right = "grateful" - or - wrong = "greatfully" and right = "gratefully" - or - wrong = "greif" and right = "grief" - or - wrong = "gridles" and right = "griddles" - or - wrong = "gropu" and right = "group" - or - wrong = "grwo" and right = "grow" - or - wrong = "guaduloupe" and right = "guadalupe" - or - wrong = "guaduloupe" and right = "guadeloupe" - or - wrong = "guadulupe" and right = "guadalupe" - or - wrong = "guadulupe" and right = "guadeloupe" - or - wrong = "guage" and right = "gauge" - or - wrong = "guarentee" and right = "guarantee" - or - wrong = "guarenteed" and right = "guaranteed" - or - wrong = "guarentees" and right = "guarantees" - or - wrong = "guatamala" and right = "guatemala" - or - wrong = "guatamalan" and right = "guatemalan" - or - wrong = "guerrila" and right = "guerrilla" - or - wrong = "guerrilas" and right = "guerrillas" - or - wrong = "guidence" and right = "guidance" - or - wrong = "guilia" and right = "giulia" - or - wrong = "guilio" and right = "giulio" - or - wrong = "guiness" and right = "guinness" - or - wrong = "guiseppe" and right = "giuseppe" - or - wrong = "gunanine" and right = "guanine" - or - wrong = "gurantee" and right = "guarantee" - or - wrong = "guranteed" and right = "guaranteed" - or - wrong = "gurantees" and right = "guarantees" - or - wrong = "guttaral" and right = "guttural" - or - wrong = "gutteral" and right = "guttural" - or - wrong = "habaeus" and right = "habeas" - or - wrong = "habeus" and right = "habeas" - or - wrong = "habsbourg" and right = "habsburg" - or - wrong = "haemorrage" and right = "haemorrhage" - or - wrong = "haev" and right = "have" - or - wrong = "haev" and right = "heave" - or - wrong = "halarious" and right = "hilarious" - or - wrong = "hallowean" and right = "halloween" - or - wrong = "halp" and right = "help" - or - wrong = "hander" and right = "handler" - or - wrong = "hapen" and right = "happen" - or - wrong = "hapened" and right = "happened" - or - wrong = "hapening" and right = "happening" - or - wrong = "happend" and right = "happened" - or - wrong = "happended" and right = "happened" - or - wrong = "happenned" and right = "happened" - or - wrong = "harased" and right = "harassed" - or - wrong = "harases" and right = "harasses" - or - wrong = "harasment" and right = "harassment" - or - wrong = "harasments" and right = "harassments" - or - wrong = "harassement" and right = "harassment" - or - wrong = "harras" and right = "harass" - or - wrong = "harrased" and right = "harassed" - or - wrong = "harrases" and right = "harasses" - or - wrong = "harrasing" and right = "harassing" - or - wrong = "harrasment" and right = "harassment" - or - wrong = "harrasments" and right = "harassments" - or - wrong = "harrassed" and right = "harassed" - or - wrong = "harrasses" and right = "harassed" - or - wrong = "harrassing" and right = "harassing" - or - wrong = "harrassment" and right = "harassment" - or - wrong = "harrassments" and right = "harassments" - or - wrong = "hatian" and right = "haitian" - or - wrong = "haviest" and right = "heaviest" - or - wrong = "headquarer" and right = "headquarter" - or - wrong = "headquater" and right = "headquarter" - or - wrong = "headquatered" and right = "headquartered" - or - wrong = "headquaters" and right = "headquarters" - or - wrong = "healthercare" and right = "healthcare" - or - wrong = "heared" and right = "heard" - or - wrong = "heathy" and right = "healthy" - or - wrong = "heidelburg" and right = "heidelberg" - or - wrong = "heigher" and right = "higher" - or - wrong = "heirarchy" and right = "hierarchy" - or - wrong = "heiroglyphics" and right = "hieroglyphics" - or - wrong = "helment" and right = "helmet" - or - wrong = "helpfull" and right = "helpful" - or - wrong = "helpped" and right = "helped" - or - wrong = "hemmorhage" and right = "hemorrhage" - or - wrong = "herad" and right = "heard" - or - wrong = "herad" and right = "hera" - or - wrong = "heridity" and right = "heredity" - or - wrong = "heroe" and right = "hero" - or - wrong = "heros" and right = "heroes" - or - wrong = "hertiage" and right = "heritage" - or - wrong = "hertzs" and right = "hertz" - or - wrong = "hesistant" and right = "hesitant" - or - wrong = "heterogenous" and right = "heterogeneous" - or - wrong = "hieght" and right = "height" - or - wrong = "hierachical" and right = "hierarchical" - or - wrong = "hierachies" and right = "hierarchies" - or - wrong = "hierachy" and right = "hierarchy" - or - wrong = "hierarcical" and right = "hierarchical" - or - wrong = "hierarcy" and right = "hierarchy" - or - wrong = "hieroglph" and right = "hieroglyph" - or - wrong = "hieroglphs" and right = "hieroglyphs" - or - wrong = "higer" and right = "higher" - or - wrong = "higest" and right = "highest" - or - wrong = "higway" and right = "highway" - or - wrong = "hillarious" and right = "hilarious" - or - wrong = "himselv" and right = "himself" - or - wrong = "hinderance" and right = "hindrance" - or - wrong = "hinderence" and right = "hindrance" - or - wrong = "hindrence" and right = "hindrance" - or - wrong = "hipopotamus" and right = "hippopotamus" - or - wrong = "hismelf" and right = "himself" - or - wrong = "histocompatability" and right = "histocompatibility" - or - wrong = "historicians" and right = "historians" - or - wrong = "holf" and right = "hold" - or - wrong = "holliday" and right = "holiday" - or - wrong = "homogeneize" and right = "homogenize" - or - wrong = "homogeneized" and right = "homogenized" - or - wrong = "honory" and right = "honorary" - or - wrong = "horrifing" and right = "horrifying" - or - wrong = "hosited" and right = "hoisted" - or - wrong = "hospitible" and right = "hospitable" - or - wrong = "hounour" and right = "honour" - or - wrong = "housr" and right = "hours" - or - wrong = "housr" and right = "house" - or - wrong = "howver" and right = "however" - or - wrong = "hsitorians" and right = "historians" - or - wrong = "hstory" and right = "history" - or - wrong = "hten" and right = "hen" - or - wrong = "hten" and right = "the" - or - wrong = "hten" and right = "then" - or - wrong = "htere" and right = "here" - or - wrong = "htere" and right = "there" - or - wrong = "htey" and right = "they" - or - wrong = "htikn" and right = "think" - or - wrong = "hting" and right = "thing" - or - wrong = "htink" and right = "think" - or - wrong = "htis" and right = "this" - or - wrong = "humer" and right = "humor" - or - wrong = "humer" and right = "humour" - or - wrong = "humerous" and right = "humerus" - or - wrong = "humerous" and right = "humorous" - or - wrong = "huminoid" and right = "humanoid" - or - wrong = "humoural" and right = "humoral" - or - wrong = "humurous" and right = "humorous" - or - wrong = "husban" and right = "husband" - or - wrong = "hvae" and right = "have" - or - wrong = "hvaing" and right = "having" - or - wrong = "hvea" and right = "have" - or - wrong = "hvea" and right = "heave" - or - wrong = "hwihc" and right = "which" - or - wrong = "hwile" and right = "while" - or - wrong = "hwole" and right = "whole" - or - wrong = "hydogen" and right = "hydrogen" - or - wrong = "hydropile" and right = "hydrophile" - or - wrong = "hydropilic" and right = "hydrophilic" - or - wrong = "hydropobe" and right = "hydrophobe" - or - wrong = "hydropobic" and right = "hydrophobic" - or - wrong = "hygeine" and right = "hygiene" - or - wrong = "hyjack" and right = "hijack" - or - wrong = "hyjacking" and right = "hijacking" - or - wrong = "hypocracy" and right = "hypocrisy" - or - wrong = "hypocrasy" and right = "hypocrisy" - or - wrong = "hypocricy" and right = "hypocrisy" - or - wrong = "hypocrit" and right = "hypocrite" - or - wrong = "hypocrits" and right = "hypocrites" - or - wrong = "iconclastic" and right = "iconoclastic" - or - wrong = "idaeidae" and right = "idea" - or - wrong = "idaes" and right = "ideas" - or - wrong = "idealogies" and right = "ideologies" - or - wrong = "idealogy" and right = "ideology" - or - wrong = "identicial" and right = "identical" - or - wrong = "identifers" and right = "identifiers" - or - wrong = "ideosyncratic" and right = "idiosyncratic" - or - wrong = "idesa" and right = "ideas" - or - wrong = "idesa" and right = "ides" - or - wrong = "idiosyncracy" and right = "idiosyncrasy" - or - wrong = "ihaca" and right = "ithaca" - or - wrong = "illegimacy" and right = "illegitimacy" - or - wrong = "illegitmate" and right = "illegitimate" - or - wrong = "illess" and right = "illness" - or - wrong = "illiegal" and right = "illegal" - or - wrong = "illution" and right = "illusion" - or - wrong = "ilness" and right = "illness" - or - wrong = "ilogical" and right = "illogical" - or - wrong = "imagenary" and right = "imaginary" - or - wrong = "imagin" and right = "imagine" - or - wrong = "imaginery" and right = "imagery" - or - wrong = "imaginery" and right = "imaginary" - or - wrong = "imanent" and right = "eminent" - or - wrong = "imanent" and right = "imminent" - or - wrong = "imcomplete" and right = "incomplete" - or - wrong = "imediately" and right = "immediately" - or - wrong = "imense" and right = "immense" - or - wrong = "imigrant" and right = "emigrant" - or - wrong = "imigrant" and right = "immigrant" - or - wrong = "imigrated" and right = "emigrated" - or - wrong = "imigrated" and right = "immigrated" - or - wrong = "imigration" and right = "emigration" - or - wrong = "imigration" and right = "immigration" - or - wrong = "iminent" and right = "eminent" - or - wrong = "iminent" and right = "immanent" - or - wrong = "iminent" and right = "imminent" - or - wrong = "immediatley" and right = "immediately" - or - wrong = "immediatly" and right = "immediately" - or - wrong = "immidately" and right = "immediately" - or - wrong = "immidiately" and right = "immediately" - or - wrong = "immitate" and right = "imitate" - or - wrong = "immitated" and right = "imitated" - or - wrong = "immitating" and right = "imitating" - or - wrong = "immitator" and right = "imitator" - or - wrong = "immunosupressant" and right = "immunosuppressant" - or - wrong = "impecabbly" and right = "impeccably" - or - wrong = "impedence" and right = "impedance" - or - wrong = "implamenting" and right = "implementing" - or - wrong = "impliment" and right = "implement" - or - wrong = "implimented" and right = "implemented" - or - wrong = "imploys" and right = "employs" - or - wrong = "importamt" and right = "important" - or - wrong = "impressario" and right = "impresario" - or - wrong = "imprioned" and right = "imprisoned" - or - wrong = "imprisonned" and right = "imprisoned" - or - wrong = "improvision" and right = "improvisation" - or - wrong = "improvments" and right = "improvements" - or - wrong = "inablility" and right = "inability" - or - wrong = "inaccessable" and right = "inaccessible" - or - wrong = "inadiquate" and right = "inadequate" - or - wrong = "inadquate" and right = "inadequate" - or - wrong = "inadvertant" and right = "inadvertent" - or - wrong = "inadvertantly" and right = "inadvertently" - or - wrong = "inagurated" and right = "inaugurated" - or - wrong = "inaguration" and right = "inauguration" - or - wrong = "inappropiate" and right = "inappropriate" - or - wrong = "inaugures" and right = "inaugurates" - or - wrong = "inbalance" and right = "imbalance" - or - wrong = "inbalanced" and right = "imbalanced" - or - wrong = "inbetween" and right = "between" - or - wrong = "incarcirated" and right = "incarcerated" - or - wrong = "incidentially" and right = "incidentally" - or - wrong = "incidently" and right = "incidentally" - or - wrong = "inclreased" and right = "increased" - or - wrong = "includ" and right = "include" - or - wrong = "includng" and right = "including" - or - wrong = "incompatabilities" and right = "incompatibilities" - or - wrong = "incompatability" and right = "incompatibility" - or - wrong = "incompatable" and right = "incompatible" - or - wrong = "incompatablities" and right = "incompatibilities" - or - wrong = "incompatablity" and right = "incompatibility" - or - wrong = "incompatiblities" and right = "incompatibilities" - or - wrong = "incompatiblity" and right = "incompatibility" - or - wrong = "incompetance" and right = "incompetence" - or - wrong = "incompetant" and right = "incompetent" - or - wrong = "incomptable" and right = "incompatible" - or - wrong = "incomptetent" and right = "incompetent" - or - wrong = "inconsistant" and right = "inconsistent" - or - wrong = "incoroporated" and right = "incorporated" - or - wrong = "incorperation" and right = "incorporation" - or - wrong = "incorportaed" and right = "incorporated" - or - wrong = "incorprates" and right = "incorporates" - or - wrong = "incorruptable" and right = "incorruptible" - or - wrong = "incramentally" and right = "incrementally" - or - wrong = "increadible" and right = "incredible" - or - wrong = "incredable" and right = "incredible" - or - wrong = "inctroduce" and right = "introduce" - or - wrong = "inctroduced" and right = "introduced" - or - wrong = "incuding" and right = "including" - or - wrong = "incunabla" and right = "incunabula" - or - wrong = "indefinately" and right = "indefinitely" - or - wrong = "indefineable" and right = "undefinable" - or - wrong = "indefinitly" and right = "indefinitely" - or - wrong = "indentical" and right = "identical" - or - wrong = "indepedantly" and right = "independently" - or - wrong = "indepedence" and right = "independence" - or - wrong = "independance" and right = "independence" - or - wrong = "independant" and right = "independent" - or - wrong = "independantly" and right = "independently" - or - wrong = "independece" and right = "independence" - or - wrong = "independendet" and right = "independent" - or - wrong = "indespensable" and right = "indispensable" - or - wrong = "indespensible" and right = "indispensable" - or - wrong = "indictement" and right = "indictment" - or - wrong = "indigineous" and right = "indigenous" - or - wrong = "indipendence" and right = "independence" - or - wrong = "indipendent" and right = "independent" - or - wrong = "indipendently" and right = "independently" - or - wrong = "indispensible" and right = "indispensable" - or - wrong = "indisputible" and right = "indisputable" - or - wrong = "indisputibly" and right = "indisputably" - or - wrong = "indite" and right = "indict" - or - wrong = "individualy" and right = "individually" - or - wrong = "indpendent" and right = "independent" - or - wrong = "indpendently" and right = "independently" - or - wrong = "indulgue" and right = "indulge" - or - wrong = "indutrial" and right = "industrial" - or - wrong = "indviduals" and right = "individuals" - or - wrong = "inefficienty" and right = "inefficiently" - or - wrong = "inevatible" and right = "inevitable" - or - wrong = "inevitible" and right = "inevitable" - or - wrong = "inevititably" and right = "inevitably" - or - wrong = "infalability" and right = "infallibility" - or - wrong = "infallable" and right = "infallible" - or - wrong = "infectuous" and right = "infectious" - or - wrong = "infered" and right = "inferred" - or - wrong = "infilitrate" and right = "infiltrate" - or - wrong = "infilitrated" and right = "infiltrated" - or - wrong = "infilitration" and right = "infiltration" - or - wrong = "infinit" and right = "infinite" - or - wrong = "inflamation" and right = "inflammation" - or - wrong = "influencial" and right = "influential" - or - wrong = "influented" and right = "influenced" - or - wrong = "infomation" and right = "information" - or - wrong = "informtion" and right = "information" - or - wrong = "infrantryman" and right = "infantryman" - or - wrong = "infrigement" and right = "infringement" - or - wrong = "ingenius" and right = "ingenious" - or - wrong = "ingreediants" and right = "ingredients" - or - wrong = "inhabitans" and right = "inhabitants" - or - wrong = "inherantly" and right = "inherently" - or - wrong = "inheritage" and right = "heritage" - or - wrong = "inheritage" and right = "inheritance" - or - wrong = "inheritence" and right = "inheritance" - or - wrong = "inital" and right = "initial" - or - wrong = "initalize" and right = "initialize" - or - wrong = "initally" and right = "initially" - or - wrong = "initation" and right = "initiation" - or - wrong = "initiaitive" and right = "initiative" - or - wrong = "inlcuding" and right = "including" - or - wrong = "inmigrant" and right = "immigrant" - or - wrong = "inmigrants" and right = "immigrants" - or - wrong = "innoculated" and right = "inoculated" - or - wrong = "inocence" and right = "innocence" - or - wrong = "inofficial" and right = "unofficial" - or - wrong = "inot" and right = "into" - or - wrong = "inpeach" and right = "impeach" - or - wrong = "inpending" and right = "impending" - or - wrong = "inpenetrable" and right = "impenetrable" - or - wrong = "inpolite" and right = "impolite" - or - wrong = "inprisonment" and right = "imprisonment" - or - wrong = "inproving" and right = "improving" - or - wrong = "insectiverous" and right = "insectivorous" - or - wrong = "insensative" and right = "insensitive" - or - wrong = "inseperable" and right = "inseparable" - or - wrong = "insistance" and right = "insistence" - or - wrong = "insitution" and right = "institution" - or - wrong = "insitutions" and right = "institutions" - or - wrong = "inspite" and right = "inspire" - or - wrong = "instade" and right = "instead" - or - wrong = "instatance" and right = "instance" - or - wrong = "institue" and right = "institute" - or - wrong = "instuction" and right = "instruction" - or - wrong = "instuments" and right = "instruments" - or - wrong = "instutionalized" and right = "institutionalized" - or - wrong = "instutions" and right = "intuitions" - or - wrong = "insurence" and right = "insurance" - or - wrong = "intelectual" and right = "intellectual" - or - wrong = "inteligence" and right = "intelligence" - or - wrong = "inteligent" and right = "intelligent" - or - wrong = "intenational" and right = "international" - or - wrong = "intented" and right = "indented" - or - wrong = "intented" and right = "intended" - or - wrong = "intepretation" and right = "interpretation" - or - wrong = "intepretator" and right = "interpretor" - or - wrong = "interational" and right = "international" - or - wrong = "interbread" and right = "interbred" - or - wrong = "interbread" and right = "interbreed" - or - wrong = "interchangable" and right = "interchangeable" - or - wrong = "interchangably" and right = "interchangeably" - or - wrong = "intercontinential" and right = "intercontinental" - or - wrong = "intercontinetal" and right = "intercontinental" - or - wrong = "intered" and right = "interned" - or - wrong = "intered" and right = "interred" - or - wrong = "interelated" and right = "interrelated" - or - wrong = "interferance" and right = "interference" - or - wrong = "interfereing" and right = "interfering" - or - wrong = "intergrated" and right = "integrated" - or - wrong = "intergration" and right = "integration" - or - wrong = "interm" and right = "interim" - or - wrong = "internation" and right = "international" - or - wrong = "interpet" and right = "interpret" - or - wrong = "interrim" and right = "interim" - or - wrong = "interrugum" and right = "interregnum" - or - wrong = "intertaining" and right = "entertaining" - or - wrong = "interupt" and right = "interrupt" - or - wrong = "intervines" and right = "intervenes" - or - wrong = "intevene" and right = "intervene" - or - wrong = "intial" and right = "initial" - or - wrong = "intialize" and right = "initialize" - or - wrong = "intialized" and right = "initialized" - or - wrong = "intially" and right = "initially" - or - wrong = "intrduced" and right = "introduced" - or - wrong = "intrest" and right = "interest" - or - wrong = "introdued" and right = "introduced" - or - wrong = "intruduced" and right = "introduced" - or - wrong = "intrument" and right = "instrument" - or - wrong = "intrumental" and right = "instrumental" - or - wrong = "intruments" and right = "instruments" - or - wrong = "intrusted" and right = "entrusted" - or - wrong = "intutive" and right = "intuitive" - or - wrong = "intutively" and right = "intuitively" - or - wrong = "inudstry" and right = "industry" - or - wrong = "inumerable" and right = "enumerable" - or - wrong = "inumerable" and right = "innumerable" - or - wrong = "inventer" and right = "inventor" - or - wrong = "invertibrates" and right = "invertebrates" - or - wrong = "investingate" and right = "investigate" - or - wrong = "involvment" and right = "involvement" - or - wrong = "irelevent" and right = "irrelevant" - or - wrong = "iresistable" and right = "irresistible" - or - wrong = "iresistably" and right = "irresistibly" - or - wrong = "iresistible" and right = "irresistible" - or - wrong = "iresistibly" and right = "irresistibly" - or - wrong = "iritable" and right = "irritable" - or - wrong = "iritated" and right = "irritated" - or - wrong = "ironicly" and right = "ironically" - or - wrong = "irregardless" and right = "regardless" - or - wrong = "irrelevent" and right = "irrelevant" - or - wrong = "irreplacable" and right = "irreplaceable" - or - wrong = "irresistable" and right = "irresistible" - or - wrong = "irresistably" and right = "irresistibly" - or - wrong = "israelies" and right = "israelis" - or - wrong = "issueing" and right = "issuing" - or - wrong = "itnroduced" and right = "introduced" - or - wrong = "iunior" and right = "junior" - or - wrong = "iwll" and right = "will" - or - wrong = "iwth" and right = "with" - or - wrong = "janurary" and right = "january" - or - wrong = "januray" and right = "january" - or - wrong = "japanes" and right = "japanese" - or - wrong = "jaques" and right = "jacques" - or - wrong = "jeapardy" and right = "jeopardy" - or - wrong = "jewllery" and right = "jewellery" - or - wrong = "johanine" and right = "johannine" - or - wrong = "jorunal" and right = "journal" - or - wrong = "jospeh" and right = "joseph" - or - wrong = "jouney" and right = "journey" - or - wrong = "journied" and right = "journeyed" - or - wrong = "journies" and right = "journeys" - or - wrong = "jstu" and right = "just" - or - wrong = "jsut" and right = "just" - or - wrong = "juadaism" and right = "judaism" - or - wrong = "juadism" and right = "judaism" - or - wrong = "judical" and right = "judicial" - or - wrong = "judisuary" and right = "judiciary" - or - wrong = "juducial" and right = "judicial" - or - wrong = "juristiction" and right = "jurisdiction" - or - wrong = "juristictions" and right = "jurisdictions" - or - wrong = "kindergarden" and right = "kindergarten" - or - wrong = "klenex" and right = "kleenex" - or - wrong = "knifes" and right = "knives" - or - wrong = "knive" and right = "knife" - or - wrong = "knowlege" and right = "knowledge" - or - wrong = "knowlegeable" and right = "knowledgeable" - or - wrong = "knwo" and right = "know" - or - wrong = "knwos" and right = "knows" - or - wrong = "konw" and right = "know" - or - wrong = "konws" and right = "knows" - or - wrong = "kwno" and right = "know" - or - wrong = "labatory" and right = "laboratory" - or - wrong = "labatory" and right = "lavatory" - or - wrong = "labled" and right = "labeled" - or - wrong = "labled" and right = "labelled" - or - wrong = "labratory" and right = "laboratory" - or - wrong = "laguage" and right = "language" - or - wrong = "laguages" and right = "languages" - or - wrong = "langage" and right = "language" - or - wrong = "langauge" and right = "language" - or - wrong = "larg" and right = "large" - or - wrong = "largst" and right = "largest" - or - wrong = "larrry" and right = "larry" - or - wrong = "lastr" and right = "last" - or - wrong = "lattitude" and right = "latitude" - or - wrong = "launchs" and right = "launch" - or - wrong = "launchs" and right = "launches" - or - wrong = "launhed" and right = "launched" - or - wrong = "lavae" and right = "larvae" - or - wrong = "layed" and right = "laid" - or - wrong = "lazyness" and right = "laziness" - or - wrong = "leage" and right = "league" - or - wrong = "leanr" and right = "lean" - or - wrong = "leanr" and right = "leaner" - or - wrong = "leanr" and right = "learn" - or - wrong = "leathal" and right = "lethal" - or - wrong = "lefted" and right = "left" - or - wrong = "legitamate" and right = "legitimate" - or - wrong = "legitmate" and right = "legitimate" - or - wrong = "leibnitz" and right = "leibniz" - or - wrong = "lengh" and right = "length" - or - wrong = "lenght" and right = "length" - or - wrong = "lengt" and right = "length" - or - wrong = "lenth" and right = "length" - or - wrong = "leran" and right = "learn" - or - wrong = "lerans" and right = "learns" - or - wrong = "leutenant" and right = "lieutenant" - or - wrong = "levetate" and right = "levitate" - or - wrong = "levetated" and right = "levitated" - or - wrong = "levetates" and right = "levitates" - or - wrong = "levetating" and right = "levitating" - or - wrong = "levle" and right = "level" - or - wrong = "liasion" and right = "liaison" - or - wrong = "liason" and right = "liaison" - or - wrong = "liasons" and right = "liaisons" - or - wrong = "libaries" and right = "libraries" - or - wrong = "libary" and right = "library" - or - wrong = "libell" and right = "libel" - or - wrong = "libguistic" and right = "linguistic" - or - wrong = "libguistics" and right = "linguistics" - or - wrong = "libitarianisn" and right = "libertarianism" - or - wrong = "lible" and right = "liable" - or - wrong = "lible" and right = "libel" - or - wrong = "lieing" and right = "lying" - or - wrong = "liek" and right = "like" - or - wrong = "liekd" and right = "liked" - or - wrong = "liesure" and right = "leisure" - or - wrong = "lieuenant" and right = "lieutenant" - or - wrong = "lieved" and right = "lived" - or - wrong = "liftime" and right = "lifetime" - or - wrong = "likelyhood" and right = "likelihood" - or - wrong = "linnaena" and right = "linnaean" - or - wrong = "lippizaner" and right = "lipizzaner" - or - wrong = "liquify" and right = "liquefy" - or - wrong = "liscense" and right = "licence" - or - wrong = "liscense" and right = "license" - or - wrong = "lisence" and right = "licence" - or - wrong = "lisence" and right = "license" - or - wrong = "lisense" and right = "licence" - or - wrong = "lisense" and right = "license" - or - wrong = "listners" and right = "listeners" - or - wrong = "litature" and right = "literature" - or - wrong = "literaly" and right = "literally" - or - wrong = "literture" and right = "literature" - or - wrong = "littel" and right = "little" - or - wrong = "litterally" and right = "literally" - or - wrong = "liuke" and right = "like" - or - wrong = "livley" and right = "lively" - or - wrong = "lmits" and right = "limits" - or - wrong = "loev" and right = "love" - or - wrong = "lonelyness" and right = "loneliness" - or - wrong = "longitudonal" and right = "longitudinal" - or - wrong = "lonley" and right = "lonely" - or - wrong = "lonly" and right = "lonely" - or - wrong = "lonly" and right = "only" - or - wrong = "loosing" and right = "losing" - or - wrong = "lotharingen" and right = "lothringen" - or - wrong = "lsat" and right = "last" - or - wrong = "lukid" and right = "likud" - or - wrong = "lveo" and right = "love" - or - wrong = "lvoe" and right = "love" - or - wrong = "lybia" and right = "libya" - or - wrong = "maching" and right = "machine" - or - wrong = "maching" and right = "marching" - or - wrong = "maching" and right = "matching" - or - wrong = "mackeral" and right = "mackerel" - or - wrong = "magasine" and right = "magazine" - or - wrong = "magincian" and right = "magician" - or - wrong = "magisine" and right = "magazine" - or - wrong = "magizine" and right = "magazine" - or - wrong = "magnificient" and right = "magnificent" - or - wrong = "magolia" and right = "magnolia" - or - wrong = "mailny" and right = "mainly" - or - wrong = "maintainance" and right = "maintenance" - or - wrong = "maintainence" and right = "maintenance" - or - wrong = "maintance" and right = "maintenance" - or - wrong = "maintenence" and right = "maintenance" - or - wrong = "maintinaing" and right = "maintaining" - or - wrong = "maintioned" and right = "mentioned" - or - wrong = "majoroty" and right = "majority" - or - wrong = "maked" and right = "made" - or - wrong = "maked" and right = "marked" - or - wrong = "makse" and right = "makes" - or - wrong = "malcom" and right = "malcolm" - or - wrong = "maltesian" and right = "maltese" - or - wrong = "mamal" and right = "mammal" - or - wrong = "mamalian" and right = "mammalian" - or - wrong = "managable" and right = "manageable" - or - wrong = "managable" and right = "manageably" - or - wrong = "managment" and right = "management" - or - wrong = "maneouvre" and right = "manoeuvre" - or - wrong = "maneouvred" and right = "manoeuvred" - or - wrong = "maneouvres" and right = "manoeuvres" - or - wrong = "maneouvring" and right = "manoeuvring" - or - wrong = "manisfestations" and right = "manifestations" - or - wrong = "manoeuverability" and right = "maneuverability" - or - wrong = "manouver" and right = "maneuver" - or - wrong = "manouver" and right = "manoeuvre" - or - wrong = "manouverability" and right = "maneuverability" - or - wrong = "manouverability" and right = "manoeuverability" - or - wrong = "manouverability" and right = "manoeuvrability" - or - wrong = "manouverable" and right = "maneuverable" - or - wrong = "manouverable" and right = "manoeuvrable" - or - wrong = "manouvers" and right = "maneuvers" - or - wrong = "manouvers" and right = "manoeuvres" - or - wrong = "mantained" and right = "maintained" - or - wrong = "manuever" and right = "maneuver" - or - wrong = "manuever" and right = "manoeuvre" - or - wrong = "manuevers" and right = "maneuvers" - or - wrong = "manuevers" and right = "manoeuvres" - or - wrong = "manufacturedd" and right = "manufactured" - or - wrong = "manufature" and right = "manufacture" - or - wrong = "manufatured" and right = "manufactured" - or - wrong = "manufaturing" and right = "manufacturing" - or - wrong = "manuver" and right = "maneuver" - or - wrong = "mariage" and right = "marriage" - or - wrong = "marjority" and right = "majority" - or - wrong = "markes" and right = "marks" - or - wrong = "marketting" and right = "marketing" - or - wrong = "marmelade" and right = "marmalade" - or - wrong = "marrage" and right = "marriage" - or - wrong = "marraige" and right = "marriage" - or - wrong = "marrtyred" and right = "martyred" - or - wrong = "marryied" and right = "married" - or - wrong = "massachussets" and right = "massachusetts" - or - wrong = "massachussetts" and right = "massachusetts" - or - wrong = "masterbation" and right = "masturbation" - or - wrong = "mataphysical" and right = "metaphysical" - or - wrong = "materalists" and right = "materialist" - or - wrong = "mathamatics" and right = "mathematics" - or - wrong = "mathematican" and right = "mathematician" - or - wrong = "mathematicas" and right = "mathematics" - or - wrong = "matheticians" and right = "mathematicians" - or - wrong = "mathmatically" and right = "mathematically" - or - wrong = "mathmatician" and right = "mathematician" - or - wrong = "mathmaticians" and right = "mathematicians" - or - wrong = "mccarthyst" and right = "mccarthyist" - or - wrong = "mchanics" and right = "mechanics" - or - wrong = "meaninng" and right = "meaning" - or - wrong = "mear" and right = "mare" - or - wrong = "mear" and right = "mere" - or - wrong = "mear" and right = "wear" - or - wrong = "mechandise" and right = "merchandise" - or - wrong = "medacine" and right = "medicine" - or - wrong = "medeival" and right = "medieval" - or - wrong = "medevial" and right = "medieval" - or - wrong = "mediciney" and right = "mediciny" - or - wrong = "medievel" and right = "medieval" - or - wrong = "mediterainnean" and right = "mediterranean" - or - wrong = "mediteranean" and right = "mediterranean" - or - wrong = "meerkrat" and right = "meerkat" - or - wrong = "melieux" and right = "milieux" - or - wrong = "membranaphone" and right = "membranophone" - or - wrong = "memeber" and right = "member" - or - wrong = "menally" and right = "mentally" - or - wrong = "meranda" and right = "miranda" - or - wrong = "meranda" and right = "veranda" - or - wrong = "mercentile" and right = "mercantile" - or - wrong = "mesage" and right = "message" - or - wrong = "messanger" and right = "messenger" - or - wrong = "messenging" and right = "messaging" - or - wrong = "messsage" and right = "message" - or - wrong = "metalic" and right = "metallic" - or - wrong = "metalurgic" and right = "metallurgic" - or - wrong = "metalurgical" and right = "metallurgical" - or - wrong = "metalurgy" and right = "metallurgy" - or - wrong = "metamorphysis" and right = "metamorphosis" - or - wrong = "metaphoricial" and right = "metaphorical" - or - wrong = "meterologist" and right = "meteorologist" - or - wrong = "meterology" and right = "meteorology" - or - wrong = "methaphor" and right = "metaphor" - or - wrong = "methaphors" and right = "metaphors" - or - wrong = "michagan" and right = "michigan" - or - wrong = "micoscopy" and right = "microscopy" - or - wrong = "midwifes" and right = "midwives" - or - wrong = "mileau" and right = "milieu" - or - wrong = "milennia" and right = "millennia" - or - wrong = "milennium" and right = "millennium" - or - wrong = "mileu" and right = "milieu" - or - wrong = "miliary" and right = "military" - or - wrong = "miligram" and right = "milligram" - or - wrong = "milion" and right = "million" - or - wrong = "miliraty" and right = "military" - or - wrong = "millenia" and right = "millennia" - or - wrong = "millenial" and right = "millennial" - or - wrong = "millenialism" and right = "millennialism" - or - wrong = "millenium" and right = "millennium" - or - wrong = "millepede" and right = "millipede" - or - wrong = "millioniare" and right = "millionaire" - or - wrong = "millitant" and right = "militant" - or - wrong = "millitary" and right = "military" - or - wrong = "millon" and right = "million" - or - wrong = "miltary" and right = "military" - or - wrong = "minature" and right = "miniature" - or - wrong = "minerial" and right = "mineral" - or - wrong = "ministery" and right = "ministry" - or - wrong = "minsitry" and right = "ministry" - or - wrong = "minstries" and right = "ministries" - or - wrong = "minstry" and right = "ministry" - or - wrong = "minumum" and right = "minimum" - or - wrong = "mirrorred" and right = "mirrored" - or - wrong = "miscelaneous" and right = "miscellaneous" - or - wrong = "miscellanious" and right = "miscellaneous" - or - wrong = "miscellanous" and right = "miscellaneous" - or - wrong = "mischeivous" and right = "mischievous" - or - wrong = "mischevious" and right = "mischievous" - or - wrong = "mischievious" and right = "mischievous" - or - wrong = "misdameanor" and right = "misdemeanor" - or - wrong = "misdameanors" and right = "misdemeanors" - or - wrong = "misdemenor" and right = "misdemeanor" - or - wrong = "misdemenors" and right = "misdemeanors" - or - wrong = "misfourtunes" and right = "misfortunes" - or - wrong = "misile" and right = "missile" - or - wrong = "misouri" and right = "missouri" - or - wrong = "mispell" and right = "misspell" - or - wrong = "mispelled" and right = "misspelled" - or - wrong = "mispelling" and right = "misspelling" - or - wrong = "missen" and right = "mizzen" - or - wrong = "missisipi" and right = "mississippi" - or - wrong = "missisippi" and right = "mississippi" - or - wrong = "missle" and right = "missile" - or - wrong = "missonary" and right = "missionary" - or - wrong = "misterious" and right = "mysterious" - or - wrong = "mistery" and right = "mystery" - or - wrong = "misteryous" and right = "mysterious" - or - wrong = "mkae" and right = "make" - or - wrong = "mkaes" and right = "makes" - or - wrong = "mkaing" and right = "making" - or - wrong = "mkea" and right = "make" - or - wrong = "moderm" and right = "modem" - or - wrong = "modle" and right = "model" - or - wrong = "moent" and right = "moment" - or - wrong = "moeny" and right = "money" - or - wrong = "mohammedans" and right = "muslims" - or - wrong = "moil" and right = "mohel" - or - wrong = "moil" and right = "soil" - or - wrong = "moleclues" and right = "molecules" - or - wrong = "momento" and right = "memento" - or - wrong = "monestaries" and right = "monasteries" - or - wrong = "monestary" and right = "monastery" - or - wrong = "monestary" and right = "monetary" - or - wrong = "monickers" and right = "monikers" - or - wrong = "monolite" and right = "monolithic" - or - wrong = "monserrat" and right = "montserrat" - or - wrong = "montains" and right = "mountains" - or - wrong = "montanous" and right = "mountainous" - or - wrong = "montnana" and right = "montana" - or - wrong = "monts" and right = "months" - or - wrong = "montypic" and right = "monotypic" - or - wrong = "moreso" and right = "more" - or - wrong = "morgage" and right = "mortgage" - or - wrong = "morisette" and right = "morissette" - or - wrong = "morrisette" and right = "morissette" - or - wrong = "morroccan" and right = "moroccan" - or - wrong = "morrocco" and right = "morocco" - or - wrong = "morroco" and right = "morocco" - or - wrong = "mortage" and right = "mortgage" - or - wrong = "mosture" and right = "moisture" - or - wrong = "motiviated" and right = "motivated" - or - wrong = "mounth" and right = "month" - or - wrong = "movei" and right = "movie" - or - wrong = "movment" and right = "movement" - or - wrong = "mroe" and right = "more" - or - wrong = "mucuous" and right = "mucous" - or - wrong = "muder" and right = "murder" - or - wrong = "mudering" and right = "murdering" - or - wrong = "muhammadan" and right = "muslim" - or - wrong = "multicultralism" and right = "multiculturalism" - or - wrong = "multipled" and right = "multiplied" - or - wrong = "multiplers" and right = "multipliers" - or - wrong = "munbers" and right = "numbers" - or - wrong = "muncipalities" and right = "municipalities" - or - wrong = "muncipality" and right = "municipality" - or - wrong = "munnicipality" and right = "municipality" - or - wrong = "muscels" and right = "muscles" - or - wrong = "muscels" and right = "mussels" - or - wrong = "muscial" and right = "musical" - or - wrong = "muscician" and right = "musician" - or - wrong = "muscicians" and right = "musicians" - or - wrong = "mutiliated" and right = "mutilated" - or - wrong = "mutiple" and right = "multiple" - or - wrong = "myraid" and right = "myriad" - or - wrong = "mysef" and right = "myself" - or - wrong = "mysogynist" and right = "misogynist" - or - wrong = "mysogyny" and right = "misogyny" - or - wrong = "mysterous" and right = "mysterious" - or - wrong = "mythraic" and right = "mithraic" - or - wrong = "naieve" and right = "naive" - or - wrong = "naploeon" and right = "napoleon" - or - wrong = "napolean" and right = "napoleon" - or - wrong = "napoleonian" and right = "napoleonic" - or - wrong = "naturaly" and right = "naturally" - or - wrong = "naturely" and right = "naturally" - or - wrong = "naturual" and right = "natural" - or - wrong = "naturually" and right = "naturally" - or - wrong = "nazereth" and right = "nazareth" - or - wrong = "neccesarily" and right = "necessarily" - or - wrong = "neccesary" and right = "necessary" - or - wrong = "neccessarily" and right = "necessarily" - or - wrong = "neccessary" and right = "necessary" - or - wrong = "neccessities" and right = "necessities" - or - wrong = "necesarily" and right = "necessarily" - or - wrong = "necesary" and right = "necessary" - or - wrong = "necessiate" and right = "necessitate" - or - wrong = "neglible" and right = "negligible" - or - wrong = "negligable" and right = "negligible" - or - wrong = "negociate" and right = "negotiate" - or - wrong = "negociation" and right = "negotiation" - or - wrong = "negociations" and right = "negotiations" - or - wrong = "negotation" and right = "negotiation" - or - wrong = "neice" and right = "nice" - or - wrong = "neice" and right = "niece" - or - wrong = "neigborhood" and right = "neighborhood" - or - wrong = "neigbour" and right = "neighbor" - or - wrong = "neigbour" and right = "neighbour" - or - wrong = "neigbourhood" and right = "neighbourhood" - or - wrong = "neigbouring" and right = "neighboring" - or - wrong = "neigbouring" and right = "neighbouring" - or - wrong = "neigbours" and right = "neighbors" - or - wrong = "neigbours" and right = "neighbours" - or - wrong = "neolitic" and right = "neolithic" - or - wrong = "nessasarily" and right = "necessarily" - or - wrong = "nessecary" and right = "necessary" - or - wrong = "nestin" and right = "nesting" - or - wrong = "neverthless" and right = "nevertheless" - or - wrong = "newletters" and right = "newsletters" - or - wrong = "nickle" and right = "nickel" - or - wrong = "nightime" and right = "nighttime" - or - wrong = "nineth" and right = "ninth" - or - wrong = "ninteenth" and right = "nineteenth" - or - wrong = "ninty" and right = "ninety" - or - wrong = "nkow" and right = "know" - or - wrong = "nkwo" and right = "know" - or - wrong = "nmae" and right = "name" - or - wrong = "noncombatents" and right = "noncombatants" - or - wrong = "nonsence" and right = "nonsense" - or - wrong = "nontheless" and right = "nonetheless" - or - wrong = "norhern" and right = "northern" - or - wrong = "northen" and right = "northern" - or - wrong = "northereastern" and right = "northeastern" - or - wrong = "notabley" and right = "notably" - or - wrong = "noteable" and right = "notable" - or - wrong = "noteably" and right = "notably" - or - wrong = "noteriety" and right = "notoriety" - or - wrong = "noth" and right = "north" - or - wrong = "nothern" and right = "northern" - or - wrong = "noticable" and right = "noticeable" - or - wrong = "noticably" and right = "noticeably" - or - wrong = "notications" and right = "notifications" - or - wrong = "noticeing" and right = "noticing" - or - wrong = "noticible" and right = "noticeable" - or - wrong = "notwhithstanding" and right = "notwithstanding" - or - wrong = "noveau" and right = "nouveau" - or - wrong = "novermber" and right = "november" - or - wrong = "nowdays" and right = "nowadays" - or - wrong = "nowe" and right = "now" - or - wrong = "nto" and right = "not" - or - wrong = "nubmer" and right = "number" - or - wrong = "nucular" and right = "nuclear" - or - wrong = "nuculear" and right = "nuclear" - or - wrong = "nuisanse" and right = "nuisance" - or - wrong = "nullabour" and right = "nullarbor" - or - wrong = "numberous" and right = "numerous" - or - wrong = "nuremburg" and right = "nuremberg" - or - wrong = "nusance" and right = "nuisance" - or - wrong = "nutritent" and right = "nutrient" - or - wrong = "nutritents" and right = "nutrients" - or - wrong = "nuturing" and right = "nurturing" - or - wrong = "obect" and right = "object" - or - wrong = "obediance" and right = "obedience" - or - wrong = "obediant" and right = "obedient" - or - wrong = "obejct" and right = "object" - or - wrong = "obession" and right = "obsession" - or - wrong = "obssessed" and right = "obsessed" - or - wrong = "obstacal" and right = "obstacle" - or - wrong = "obstancles" and right = "obstacles" - or - wrong = "obstruced" and right = "obstructed" - or - wrong = "ocasion" and right = "occasion" - or - wrong = "ocasional" and right = "occasional" - or - wrong = "ocasionally" and right = "occasionally" - or - wrong = "ocasionaly" and right = "occasionally" - or - wrong = "ocasioned" and right = "occasioned" - or - wrong = "ocasions" and right = "occasions" - or - wrong = "ocassion" and right = "occasion" - or - wrong = "ocassional" and right = "occasional" - or - wrong = "ocassionally" and right = "occasionally" - or - wrong = "ocassionaly" and right = "occasionally" - or - wrong = "ocassioned" and right = "occasioned" - or - wrong = "ocassions" and right = "occasions" - or - wrong = "occaison" and right = "occasion" - or - wrong = "occassion" and right = "occasion" - or - wrong = "occassional" and right = "occasional" - or - wrong = "occassionally" and right = "occasionally" - or - wrong = "occassionaly" and right = "occasionally" - or - wrong = "occassioned" and right = "occasioned" - or - wrong = "occassions" and right = "occasions" - or - wrong = "occationally" and right = "occasionally" - or - wrong = "occour" and right = "occur" - or - wrong = "occurance" and right = "occurrence" - or - wrong = "occurances" and right = "occurrences" - or - wrong = "occured" and right = "occurred" - or - wrong = "occurence" and right = "occurrence" - or - wrong = "occurences" and right = "occurrences" - or - wrong = "occuring" and right = "occurring" - or - wrong = "occurr" and right = "occur" - or - wrong = "occurrance" and right = "occurrence" - or - wrong = "occurrances" and right = "occurrences" - or - wrong = "octohedra" and right = "octahedra" - or - wrong = "octohedral" and right = "octahedral" - or - wrong = "octohedron" and right = "octahedron" - or - wrong = "ocuntries" and right = "countries" - or - wrong = "ocuntry" and right = "country" - or - wrong = "ocurr" and right = "occur" - or - wrong = "ocurrance" and right = "occurrence" - or - wrong = "ocurred" and right = "occurred" - or - wrong = "ocurrence" and right = "occurrence" - or - wrong = "offcers" and right = "officers" - or - wrong = "offcially" and right = "officially" - or - wrong = "offereings" and right = "offerings" - or - wrong = "offical" and right = "official" - or - wrong = "offically" and right = "officially" - or - wrong = "officals" and right = "officials" - or - wrong = "officaly" and right = "officially" - or - wrong = "officialy" and right = "officially" - or - wrong = "offred" and right = "offered" - or - wrong = "oftenly" and right = "often" - or - wrong = "oging" and right = "going" - or - wrong = "oging" and right = "ogling" - or - wrong = "oject" and right = "object" - or - wrong = "omision" and right = "omission" - or - wrong = "omited" and right = "omitted" - or - wrong = "omiting" and right = "omitting" - or - wrong = "omlette" and right = "omelette" - or - wrong = "ommision" and right = "omission" - or - wrong = "ommited" and right = "omitted" - or - wrong = "ommiting" and right = "omitting" - or - wrong = "ommitted" and right = "omitted" - or - wrong = "ommitting" and right = "omitting" - or - wrong = "omniverous" and right = "omnivorous" - or - wrong = "omniverously" and right = "omnivorously" - or - wrong = "omre" and right = "more" - or - wrong = "onot" and right = "not" - or - wrong = "onot" and right = "note" - or - wrong = "onyl" and right = "only" - or - wrong = "openess" and right = "openness" - or - wrong = "oponent" and right = "opponent" - or - wrong = "oportunity" and right = "opportunity" - or - wrong = "opose" and right = "oppose" - or - wrong = "oposite" and right = "opposite" - or - wrong = "oposition" and right = "opposition" - or - wrong = "oppenly" and right = "openly" - or - wrong = "oppinion" and right = "opinion" - or - wrong = "opponant" and right = "opponent" - or - wrong = "oppononent" and right = "opponent" - or - wrong = "oppositition" and right = "opposition" - or - wrong = "oppossed" and right = "opposed" - or - wrong = "opprotunity" and right = "opportunity" - or - wrong = "opression" and right = "oppression" - or - wrong = "opressive" and right = "oppressive" - or - wrong = "opthalmic" and right = "ophthalmic" - or - wrong = "opthalmologist" and right = "ophthalmologist" - or - wrong = "opthalmology" and right = "ophthalmology" - or - wrong = "opthamologist" and right = "ophthalmologist" - or - wrong = "optmizations" and right = "optimizations" - or - wrong = "optomism" and right = "optimism" - or - wrong = "orded" and right = "ordered" - or - wrong = "organim" and right = "organism" - or - wrong = "organistion" and right = "organisation" - or - wrong = "organiztion" and right = "organization" - or - wrong = "orgin" and right = "organ" - or - wrong = "orgin" and right = "origin" - or - wrong = "orginal" and right = "original" - or - wrong = "orginally" and right = "originally" - or - wrong = "orginize" and right = "organise" - or - wrong = "oridinarily" and right = "ordinarily" - or - wrong = "origanaly" and right = "originally" - or - wrong = "originall" and right = "original" - or - wrong = "originall" and right = "originally" - or - wrong = "originaly" and right = "originally" - or - wrong = "originially" and right = "originally" - or - wrong = "originnally" and right = "originally" - or - wrong = "origional" and right = "original" - or - wrong = "orignally" and right = "originally" - or - wrong = "orignially" and right = "originally" - or - wrong = "otehr" and right = "other" - or - wrong = "oublisher" and right = "publisher" - or - wrong = "ouevre" and right = "oeuvre" - or - wrong = "ouput" and right = "output" - or - wrong = "oustanding" and right = "outstanding" - or - wrong = "overriden" and right = "overridden" - or - wrong = "overshaddowed" and right = "overshadowed" - or - wrong = "overwelming" and right = "overwhelming" - or - wrong = "overwheliming" and right = "overwhelming" - or - wrong = "owrk" and right = "work" - or - wrong = "owudl" and right = "would" - or - wrong = "oxigen" and right = "oxygen" - or - wrong = "oximoron" and right = "oxymoron" - or - wrong = "p0enis" and right = "penis" - or - wrong = "paide" and right = "paid" - or - wrong = "paitience" and right = "patience" - or - wrong = "palce" and right = "palace" - or - wrong = "palce" and right = "place" - or - wrong = "paleolitic" and right = "paleolithic" - or - wrong = "paliamentarian" and right = "parliamentarian" - or - wrong = "palistian" and right = "palestinian" - or - wrong = "palistinian" and right = "palestinian" - or - wrong = "palistinians" and right = "palestinians" - or - wrong = "pallete" and right = "palette" - or - wrong = "pamflet" and right = "pamphlet" - or - wrong = "pamplet" and right = "pamphlet" - or - wrong = "pantomine" and right = "pantomime" - or - wrong = "papanicalou" and right = "papanicolaou" - or - wrong = "paralel" and right = "parallel" - or - wrong = "paralell" and right = "parallel" - or - wrong = "paralelly" and right = "parallelly" - or - wrong = "paralely" and right = "parallelly" - or - wrong = "parallely" and right = "parallelly" - or - wrong = "paramater" and right = "parameter" - or - wrong = "paramters" and right = "parameters" - or - wrong = "parametarized" and right = "parameterized" - or - wrong = "paranthesis" and right = "parenthesis" - or - wrong = "paraphenalia" and right = "paraphernalia" - or - wrong = "parellels" and right = "parallels" - or - wrong = "parisitic" and right = "parasitic" - or - wrong = "parituclar" and right = "particular" - or - wrong = "parliment" and right = "parliament" - or - wrong = "parrakeets" and right = "parakeets" - or - wrong = "parralel" and right = "parallel" - or - wrong = "parrallel" and right = "parallel" - or - wrong = "parrallell" and right = "parallel" - or - wrong = "parrallelly" and right = "parallelly" - or - wrong = "parrallely" and right = "parallelly" - or - wrong = "partialy" and right = "partially" - or - wrong = "particually" and right = "particularly" - or - wrong = "particualr" and right = "particular" - or - wrong = "particuarly" and right = "particularly" - or - wrong = "particularily" and right = "particularly" - or - wrong = "particulary" and right = "particularly" - or - wrong = "pary" and right = "party" - or - wrong = "pased" and right = "passed" - or - wrong = "pasengers" and right = "passengers" - or - wrong = "passerbys" and right = "passersby" - or - wrong = "pasttime" and right = "pastime" - or - wrong = "pastural" and right = "pastoral" - or - wrong = "paticular" and right = "particular" - or - wrong = "pattented" and right = "patented" - or - wrong = "pavillion" and right = "pavilion" - or - wrong = "payed" and right = "paid" - or - wrong = "pblisher" and right = "publisher" - or - wrong = "pbulisher" and right = "publisher" - or - wrong = "peageant" and right = "pageant" - or - wrong = "peaple" and right = "people" - or - wrong = "peaples" and right = "peoples" - or - wrong = "peculure" and right = "peculiar" - or - wrong = "pedestrain" and right = "pedestrian" - or - wrong = "peformed" and right = "performed" - or - wrong = "peice" and right = "piece" - or - wrong = "peloponnes" and right = "peloponnesus" - or - wrong = "penatly" and right = "penalty" - or - wrong = "penerator" and right = "penetrator" - or - wrong = "penisula" and right = "peninsula" - or - wrong = "penisular" and right = "peninsular" - or - wrong = "penninsula" and right = "peninsula" - or - wrong = "penninsular" and right = "peninsular" - or - wrong = "pennisula" and right = "peninsula" - or - wrong = "pennyslvania" and right = "pennsylvania" - or - wrong = "pensinula" and right = "peninsula" - or - wrong = "pensle" and right = "pencil" - or - wrong = "peom" and right = "poem" - or - wrong = "peoms" and right = "poems" - or - wrong = "peopel" and right = "people" - or - wrong = "peopels" and right = "peoples" - or - wrong = "peotry" and right = "poetry" - or - wrong = "perade" and right = "parade" - or - wrong = "percepted" and right = "perceived" - or - wrong = "percieve" and right = "perceive" - or - wrong = "percieved" and right = "perceived" - or - wrong = "perenially" and right = "perennially" - or - wrong = "peretrator" and right = "perpetrator" - or - wrong = "perfomance" and right = "performance" - or - wrong = "perfomers" and right = "performers" - or - wrong = "performence" and right = "performance" - or - wrong = "performes" and right = "performed" - or - wrong = "performes" and right = "performs" - or - wrong = "perhasp" and right = "perhaps" - or - wrong = "perheaps" and right = "perhaps" - or - wrong = "perhpas" and right = "perhaps" - or - wrong = "peripathetic" and right = "peripatetic" - or - wrong = "peristent" and right = "persistent" - or - wrong = "perjery" and right = "perjury" - or - wrong = "perjorative" and right = "pejorative" - or - wrong = "permanant" and right = "permanent" - or - wrong = "permenant" and right = "permanent" - or - wrong = "permenantly" and right = "permanently" - or - wrong = "permissable" and right = "permissible" - or - wrong = "perogative" and right = "prerogative" - or - wrong = "peronal" and right = "personal" - or - wrong = "perosnality" and right = "personality" - or - wrong = "perpertrated" and right = "perpetrated" - or - wrong = "perphas" and right = "perhaps" - or - wrong = "perpindicular" and right = "perpendicular" - or - wrong = "persan" and right = "person" - or - wrong = "perseverence" and right = "perseverance" - or - wrong = "persistance" and right = "persistence" - or - wrong = "persistant" and right = "persistent" - or - wrong = "personel" and right = "personal" - or - wrong = "personel" and right = "personnel" - or - wrong = "personell" and right = "personnel" - or - wrong = "personnell" and right = "personnel" - or - wrong = "persuded" and right = "persuaded" - or - wrong = "persue" and right = "pursue" - or - wrong = "persued" and right = "pursued" - or - wrong = "persuing" and right = "pursuing" - or - wrong = "persuit" and right = "pursuit" - or - wrong = "persuits" and right = "pursuits" - or - wrong = "pertubation" and right = "perturbation" - or - wrong = "pertubations" and right = "perturbations" - or - wrong = "pessiary" and right = "pessary" - or - wrong = "petetion" and right = "petition" - or - wrong = "pharoah" and right = "pharaoh" - or - wrong = "phenomenom" and right = "phenomenon" - or - wrong = "phenomenonal" and right = "phenomenal" - or - wrong = "phenomenonly" and right = "phenomenally" - or - wrong = "phenomonenon" and right = "phenomenon" - or - wrong = "phenomonon" and right = "phenomenon" - or - wrong = "phenonmena" and right = "phenomena" - or - wrong = "philipines" and right = "philippines" - or - wrong = "philisopher" and right = "philosopher" - or - wrong = "philisophical" and right = "philosophical" - or - wrong = "philisophy" and right = "philosophy" - or - wrong = "phillipine" and right = "philippine" - or - wrong = "phillipines" and right = "philippines" - or - wrong = "phillippines" and right = "philippines" - or - wrong = "phillosophically" and right = "philosophically" - or - wrong = "philospher" and right = "philosopher" - or - wrong = "philosphies" and right = "philosophies" - or - wrong = "philosphy" and right = "philosophy" - or - wrong = "phonecian" and right = "phoenecian" - or - wrong = "phongraph" and right = "phonograph" - or - wrong = "phylosophical" and right = "philosophical" - or - wrong = "physicaly" and right = "physically" - or - wrong = "piblisher" and right = "publisher" - or - wrong = "pich" and right = "pitch" - or - wrong = "pilgrimmage" and right = "pilgrimage" - or - wrong = "pilgrimmages" and right = "pilgrimages" - or - wrong = "pinapple" and right = "pineapple" - or - wrong = "pinnaple" and right = "pineapple" - or - wrong = "pinoneered" and right = "pioneered" - or - wrong = "plagarism" and right = "plagiarism" - or - wrong = "planation" and right = "plantation" - or - wrong = "planed" and right = "planned" - or - wrong = "plantiff" and right = "plaintiff" - or - wrong = "plateu" and right = "plateau" - or - wrong = "plausable" and right = "plausible" - or - wrong = "playright" and right = "playwright" - or - wrong = "playwrite" and right = "playwright" - or - wrong = "playwrites" and right = "playwrights" - or - wrong = "pleasent" and right = "pleasant" - or - wrong = "plebicite" and right = "plebiscite" - or - wrong = "plesant" and right = "pleasant" - or - wrong = "poenis" and right = "penis" - or - wrong = "poeoples" and right = "peoples" - or - wrong = "poety" and right = "poetry" - or - wrong = "poisin" and right = "poison" - or - wrong = "polical" and right = "political" - or - wrong = "polinator" and right = "pollinator" - or - wrong = "polinators" and right = "pollinators" - or - wrong = "politican" and right = "politician" - or - wrong = "politicans" and right = "politicians" - or - wrong = "poltical" and right = "political" - or - wrong = "polute" and right = "pollute" - or - wrong = "poluted" and right = "polluted" - or - wrong = "polutes" and right = "pollutes" - or - wrong = "poluting" and right = "polluting" - or - wrong = "polution" and right = "pollution" - or - wrong = "polyphonyic" and right = "polyphonic" - or - wrong = "polysaccaride" and right = "polysaccharide" - or - wrong = "polysaccharid" and right = "polysaccharide" - or - wrong = "pomegranite" and right = "pomegranate" - or - wrong = "pomotion" and right = "promotion" - or - wrong = "poportional" and right = "proportional" - or - wrong = "popoulation" and right = "population" - or - wrong = "popularaty" and right = "popularity" - or - wrong = "populare" and right = "popular" - or - wrong = "populer" and right = "popular" - or - wrong = "porshan" and right = "portion" - or - wrong = "porshon" and right = "portion" - or - wrong = "portait" and right = "portrait" - or - wrong = "portayed" and right = "portrayed" - or - wrong = "portraing" and right = "portraying" - or - wrong = "portugese" and right = "portuguese" - or - wrong = "portuguease" and right = "portuguese" - or - wrong = "portugues" and right = "portuguese" - or - wrong = "posess" and right = "possess" - or - wrong = "posessed" and right = "possessed" - or - wrong = "posesses" and right = "possesses" - or - wrong = "posessing" and right = "possessing" - or - wrong = "posession" and right = "possession" - or - wrong = "posessions" and right = "possessions" - or - wrong = "posion" and right = "poison" - or - wrong = "positon" and right = "position" - or - wrong = "positon" and right = "positron" - or - wrong = "possable" and right = "possible" - or - wrong = "possably" and right = "possibly" - or - wrong = "posseses" and right = "possesses" - or - wrong = "possesing" and right = "possessing" - or - wrong = "possesion" and right = "possession" - or - wrong = "possessess" and right = "possesses" - or - wrong = "possibile" and right = "possible" - or - wrong = "possibilty" and right = "possibility" - or - wrong = "possiblility" and right = "possibility" - or - wrong = "possiblilty" and right = "possibility" - or - wrong = "possiblities" and right = "possibilities" - or - wrong = "possiblity" and right = "possibility" - or - wrong = "possition" and right = "position" - or - wrong = "postdam" and right = "potsdam" - or - wrong = "posthomous" and right = "posthumous" - or - wrong = "postion" and right = "position" - or - wrong = "postive" and right = "positive" - or - wrong = "potatos" and right = "potatoes" - or - wrong = "potrait" and right = "portrait" - or - wrong = "potrayed" and right = "portrayed" - or - wrong = "poulations" and right = "populations" - or - wrong = "poverful" and right = "powerful" - or - wrong = "poweful" and right = "powerful" - or - wrong = "powerfull" and right = "powerful" - or - wrong = "ppublisher" and right = "publisher" - or - wrong = "practial" and right = "practical" - or - wrong = "practially" and right = "practically" - or - wrong = "practicaly" and right = "practically" - or - wrong = "practicioner" and right = "practitioner" - or - wrong = "practicioners" and right = "practitioners" - or - wrong = "practicly" and right = "practically" - or - wrong = "practioner" and right = "practitioner" - or - wrong = "practioners" and right = "practitioners" - or - wrong = "prairy" and right = "prairie" - or - wrong = "prarie" and right = "prairie" - or - wrong = "praries" and right = "prairies" - or - wrong = "pratice" and right = "practice" - or - wrong = "preample" and right = "preamble" - or - wrong = "precedessor" and right = "predecessor" - or - wrong = "preceed" and right = "precede" - or - wrong = "preceeded" and right = "preceded" - or - wrong = "preceeding" and right = "preceding" - or - wrong = "preceeds" and right = "precedes" - or - wrong = "precendence" and right = "precedence" - or - wrong = "precentage" and right = "percentage" - or - wrong = "precice" and right = "precise" - or - wrong = "precisly" and right = "precisely" - or - wrong = "precurser" and right = "precursor" - or - wrong = "predecesors" and right = "predecessors" - or - wrong = "predicatble" and right = "predictable" - or - wrong = "predicitons" and right = "predictions" - or - wrong = "predomiantly" and right = "predominately" - or - wrong = "prefered" and right = "preferred" - or - wrong = "prefering" and right = "preferring" - or - wrong = "preferrably" and right = "preferably" - or - wrong = "pregancies" and right = "pregnancies" - or - wrong = "preiod" and right = "period" - or - wrong = "preliferation" and right = "proliferation" - or - wrong = "premeire" and right = "premiere" - or - wrong = "premeired" and right = "premiered" - or - wrong = "premillenial" and right = "premillennial" - or - wrong = "preminence" and right = "preeminence" - or - wrong = "premission" and right = "permission" - or - wrong = "premonasterians" and right = "premonstratensians" - or - wrong = "preocupation" and right = "preoccupation" - or - wrong = "prepair" and right = "prepare" - or - wrong = "prepartion" and right = "preparation" - or - wrong = "prepatory" and right = "preparatory" - or - wrong = "preperation" and right = "preparation" - or - wrong = "preperations" and right = "preparations" - or - wrong = "preriod" and right = "period" - or - wrong = "presedential" and right = "presidential" - or - wrong = "presense" and right = "presence" - or - wrong = "presidenital" and right = "presidential" - or - wrong = "presidental" and right = "presidential" - or - wrong = "presitgious" and right = "prestigious" - or - wrong = "prespective" and right = "perspective" - or - wrong = "prestigeous" and right = "prestigious" - or - wrong = "prestigous" and right = "prestigious" - or - wrong = "presumabely" and right = "presumably" - or - wrong = "presumibly" and right = "presumably" - or - wrong = "pretection" and right = "protection" - or - wrong = "prevelant" and right = "prevalent" - or - wrong = "preverse" and right = "perverse" - or - wrong = "previvous" and right = "previous" - or - wrong = "pricipal" and right = "principal" - or - wrong = "priciple" and right = "principle" - or - wrong = "priestood" and right = "priesthood" - or - wrong = "primarly" and right = "primarily" - or - wrong = "primative" and right = "primitive" - or - wrong = "primatively" and right = "primitively" - or - wrong = "primatives" and right = "primitives" - or - wrong = "primordal" and right = "primordial" - or - wrong = "principaly" and right = "principality" - or - wrong = "principial" and right = "principal" - or - wrong = "principlaity" and right = "principality" - or - wrong = "principly" and right = "principally" - or - wrong = "prinicipal" and right = "principal" - or - wrong = "privalege" and right = "privilege" - or - wrong = "privaleges" and right = "privileges" - or - wrong = "priveledges" and right = "privileges" - or - wrong = "privelege" and right = "privilege" - or - wrong = "priveleged" and right = "privileged" - or - wrong = "priveleges" and right = "privileges" - or - wrong = "privelige" and right = "privilege" - or - wrong = "priveliged" and right = "privileged" - or - wrong = "priveliges" and right = "privileges" - or - wrong = "privelleges" and right = "privileges" - or - wrong = "privilage" and right = "privilege" - or - wrong = "priviledge" and right = "privilege" - or - wrong = "priviledges" and right = "privileges" - or - wrong = "privledge" and right = "privilege" - or - wrong = "privte" and right = "private" - or - wrong = "probabilaty" and right = "probability" - or - wrong = "probablistic" and right = "probabilistic" - or - wrong = "probablly" and right = "probably" - or - wrong = "probalibity" and right = "probability" - or - wrong = "probaly" and right = "probably" - or - wrong = "probelm" and right = "problem" - or - wrong = "proccess" and right = "process" - or - wrong = "proccessing" and right = "processing" - or - wrong = "procede" and right = "precede" - or - wrong = "procede" and right = "proceed" - or - wrong = "proceded" and right = "preceded" - or - wrong = "proceded" and right = "proceeded" - or - wrong = "procedes" and right = "precedes" - or - wrong = "procedes" and right = "proceeds" - or - wrong = "procedger" and right = "procedure" - or - wrong = "proceding" and right = "preceding" - or - wrong = "proceding" and right = "proceeding" - or - wrong = "procedings" and right = "proceedings" - or - wrong = "proceedure" and right = "procedure" - or - wrong = "proces" and right = "process" - or - wrong = "procesed" and right = "processed" - or - wrong = "processer" and right = "processor" - or - wrong = "proclaimation" and right = "proclamation" - or - wrong = "proclamed" and right = "proclaimed" - or - wrong = "proclaming" and right = "proclaiming" - or - wrong = "proclomation" and right = "proclamation" - or - wrong = "profesion" and right = "profession" - or - wrong = "profesion" and right = "profusion" - or - wrong = "profesor" and right = "professor" - or - wrong = "professer" and right = "professor" - or - wrong = "proffesed" and right = "professed" - or - wrong = "proffesion" and right = "profession" - or - wrong = "proffesional" and right = "professional" - or - wrong = "proffesor" and right = "professor" - or - wrong = "profilic" and right = "prolific" - or - wrong = "progessed" and right = "progressed" - or - wrong = "progidy" and right = "prodigy" - or - wrong = "programable" and right = "programmable" - or - wrong = "progrom" and right = "pogrom" - or - wrong = "progrom" and right = "program" - or - wrong = "progroms" and right = "pogroms" - or - wrong = "progroms" and right = "programs" - or - wrong = "prohabition" and right = "prohibition" - or - wrong = "prologomena" and right = "prolegomena" - or - wrong = "prominance" and right = "prominence" - or - wrong = "prominant" and right = "prominent" - or - wrong = "prominantly" and right = "prominently" - or - wrong = "prominately" and right = "predominately" - or - wrong = "prominately" and right = "prominently" - or - wrong = "promiscous" and right = "promiscuous" - or - wrong = "promotted" and right = "promoted" - or - wrong = "pronomial" and right = "pronominal" - or - wrong = "pronouced" and right = "pronounced" - or - wrong = "pronounched" and right = "pronounced" - or - wrong = "pronounciation" and right = "pronunciation" - or - wrong = "proove" and right = "prove" - or - wrong = "prooved" and right = "proved" - or - wrong = "prophacy" and right = "prophecy" - or - wrong = "propietary" and right = "proprietary" - or - wrong = "propmted" and right = "prompted" - or - wrong = "propoganda" and right = "propaganda" - or - wrong = "propogate" and right = "propagate" - or - wrong = "propogates" and right = "propagates" - or - wrong = "propogation" and right = "propagation" - or - wrong = "propostion" and right = "proposition" - or - wrong = "propotions" and right = "proportions" - or - wrong = "propper" and right = "proper" - or - wrong = "propperly" and right = "properly" - or - wrong = "proprietory" and right = "proprietary" - or - wrong = "proseletyzing" and right = "proselytizing" - or - wrong = "protaganist" and right = "protagonist" - or - wrong = "protaganists" and right = "protagonists" - or - wrong = "protocal" and right = "protocol" - or - wrong = "protoganist" and right = "protagonist" - or - wrong = "prototpe" and right = "prototype" - or - wrong = "protoype" and right = "prototype" - or - wrong = "protrayed" and right = "portrayed" - or - wrong = "protruberance" and right = "protuberance" - or - wrong = "protruberances" and right = "protuberances" - or - wrong = "prouncements" and right = "pronouncements" - or - wrong = "provacative" and right = "provocative" - or - wrong = "provded" and right = "provided" - or - wrong = "provicial" and right = "provincial" - or - wrong = "provinicial" and right = "provincial" - or - wrong = "provisiosn" and right = "provision" - or - wrong = "provisonal" and right = "provisional" - or - wrong = "proximty" and right = "proximity" - or - wrong = "pseudononymous" and right = "pseudonymous" - or - wrong = "pseudonyn" and right = "pseudonym" - or - wrong = "psuedo" and right = "pseudo" - or - wrong = "psycology" and right = "psychology" - or - wrong = "psyhic" and right = "psychic" - or - wrong = "pubilsher" and right = "publisher" - or - wrong = "pubisher" and right = "publisher" - or - wrong = "publiaher" and right = "publisher" - or - wrong = "publically" and right = "publicly" - or - wrong = "publicaly" and right = "publicly" - or - wrong = "publicher" and right = "publisher" - or - wrong = "publihser" and right = "publisher" - or - wrong = "publisehr" and right = "publisher" - or - wrong = "publiser" and right = "publisher" - or - wrong = "publisger" and right = "publisher" - or - wrong = "publisheed" and right = "published" - or - wrong = "publisherr" and right = "publisher" - or - wrong = "publishher" and right = "publisher" - or - wrong = "publishor" and right = "publisher" - or - wrong = "publishre" and right = "publisher" - or - wrong = "publissher" and right = "publisher" - or - wrong = "publlisher" and right = "publisher" - or - wrong = "publsiher" and right = "publisher" - or - wrong = "publusher" and right = "publisher" - or - wrong = "puchasing" and right = "purchasing" - or - wrong = "pucini" and right = "puccini" - or - wrong = "pulisher" and right = "publisher" - or - wrong = "pumkin" and right = "pumpkin" - or - wrong = "puplisher" and right = "publisher" - or - wrong = "puritannical" and right = "puritanical" - or - wrong = "purposedly" and right = "purposely" - or - wrong = "purpotedly" and right = "purportedly" - or - wrong = "pursuade" and right = "persuade" - or - wrong = "pursuaded" and right = "persuaded" - or - wrong = "pursuades" and right = "persuades" - or - wrong = "pususading" and right = "persuading" - or - wrong = "puting" and right = "putting" - or - wrong = "pwoer" and right = "power" - or - wrong = "pyscic" and right = "psychic" - or - wrong = "qtuie" and right = "quiet" - or - wrong = "qtuie" and right = "quite" - or - wrong = "quantaty" and right = "quantity" - or - wrong = "quantitiy" and right = "quantity" - or - wrong = "quarantaine" and right = "quarantine" - or - wrong = "queenland" and right = "queensland" - or - wrong = "questonable" and right = "questionable" - or - wrong = "quicklyu" and right = "quickly" - or - wrong = "quinessential" and right = "quintessential" - or - wrong = "quitted" and right = "quit" - or - wrong = "quizes" and right = "quizzes" - or - wrong = "qutie" and right = "quiet" - or - wrong = "qutie" and right = "quite" - or - wrong = "rabinnical" and right = "rabbinical" - or - wrong = "racaus" and right = "raucous" - or - wrong = "radiactive" and right = "radioactive" - or - wrong = "radify" and right = "ratify" - or - wrong = "raelly" and right = "really" - or - wrong = "rarified" and right = "rarefied" - or - wrong = "reaccurring" and right = "recurring" - or - wrong = "reacing" and right = "reaching" - or - wrong = "reacll" and right = "recall" - or - wrong = "readmition" and right = "readmission" - or - wrong = "realitvely" and right = "relatively" - or - wrong = "realsitic" and right = "realistic" - or - wrong = "realtions" and right = "relations" - or - wrong = "realy" and right = "really" - or - wrong = "realyl" and right = "really" - or - wrong = "reasearch" and right = "research" - or - wrong = "rebiulding" and right = "rebuilding" - or - wrong = "rebllions" and right = "rebellions" - or - wrong = "rebounce" and right = "rebound" - or - wrong = "reccomend" and right = "recommend" - or - wrong = "reccomendations" and right = "recommendations" - or - wrong = "reccomended" and right = "recommended" - or - wrong = "reccomending" and right = "recommending" - or - wrong = "reccommend" and right = "recommend" - or - wrong = "reccommended" and right = "recommended" - or - wrong = "reccommending" and right = "recommending" - or - wrong = "reccuring" and right = "recurring" - or - wrong = "receeded" and right = "receded" - or - wrong = "receeding" and right = "receding" - or - wrong = "recepient" and right = "recipient" - or - wrong = "recepients" and right = "recipients" - or - wrong = "receving" and right = "receiving" - or - wrong = "rechargable" and right = "rechargeable" - or - wrong = "reched" and right = "reached" - or - wrong = "recide" and right = "reside" - or - wrong = "recided" and right = "resided" - or - wrong = "recident" and right = "resident" - or - wrong = "recidents" and right = "residents" - or - wrong = "reciding" and right = "residing" - or - wrong = "reciepents" and right = "recipients" - or - wrong = "reciept" and right = "receipt" - or - wrong = "recieve" and right = "receive" - or - wrong = "recieved" and right = "received" - or - wrong = "reciever" and right = "receiver" - or - wrong = "recievers" and right = "receivers" - or - wrong = "recieves" and right = "receives" - or - wrong = "recieving" and right = "receiving" - or - wrong = "recipiant" and right = "recipient" - or - wrong = "recipiants" and right = "recipients" - or - wrong = "recived" and right = "received" - or - wrong = "recivership" and right = "receivership" - or - wrong = "recogise" and right = "recognise" - or - wrong = "recogize" and right = "recognize" - or - wrong = "recomend" and right = "recommend" - or - wrong = "recomended" and right = "recommended" - or - wrong = "recomending" and right = "recommending" - or - wrong = "recomends" and right = "recommends" - or - wrong = "recommedations" and right = "recommendations" - or - wrong = "recompence" and right = "recompense" - or - wrong = "reconaissance" and right = "reconnaissance" - or - wrong = "reconcilation" and right = "reconciliation" - or - wrong = "reconized" and right = "recognized" - or - wrong = "reconnaisance" and right = "reconnaissance" - or - wrong = "reconnaissence" and right = "reconnaissance" - or - wrong = "recontructed" and right = "reconstructed" - or - wrong = "recquired" and right = "required" - or - wrong = "recrational" and right = "recreational" - or - wrong = "recrod" and right = "record" - or - wrong = "recuiting" and right = "recruiting" - or - wrong = "recuring" and right = "recurring" - or - wrong = "recurrance" and right = "recurrence" - or - wrong = "rediculous" and right = "ridiculous" - or - wrong = "reedeming" and right = "redeeming" - or - wrong = "reenforced" and right = "reinforced" - or - wrong = "refect" and right = "reflect" - or - wrong = "refedendum" and right = "referendum" - or - wrong = "referal" and right = "referral" - or - wrong = "referece" and right = "reference" - or - wrong = "refereces" and right = "references" - or - wrong = "refered" and right = "referred" - or - wrong = "referemce" and right = "reference" - or - wrong = "referemces" and right = "references" - or - wrong = "referencs" and right = "references" - or - wrong = "referenece" and right = "reference" - or - wrong = "refereneced" and right = "referenced" - or - wrong = "refereneces" and right = "references" - or - wrong = "referiang" and right = "referring" - or - wrong = "refering" and right = "referring" - or - wrong = "refernce" and right = "reference" - or - wrong = "refernce" and right = "references" - or - wrong = "refernces" and right = "references" - or - wrong = "referrence" and right = "reference" - or - wrong = "referrences" and right = "references" - or - wrong = "referrs" and right = "refers" - or - wrong = "reffered" and right = "referred" - or - wrong = "refference" and right = "reference" - or - wrong = "reffering" and right = "referring" - or - wrong = "refrence" and right = "reference" - or - wrong = "refrences" and right = "references" - or - wrong = "refrers" and right = "refers" - or - wrong = "refridgeration" and right = "refrigeration" - or - wrong = "refridgerator" and right = "refrigerator" - or - wrong = "refromist" and right = "reformist" - or - wrong = "refusla" and right = "refusal" - or - wrong = "regardes" and right = "regards" - or - wrong = "regluar" and right = "regular" - or - wrong = "reguarly" and right = "regularly" - or - wrong = "regulaion" and right = "regulation" - or - wrong = "regulaotrs" and right = "regulators" - or - wrong = "regularily" and right = "regularly" - or - wrong = "rehersal" and right = "rehearsal" - or - wrong = "reicarnation" and right = "reincarnation" - or - wrong = "reigining" and right = "reigning" - or - wrong = "reknown" and right = "renown" - or - wrong = "reknowned" and right = "renowned" - or - wrong = "rela" and right = "real" - or - wrong = "relaly" and right = "really" - or - wrong = "relatiopnship" and right = "relationship" - or - wrong = "relativly" and right = "relatively" - or - wrong = "relected" and right = "reelected" - or - wrong = "releive" and right = "relieve" - or - wrong = "releived" and right = "relieved" - or - wrong = "releiver" and right = "reliever" - or - wrong = "releses" and right = "releases" - or - wrong = "relevence" and right = "relevance" - or - wrong = "relevent" and right = "relevant" - or - wrong = "reliablity" and right = "reliability" - or - wrong = "relient" and right = "reliant" - or - wrong = "religeous" and right = "religious" - or - wrong = "religous" and right = "religious" - or - wrong = "religously" and right = "religiously" - or - wrong = "relinqushment" and right = "relinquishment" - or - wrong = "relitavely" and right = "relatively" - or - wrong = "relized" and right = "realised" - or - wrong = "relized" and right = "realized" - or - wrong = "relpacement" and right = "replacement" - or - wrong = "remaing" and right = "remaining" - or - wrong = "remeber" and right = "remember" - or - wrong = "rememberable" and right = "memorable" - or - wrong = "rememberance" and right = "remembrance" - or - wrong = "remembrence" and right = "remembrance" - or - wrong = "remenant" and right = "remnant" - or - wrong = "remenicent" and right = "reminiscent" - or - wrong = "reminent" and right = "remnant" - or - wrong = "reminescent" and right = "reminiscent" - or - wrong = "reminscent" and right = "reminiscent" - or - wrong = "reminsicent" and right = "reminiscent" - or - wrong = "rendevous" and right = "rendezvous" - or - wrong = "rendezous" and right = "rendezvous" - or - wrong = "renedered" and right = "rende" - or - wrong = "renewl" and right = "renewal" - or - wrong = "rennovate" and right = "renovate" - or - wrong = "rennovated" and right = "renovated" - or - wrong = "rennovating" and right = "renovating" - or - wrong = "rennovation" and right = "renovation" - or - wrong = "rentors" and right = "renters" - or - wrong = "reoccurrence" and right = "recurrence" - or - wrong = "reorganision" and right = "reorganisation" - or - wrong = "repatition" and right = "repartition" - or - wrong = "repatition" and right = "repetition" - or - wrong = "repblic" and right = "republic" - or - wrong = "repblican" and right = "republican" - or - wrong = "repblicans" and right = "republicans" - or - wrong = "repblics" and right = "republics" - or - wrong = "repectively" and right = "respectively" - or - wrong = "repeition" and right = "repetition" - or - wrong = "repentence" and right = "repentance" - or - wrong = "repentent" and right = "repentant" - or - wrong = "repeteadly" and right = "repeatedly" - or - wrong = "repetion" and right = "repetition" - or - wrong = "repid" and right = "rapid" - or - wrong = "reponse" and right = "response" - or - wrong = "reponsible" and right = "responsible" - or - wrong = "reportadly" and right = "reportedly" - or - wrong = "represantative" and right = "representative" - or - wrong = "representive" and right = "representative" - or - wrong = "representives" and right = "representatives" - or - wrong = "reproducable" and right = "reproducible" - or - wrong = "reprtoire" and right = "repertoire" - or - wrong = "repsectively" and right = "respectively" - or - wrong = "reptition" and right = "repetition" - or - wrong = "repubic" and right = "republic" - or - wrong = "repubican" and right = "republican" - or - wrong = "repubicans" and right = "republicans" - or - wrong = "repubics" and right = "republics" - or - wrong = "republi" and right = "republic" - or - wrong = "republian" and right = "republican" - or - wrong = "republians" and right = "republicans" - or - wrong = "republis" and right = "republics" - or - wrong = "repulic" and right = "republic" - or - wrong = "repulican" and right = "republican" - or - wrong = "repulicans" and right = "republicans" - or - wrong = "repulics" and right = "republics" - or - wrong = "requirment" and right = "requirement" - or - wrong = "requred" and right = "required" - or - wrong = "resaurant" and right = "restaurant" - or - wrong = "resembelance" and right = "resemblance" - or - wrong = "resembes" and right = "resembles" - or - wrong = "resemblence" and right = "resemblance" - or - wrong = "resevoir" and right = "reservoir" - or - wrong = "residental" and right = "residential" - or - wrong = "resignement" and right = "resignment" - or - wrong = "resistable" and right = "resistible" - or - wrong = "resistence" and right = "resistance" - or - wrong = "resistent" and right = "resistant" - or - wrong = "respectivly" and right = "respectively" - or - wrong = "responce" and right = "response" - or - wrong = "responibilities" and right = "responsibilities" - or - wrong = "responisble" and right = "responsible" - or - wrong = "responnsibilty" and right = "responsibility" - or - wrong = "responsability" and right = "responsibility" - or - wrong = "responsibile" and right = "responsible" - or - wrong = "responsibilites" and right = "responsibilities" - or - wrong = "responsiblities" and right = "responsibilities" - or - wrong = "responsiblity" and right = "responsibility" - or - wrong = "ressemblance" and right = "resemblance" - or - wrong = "ressemble" and right = "resemble" - or - wrong = "ressembled" and right = "resembled" - or - wrong = "ressemblence" and right = "resemblance" - or - wrong = "ressembling" and right = "resembling" - or - wrong = "resssurecting" and right = "resurrecting" - or - wrong = "ressurect" and right = "resurrect" - or - wrong = "ressurected" and right = "resurrected" - or - wrong = "ressurection" and right = "resurrection" - or - wrong = "ressurrection" and right = "resurrection" - or - wrong = "restarant" and right = "restaurant" - or - wrong = "restarants" and right = "restaurants" - or - wrong = "restaraunt" and right = "restaurant" - or - wrong = "restaraunteur" and right = "restaurateur" - or - wrong = "restaraunteurs" and right = "restaurateurs" - or - wrong = "restaraunts" and right = "restaurants" - or - wrong = "restauranteurs" and right = "restaurateurs" - or - wrong = "restauration" and right = "restoration" - or - wrong = "restauraunt" and right = "restaurant" - or - wrong = "resteraunt" and right = "restaurant" - or - wrong = "resteraunts" and right = "restaurants" - or - wrong = "resticted" and right = "restricted" - or - wrong = "restraunt" and right = "restaurant" - or - wrong = "restraunt" and right = "restraint" - or - wrong = "resturant" and right = "restaurant" - or - wrong = "resturants" and right = "restaurants" - or - wrong = "resturaunt" and right = "restaurant" - or - wrong = "resturaunts" and right = "restaurants" - or - wrong = "resurecting" and right = "resurrecting" - or - wrong = "retalitated" and right = "retaliated" - or - wrong = "retalitation" and right = "retaliation" - or - wrong = "retreive" and right = "retrieve" - or - wrong = "retrive" and right = "retrieve" - or - wrong = "returnd" and right = "returned" - or - wrong = "revaluated" and right = "reevaluated" - or - wrong = "reveiw" and right = "review" - or - wrong = "reveral" and right = "reversal" - or - wrong = "reversable" and right = "reversible" - or - wrong = "revolutionar" and right = "revolutionary" - or - wrong = "rewitten" and right = "rewritten" - or - wrong = "rewriet" and right = "rewrite" - or - wrong = "rference" and right = "reference" - or - wrong = "rferences" and right = "references" - or - wrong = "rhymme" and right = "rhyme" - or - wrong = "rhythem" and right = "rhythm" - or - wrong = "rhythim" and right = "rhythm" - or - wrong = "rhytmic" and right = "rhythmic" - or - wrong = "rigeur" and right = "rigor" - or - wrong = "rigeur" and right = "rigour" - or - wrong = "rigeur" and right = "rigueur" - or - wrong = "rigourous" and right = "rigorous" - or - wrong = "rininging" and right = "ringing" - or - wrong = "rised" and right = "raised" - or - wrong = "rised" and right = "rose" - or - wrong = "rockerfeller" and right = "rockefeller" - or - wrong = "rococco" and right = "rococo" - or - wrong = "rocord" and right = "record" - or - wrong = "roomate" and right = "roommate" - or - wrong = "rougly" and right = "roughly" - or - wrong = "rucuperate" and right = "recuperate" - or - wrong = "rudimentatry" and right = "rudimentary" - or - wrong = "rulle" and right = "rule" - or - wrong = "runing" and right = "running" - or - wrong = "runnung" and right = "running" - or - wrong = "russina" and right = "russian" - or - wrong = "russion" and right = "russian" - or - wrong = "rwite" and right = "write" - or - wrong = "rythem" and right = "rhythm" - or - wrong = "rythim" and right = "rhythm" - or - wrong = "rythm" and right = "rhythm" - or - wrong = "rythmic" and right = "rhythmic" - or - wrong = "rythyms" and right = "rhythms" - or - wrong = "sacrafice" and right = "sacrifice" - or - wrong = "sacreligious" and right = "sacrilegious" - or - wrong = "sacremento" and right = "sacramento" - or - wrong = "sacrifical" and right = "sacrificial" - or - wrong = "saftey" and right = "safety" - or - wrong = "safty" and right = "safety" - or - wrong = "salery" and right = "salary" - or - wrong = "sanctionning" and right = "sanctioning" - or - wrong = "sandwhich" and right = "sandwich" - or - wrong = "sanhedrim" and right = "sanhedrin" - or - wrong = "santioned" and right = "sanctioned" - or - wrong = "sargant" and right = "sergeant" - or - wrong = "sargeant" and right = "sergeant" - or - wrong = "sasy" and right = "sassy" - or - wrong = "sasy" and right = "says" - or - wrong = "satelite" and right = "satellite" - or - wrong = "satelites" and right = "satellites" - or - wrong = "saterday" and right = "saturday" - or - wrong = "saterdays" and right = "saturdays" - or - wrong = "satisfactority" and right = "satisfactorily" - or - wrong = "satric" and right = "satiric" - or - wrong = "satrical" and right = "satirical" - or - wrong = "satrically" and right = "satirically" - or - wrong = "sattelite" and right = "satellite" - or - wrong = "sattelites" and right = "satellites" - or - wrong = "saught" and right = "sought" - or - wrong = "saveing" and right = "saving" - or - wrong = "saxaphone" and right = "saxophone" - or - wrong = "scaleable" and right = "scalable" - or - wrong = "scandanavia" and right = "scandinavia" - or - wrong = "scaricity" and right = "scarcity" - or - wrong = "scavanged" and right = "scavenged" - or - wrong = "schedual" and right = "schedule" - or - wrong = "scholarhip" and right = "scholarship" - or - wrong = "scholarstic" and right = "scholarly" - or - wrong = "scholarstic" and right = "scholastic" - or - wrong = "scientfic" and right = "scientific" - or - wrong = "scientifc" and right = "scientific" - or - wrong = "scientis" and right = "scientist" - or - wrong = "scince" and right = "science" - or - wrong = "scinece" and right = "science" - or - wrong = "scirpt" and right = "script" - or - wrong = "scoll" and right = "scroll" - or - wrong = "screenwrighter" and right = "screenwriter" - or - wrong = "scrutinity" and right = "scrutiny" - or - wrong = "scuptures" and right = "sculptures" - or - wrong = "seach" and right = "search" - or - wrong = "seached" and right = "searched" - or - wrong = "seaches" and right = "searches" - or - wrong = "secceeded" and right = "seceded" - or - wrong = "secceeded" and right = "succeeded" - or - wrong = "seceed" and right = "secede" - or - wrong = "seceed" and right = "succeed" - or - wrong = "seceeded" and right = "seceded" - or - wrong = "seceeded" and right = "succeeded" - or - wrong = "secratary" and right = "secretary" - or - wrong = "secretery" and right = "secretary" - or - wrong = "sedereal" and right = "sidereal" - or - wrong = "seeked" and right = "sought" - or - wrong = "segementation" and right = "segmentation" - or - wrong = "seguoys" and right = "segues" - or - wrong = "seige" and right = "siege" - or - wrong = "seing" and right = "seeing" - or - wrong = "seinor" and right = "senior" - or - wrong = "seldomly" and right = "seldom" - or - wrong = "senarios" and right = "scenarios" - or - wrong = "sence" and right = "sense" - or - wrong = "sence" and right = "since" - or - wrong = "senstive" and right = "sensitive" - or - wrong = "sensure" and right = "censure" - or - wrong = "seperate" and right = "separate" - or - wrong = "seperated" and right = "separated" - or - wrong = "seperately" and right = "separately" - or - wrong = "seperates" and right = "separates" - or - wrong = "seperating" and right = "separating" - or - wrong = "seperation" and right = "separation" - or - wrong = "seperatism" and right = "separatism" - or - wrong = "seperatist" and right = "separatist" - or - wrong = "seperator" and right = "separator" - or - wrong = "sepina" and right = "subpoena" - or - wrong = "sepulchure" and right = "sepulcher" - or - wrong = "sepulchure" and right = "sepulchre" - or - wrong = "sepulcre" and right = "sepulcher" - or - wrong = "sepulcre" and right = "sepulchre" - or - wrong = "sergent" and right = "sergeant" - or - wrong = "settelement" and right = "settlement" - or - wrong = "settlment" and right = "settlement" - or - wrong = "settting" and right = "setting" - or - wrong = "severeal" and right = "several" - or - wrong = "severley" and right = "severely" - or - wrong = "severly" and right = "severely" - or - wrong = "sevice" and right = "service" - or - wrong = "shadasloo" and right = "shadaloo" - or - wrong = "shaddow" and right = "shadow" - or - wrong = "shadoloo" and right = "shadaloo" - or - wrong = "shamen" and right = "shaman" - or - wrong = "shamen" and right = "shamans" - or - wrong = "sheat" and right = "cheat" - or - wrong = "sheat" and right = "sheath" - or - wrong = "sheat" and right = "sheet" - or - wrong = "sheild" and right = "shield" - or - wrong = "sherif" and right = "sheriff" - or - wrong = "shineing" and right = "shining" - or - wrong = "shiped" and right = "shipped" - or - wrong = "shiping" and right = "shipping" - or - wrong = "shopkeeepers" and right = "shopkeepers" - or - wrong = "shorly" and right = "shortly" - or - wrong = "shoudl" and right = "should" - or - wrong = "shoudln" and right = "should" - or - wrong = "shreak" and right = "shriek" - or - wrong = "shrinked" and right = "shrunk" - or - wrong = "sicne" and right = "since" - or - wrong = "sideral" and right = "sidereal" - or - wrong = "sieze" and right = "seize" - or - wrong = "sieze" and right = "size" - or - wrong = "siezed" and right = "seized" - or - wrong = "siezed" and right = "sized" - or - wrong = "siezing" and right = "seizing" - or - wrong = "siezing" and right = "sizing" - or - wrong = "siezure" and right = "seizure" - or - wrong = "siezures" and right = "seizures" - or - wrong = "siginificant" and right = "significant" - or - wrong = "signficant" and right = "significant" - or - wrong = "signficiant" and right = "significant" - or - wrong = "signfies" and right = "signifies" - or - wrong = "signifantly" and right = "significantly" - or - wrong = "significently" and right = "significantly" - or - wrong = "signifigant" and right = "significant" - or - wrong = "signifigantly" and right = "significantly" - or - wrong = "signitories" and right = "signatories" - or - wrong = "signitory" and right = "signatory" - or - wrong = "similarily" and right = "similarly" - or - wrong = "similiar" and right = "similar" - or - wrong = "similiarity" and right = "similarity" - or - wrong = "similiarly" and right = "similarly" - or - wrong = "simmilar" and right = "similar" - or - wrong = "simpley" and right = "simply" - or - wrong = "simplier" and right = "simpler" - or - wrong = "simultanous" and right = "simultaneous" - or - wrong = "simultanously" and right = "simultaneously" - or - wrong = "sincerley" and right = "sincerely" - or - wrong = "singsog" and right = "singsong" - or - wrong = "sinse" and right = "since" - or - wrong = "sinse" and right = "sines" - or - wrong = "sionist" and right = "zionist" - or - wrong = "sionists" and right = "zionists" - or - wrong = "sixtin" and right = "sistine" - or - wrong = "skagerak" and right = "skagerrak" - or - wrong = "skateing" and right = "skating" - or - wrong = "slaugterhouses" and right = "slaughterhouses" - or - wrong = "slighly" and right = "slightly" - or - wrong = "slippy" and right = "slippery" - or - wrong = "slowy" and right = "slowly" - or - wrong = "smae" and right = "same" - or - wrong = "smealting" and right = "smelting" - or - wrong = "smoe" and right = "some" - or - wrong = "sneeks" and right = "sneaks" - or - wrong = "snese" and right = "sneeze" - or - wrong = "socalism" and right = "socialism" - or - wrong = "socities" and right = "societies" - or - wrong = "soem" and right = "some" - or - wrong = "sofware" and right = "software" - or - wrong = "sohw" and right = "show" - or - wrong = "soilders" and right = "soldiers" - or - wrong = "solatary" and right = "solitary" - or - wrong = "soley" and right = "solely" - or - wrong = "soliders" and right = "soldiers" - or - wrong = "soliliquy" and right = "soliloquy" - or - wrong = "soluable" and right = "soluble" - or - wrong = "somene" and right = "someone" - or - wrong = "somtimes" and right = "sometimes" - or - wrong = "somwhere" and right = "somewhere" - or - wrong = "sophicated" and right = "sophisticated" - or - wrong = "sophmore" and right = "sophomore" - or - wrong = "sorceror" and right = "sorcerer" - or - wrong = "sorrounding" and right = "surrounding" - or - wrong = "sotry" and right = "story" - or - wrong = "sotyr" and right = "satyr" - or - wrong = "sotyr" and right = "story" - or - wrong = "soudn" and right = "sound" - or - wrong = "soudns" and right = "sounds" - or - wrong = "sould" and right = "could" - or - wrong = "sould" and right = "should" - or - wrong = "sould" and right = "sold" - or - wrong = "sould" and right = "soul" - or - wrong = "sountrack" and right = "soundtrack" - or - wrong = "sourth" and right = "south" - or - wrong = "sourthern" and right = "southern" - or - wrong = "souvenier" and right = "souvenir" - or - wrong = "souveniers" and right = "souvenirs" - or - wrong = "soveits" and right = "soviets" - or - wrong = "sovereignity" and right = "sovereignty" - or - wrong = "soverign" and right = "sovereign" - or - wrong = "soverignity" and right = "sovereignty" - or - wrong = "soverignty" and right = "sovereignty" - or - wrong = "spainish" and right = "spanish" - or - wrong = "speach" and right = "speech" - or - wrong = "specfic" and right = "specific" - or - wrong = "speciallized" and right = "specialised" - or - wrong = "speciallized" and right = "specialized" - or - wrong = "specif" and right = "specific" - or - wrong = "specif" and right = "specify" - or - wrong = "specifiying" and right = "specifying" - or - wrong = "speciman" and right = "specimen" - or - wrong = "spectauclar" and right = "spectacular" - or - wrong = "spectaulars" and right = "spectaculars" - or - wrong = "spects" and right = "aspects" - or - wrong = "spects" and right = "expects" - or - wrong = "spectum" and right = "spectrum" - or - wrong = "speices" and right = "species" - or - wrong = "spendour" and right = "splendour" - or - wrong = "spermatozoan" and right = "spermatozoon" - or - wrong = "spoace" and right = "space" - or - wrong = "sponser" and right = "sponsor" - or - wrong = "sponsered" and right = "sponsored" - or - wrong = "spontanous" and right = "spontaneous" - or - wrong = "sponzored" and right = "sponsored" - or - wrong = "spoonfulls" and right = "spoonfuls" - or - wrong = "sppeches" and right = "speeches" - or - wrong = "spreaded" and right = "spread" - or - wrong = "sprech" and right = "speech" - or - wrong = "spred" and right = "spread" - or - wrong = "spriritual" and right = "spiritual" - or - wrong = "spritual" and right = "spiritual" - or - wrong = "sqaure" and right = "square" - or - wrong = "sring" and right = "string" - or - wrong = "stablility" and right = "stability" - or - wrong = "stainlees" and right = "stainless" - or - wrong = "staion" and right = "station" - or - wrong = "standars" and right = "standards" - or - wrong = "stange" and right = "strange" - or - wrong = "startegic" and right = "strategic" - or - wrong = "startegies" and right = "strategies" - or - wrong = "startegy" and right = "strategy" - or - wrong = "stateman" and right = "statesman" - or - wrong = "statememts" and right = "statements" - or - wrong = "statment" and right = "statement" - or - wrong = "steriods" and right = "steroids" - or - wrong = "sterotypes" and right = "stereotypes" - or - wrong = "stilus" and right = "stylus" - or - wrong = "stingent" and right = "stringent" - or - wrong = "stiring" and right = "stirring" - or - wrong = "stirrs" and right = "stirs" - or - wrong = "stlye" and right = "style" - or - wrong = "stomache" and right = "stomach" - or - wrong = "stong" and right = "strong" - or - wrong = "stopry" and right = "story" - or - wrong = "storeis" and right = "stories" - or - wrong = "storise" and right = "stories" - or - wrong = "stornegst" and right = "strongest" - or - wrong = "stoyr" and right = "story" - or - wrong = "stpo" and right = "stop" - or - wrong = "stradegies" and right = "strategies" - or - wrong = "stradegy" and right = "strategy" - or - wrong = "strat" and right = "start" - or - wrong = "strat" and right = "strata" - or - wrong = "stratagically" and right = "strategically" - or - wrong = "streemlining" and right = "streamlining" - or - wrong = "stregth" and right = "strength" - or - wrong = "strenghen" and right = "strengthen" - or - wrong = "strenghened" and right = "strengthened" - or - wrong = "strenghening" and right = "strengthening" - or - wrong = "strenght" and right = "strength" - or - wrong = "strenghten" and right = "strengthen" - or - wrong = "strenghtened" and right = "strengthened" - or - wrong = "strenghtening" and right = "strengthening" - or - wrong = "strengtened" and right = "strengthened" - or - wrong = "strenous" and right = "strenuous" - or - wrong = "strictist" and right = "strictest" - or - wrong = "strikely" and right = "strikingly" - or - wrong = "strnad" and right = "strand" - or - wrong = "stroy" and right = "destroy" - or - wrong = "stroy" and right = "story" - or - wrong = "structual" and right = "structural" - or - wrong = "stubborness" and right = "stubbornness" - or - wrong = "stucture" and right = "structure" - or - wrong = "stuctured" and right = "structured" - or - wrong = "studdy" and right = "study" - or - wrong = "studing" and right = "studying" - or - wrong = "stuggling" and right = "struggling" - or - wrong = "sturcture" and right = "structure" - or - wrong = "subcatagories" and right = "subcategories" - or - wrong = "subcatagory" and right = "subcategory" - or - wrong = "subconsiously" and right = "subconsciously" - or - wrong = "subjudgation" and right = "subjugation" - or - wrong = "submachne" and right = "submachine" - or - wrong = "subpecies" and right = "subspecies" - or - wrong = "subsidary" and right = "subsidiary" - or - wrong = "subsiduary" and right = "subsidiary" - or - wrong = "subsquent" and right = "subsequent" - or - wrong = "subsquently" and right = "subsequently" - or - wrong = "substace" and right = "substance" - or - wrong = "substancial" and right = "substantial" - or - wrong = "substatial" and right = "substantial" - or - wrong = "substituded" and right = "substituted" - or - wrong = "substract" and right = "subtract" - or - wrong = "substracted" and right = "subtracted" - or - wrong = "substracting" and right = "subtracting" - or - wrong = "substraction" and right = "subtraction" - or - wrong = "substracts" and right = "subtracts" - or - wrong = "subtances" and right = "substances" - or - wrong = "subterranian" and right = "subterranean" - or - wrong = "suburburban" and right = "suburban" - or - wrong = "succceeded" and right = "succeeded" - or - wrong = "succcesses" and right = "successes" - or - wrong = "succedded" and right = "succeeded" - or - wrong = "succeded" and right = "succeeded" - or - wrong = "succeds" and right = "succeeds" - or - wrong = "succesful" and right = "successful" - or - wrong = "succesfully" and right = "successfully" - or - wrong = "succesfuly" and right = "successfully" - or - wrong = "succesion" and right = "succession" - or - wrong = "succesive" and right = "successive" - or - wrong = "successfull" and right = "successful" - or - wrong = "successully" and right = "successfully" - or - wrong = "succsess" and right = "success" - or - wrong = "succsessfull" and right = "successful" - or - wrong = "suceed" and right = "succeed" - or - wrong = "suceeded" and right = "succeeded" - or - wrong = "suceeding" and right = "succeeding" - or - wrong = "suceeds" and right = "succeeds" - or - wrong = "sucesful" and right = "successful" - or - wrong = "sucesfully" and right = "successfully" - or - wrong = "sucesfuly" and right = "successfully" - or - wrong = "sucesion" and right = "succession" - or - wrong = "sucess" and right = "success" - or - wrong = "sucesses" and right = "successes" - or - wrong = "sucessful" and right = "successful" - or - wrong = "sucessfull" and right = "successful" - or - wrong = "sucessfully" and right = "successfully" - or - wrong = "sucessfuly" and right = "successfully" - or - wrong = "sucession" and right = "succession" - or - wrong = "sucessive" and right = "successive" - or - wrong = "sucessor" and right = "successor" - or - wrong = "sucessot" and right = "successor" - or - wrong = "sucide" and right = "suicide" - or - wrong = "sucidial" and right = "suicidal" - or - wrong = "sudent" and right = "student" - or - wrong = "sudents" and right = "students" - or - wrong = "sufferage" and right = "suffrage" - or - wrong = "sufferred" and right = "suffered" - or - wrong = "sufferring" and right = "suffering" - or - wrong = "sufficent" and right = "sufficient" - or - wrong = "sufficently" and right = "sufficiently" - or - wrong = "sumary" and right = "summary" - or - wrong = "sunglases" and right = "sunglasses" - or - wrong = "suop" and right = "soup" - or - wrong = "superceeded" and right = "superseded" - or - wrong = "superintendant" and right = "superintendent" - or - wrong = "suphisticated" and right = "sophisticated" - or - wrong = "suplimented" and right = "supplemented" - or - wrong = "suported" and right = "supported" - or - wrong = "supose" and right = "suppose" - or - wrong = "suposed" and right = "supposed" - or - wrong = "suposedly" and right = "supposedly" - or - wrong = "suposes" and right = "supposes" - or - wrong = "suposing" and right = "supposing" - or - wrong = "supplamented" and right = "supplemented" - or - wrong = "suppliementing" and right = "supplementing" - or - wrong = "suppoed" and right = "supposed" - or - wrong = "supposingly" and right = "supposedly" - or - wrong = "suppy" and right = "supply" - or - wrong = "suprassing" and right = "surpassing" - or - wrong = "supress" and right = "suppress" - or - wrong = "supressed" and right = "suppressed" - or - wrong = "supresses" and right = "suppresses" - or - wrong = "supressing" and right = "suppressing" - or - wrong = "suprise" and right = "surprise" - or - wrong = "suprised" and right = "surprised" - or - wrong = "suprising" and right = "surprising" - or - wrong = "suprisingly" and right = "surprisingly" - or - wrong = "suprize" and right = "surprise" - or - wrong = "suprized" and right = "surprised" - or - wrong = "suprizing" and right = "surprising" - or - wrong = "suprizingly" and right = "surprisingly" - or - wrong = "surfce" and right = "surface" - or - wrong = "surley" and right = "surely" - or - wrong = "surley" and right = "surly" - or - wrong = "suround" and right = "surround" - or - wrong = "surounded" and right = "surrounded" - or - wrong = "surounding" and right = "surrounding" - or - wrong = "suroundings" and right = "surroundings" - or - wrong = "surounds" and right = "surrounds" - or - wrong = "surplanted" and right = "supplanted" - or - wrong = "surpress" and right = "suppress" - or - wrong = "surpressed" and right = "suppressed" - or - wrong = "surprize" and right = "surprise" - or - wrong = "surprized" and right = "surprised" - or - wrong = "surprizing" and right = "surprising" - or - wrong = "surprizingly" and right = "surprisingly" - or - wrong = "surrended" and right = "surrendered" - or - wrong = "surrended" and right = "surrounded" - or - wrong = "surrepetitious" and right = "surreptitious" - or - wrong = "surrepetitiously" and right = "surreptitiously" - or - wrong = "surreptious" and right = "surreptitious" - or - wrong = "surreptiously" and right = "surreptitiously" - or - wrong = "surronded" and right = "surrounded" - or - wrong = "surrouded" and right = "surrounded" - or - wrong = "surrouding" and right = "surrounding" - or - wrong = "surrundering" and right = "surrendering" - or - wrong = "surveilence" and right = "surveillance" - or - wrong = "surveill" and right = "surveil" - or - wrong = "surveyer" and right = "surveyor" - or - wrong = "surviver" and right = "survivor" - or - wrong = "survivers" and right = "survivors" - or - wrong = "survivied" and right = "survived" - or - wrong = "suseptable" and right = "susceptible" - or - wrong = "suseptible" and right = "susceptible" - or - wrong = "suspention" and right = "suspension" - or - wrong = "swaer" and right = "swear" - or - wrong = "swaers" and right = "swears" - or - wrong = "swepth" and right = "swept" - or - wrong = "swiming" and right = "swimming" - or - wrong = "syas" and right = "says" - or - wrong = "symetrical" and right = "symmetrical" - or - wrong = "symetrically" and right = "symmetrically" - or - wrong = "symetry" and right = "symmetry" - or - wrong = "symettric" and right = "symmetric" - or - wrong = "symmetral" and right = "symmetric" - or - wrong = "symmetricaly" and right = "symmetrically" - or - wrong = "synagouge" and right = "synagogue" - or - wrong = "syncronization" and right = "synchronization" - or - wrong = "synonomous" and right = "synonymous" - or - wrong = "synonymns" and right = "synonyms" - or - wrong = "synphony" and right = "symphony" - or - wrong = "syphyllis" and right = "syphilis" - or - wrong = "sypmtoms" and right = "symptoms" - or - wrong = "syrap" and right = "syrup" - or - wrong = "sysmatically" and right = "systematically" - or - wrong = "sytem" and right = "system" - or - wrong = "sytle" and right = "style" - or - wrong = "tabacco" and right = "tobacco" - or - wrong = "tahn" and right = "than" - or - wrong = "taht" and right = "that" - or - wrong = "talekd" and right = "talked" - or - wrong = "targetted" and right = "targeted" - or - wrong = "targetting" and right = "targeting" - or - wrong = "tast" and right = "taste" - or - wrong = "tath" and right = "that" - or - wrong = "tatoo" and right = "tattoo" - or - wrong = "tattooes" and right = "tattoos" - or - wrong = "taxanomic" and right = "taxonomic" - or - wrong = "taxanomy" and right = "taxonomy" - or - wrong = "teached" and right = "taught" - or - wrong = "techician" and right = "technician" - or - wrong = "techicians" and right = "technicians" - or - wrong = "techiniques" and right = "techniques" - or - wrong = "technitian" and right = "technician" - or - wrong = "technnology" and right = "technology" - or - wrong = "technolgy" and right = "technology" - or - wrong = "teh" and right = "the" - or - wrong = "tehy" and right = "they" - or - wrong = "telelevision" and right = "television" - or - wrong = "televsion" and right = "television" - or - wrong = "telphony" and right = "telephony" - or - wrong = "temerature" and right = "temperature" - or - wrong = "tempalte" and right = "template" - or - wrong = "tempaltes" and right = "templates" - or - wrong = "temparate" and right = "temperate" - or - wrong = "temperarily" and right = "temporarily" - or - wrong = "temperment" and right = "temperament" - or - wrong = "tempertaure" and right = "temperature" - or - wrong = "temperture" and right = "temperature" - or - wrong = "temprary" and right = "temporary" - or - wrong = "tenacle" and right = "tentacle" - or - wrong = "tenacles" and right = "tentacles" - or - wrong = "tendacy" and right = "tendency" - or - wrong = "tendancies" and right = "tendencies" - or - wrong = "tendancy" and right = "tendency" - or - wrong = "tepmorarily" and right = "temporarily" - or - wrong = "terrestial" and right = "terrestrial" - or - wrong = "terriories" and right = "territories" - or - wrong = "terriory" and right = "territory" - or - wrong = "territorist" and right = "terrorist" - or - wrong = "territoy" and right = "territory" - or - wrong = "terroist" and right = "terrorist" - or - wrong = "testiclular" and right = "testicular" - or - wrong = "testomony" and right = "testimony" - or - wrong = "tghe" and right = "the" - or - wrong = "thast" and right = "that" - or - wrong = "theather" and right = "theater" - or - wrong = "theese" and right = "these" - or - wrong = "theif" and right = "thief" - or - wrong = "theives" and right = "thieves" - or - wrong = "themselfs" and right = "themselves" - or - wrong = "themslves" and right = "themselves" - or - wrong = "ther" and right = "the" - or - wrong = "ther" and right = "their" - or - wrong = "ther" and right = "there" - or - wrong = "therafter" and right = "thereafter" - or - wrong = "therby" and right = "thereby" - or - wrong = "theri" and right = "their" - or - wrong = "thgat" and right = "that" - or - wrong = "thge" and right = "the" - or - wrong = "thier" and right = "their" - or - wrong = "thign" and right = "thing" - or - wrong = "thigns" and right = "things" - or - wrong = "thigsn" and right = "things" - or - wrong = "thikn" and right = "think" - or - wrong = "thikning" and right = "thickening" - or - wrong = "thikning" and right = "thinking" - or - wrong = "thikns" and right = "thinks" - or - wrong = "thiunk" and right = "think" - or - wrong = "thn" and right = "then" - or - wrong = "thna" and right = "than" - or - wrong = "thne" and right = "then" - or - wrong = "thnig" and right = "thing" - or - wrong = "thnigs" and right = "things" - or - wrong = "thoughout" and right = "throughout" - or - wrong = "threatend" and right = "threatened" - or - wrong = "threatning" and right = "threatening" - or - wrong = "threee" and right = "three" - or - wrong = "threshhold" and right = "threshold" - or - wrong = "thrid" and right = "third" - or - wrong = "throrough" and right = "thorough" - or - wrong = "throughly" and right = "thoroughly" - or - wrong = "throught" and right = "thought" - or - wrong = "throught" and right = "through" - or - wrong = "throught" and right = "throughout" - or - wrong = "througout" and right = "throughout" - or - wrong = "thru" and right = "through" - or - wrong = "thsi" and right = "this" - or - wrong = "thsoe" and right = "those" - or - wrong = "thta" and right = "that" - or - wrong = "thyat" and right = "that" - or - wrong = "tiem" and right = "tim" - or - wrong = "tiem" and right = "time" - or - wrong = "tihkn" and right = "think" - or - wrong = "tihs" and right = "this" - or - wrong = "timne" and right = "time" - or - wrong = "tiome" and right = "time" - or - wrong = "tiome" and right = "tome" - or - wrong = "tje" and right = "the" - or - wrong = "tjhe" and right = "the" - or - wrong = "tjpanishad" and right = "upanishad" - or - wrong = "tkae" and right = "take" - or - wrong = "tkaes" and right = "takes" - or - wrong = "tkaing" and right = "taking" - or - wrong = "tlaking" and right = "talking" - or - wrong = "tobbaco" and right = "tobacco" - or - wrong = "todya" and right = "today" - or - wrong = "toghether" and right = "together" - or - wrong = "toke" and right = "took" - or - wrong = "tolerence" and right = "tolerance" - or - wrong = "tolkein" and right = "tolkien" - or - wrong = "tomatos" and right = "tomatoes" - or - wrong = "tommorow" and right = "tomorrow" - or - wrong = "tommorrow" and right = "tomorrow" - or - wrong = "tongiht" and right = "tonight" - or - wrong = "toriodal" and right = "toroidal" - or - wrong = "tormenters" and right = "tormentors" - or - wrong = "tornadoe" and right = "tornado" - or - wrong = "torpeados" and right = "torpedoes" - or - wrong = "torpedos" and right = "torpedoes" - or - wrong = "tortise" and right = "tortoise" - or - wrong = "toubles" and right = "troubles" - or - wrong = "tounge" and right = "tongue" - or - wrong = "tourch" and right = "torch" - or - wrong = "tourch" and right = "touch" - or - wrong = "towords" and right = "towards" - or - wrong = "towrad" and right = "toward" - or - wrong = "tradionally" and right = "traditionally" - or - wrong = "traditionaly" and right = "traditionally" - or - wrong = "traditionnal" and right = "traditional" - or - wrong = "traditition" and right = "tradition" - or - wrong = "tradtionally" and right = "traditionally" - or - wrong = "trafficed" and right = "trafficked" - or - wrong = "trafficing" and right = "trafficking" - or - wrong = "trafic" and right = "traffic" - or - wrong = "trancendent" and right = "transcendent" - or - wrong = "trancending" and right = "transcending" - or - wrong = "tranform" and right = "transform" - or - wrong = "tranformed" and right = "transformed" - or - wrong = "transcendance" and right = "transcendence" - or - wrong = "transcendant" and right = "transcendent" - or - wrong = "transcendentational" and right = "transcendental" - or - wrong = "transcripting" and right = "transcribing" - or - wrong = "transcripting" and right = "transcription" - or - wrong = "transending" and right = "transcending" - or - wrong = "transesxuals" and right = "transsexuals" - or - wrong = "transfered" and right = "transferred" - or - wrong = "transfering" and right = "transferring" - or - wrong = "transformaton" and right = "transformation" - or - wrong = "transistion" and right = "transition" - or - wrong = "translater" and right = "translator" - or - wrong = "translaters" and right = "translators" - or - wrong = "transmissable" and right = "transmissible" - or - wrong = "transporation" and right = "transportation" - or - wrong = "tremelo" and right = "tremolo" - or - wrong = "tremelos" and right = "tremolos" - or - wrong = "treshold" and right = "threshold" - or - wrong = "triguered" and right = "triggered" - or - wrong = "triology" and right = "trilogy" - or - wrong = "troling" and right = "trolling" - or - wrong = "troup" and right = "troupe" - or - wrong = "troups" and right = "troops" - or - wrong = "troups" and right = "troupes" - or - wrong = "truely" and right = "truly" - or - wrong = "trustworthyness" and right = "trustworthiness" - or - wrong = "turnk" and right = "trunk" - or - wrong = "turnk" and right = "turnkey" - or - wrong = "tuscon" and right = "tucson" - or - wrong = "tust" and right = "trust" - or - wrong = "twelth" and right = "twelfth" - or - wrong = "twon" and right = "town" - or - wrong = "twpo" and right = "two" - or - wrong = "tyhat" and right = "that" - or - wrong = "tyhe" and right = "they" - or - wrong = "typcial" and right = "typical" - or - wrong = "typicaly" and right = "typically" - or - wrong = "tyranies" and right = "tyrannies" - or - wrong = "tyrany" and right = "tyranny" - or - wrong = "tyrranies" and right = "tyrannies" - or - wrong = "tyrrany" and right = "tyranny" - or - wrong = "ubiquitious" and right = "ubiquitous" - or - wrong = "ublisher" and right = "publisher" - or - wrong = "udpate" and right = "update" - or - wrong = "uise" and right = "use" - or - wrong = "ukranian" and right = "ukrainian" - or - wrong = "ultimely" and right = "ultimately" - or - wrong = "unacompanied" and right = "unaccompanied" - or - wrong = "unahppy" and right = "unhappy" - or - wrong = "unanymous" and right = "unanimous" - or - wrong = "unathorised" and right = "unauthorised" - or - wrong = "unavailible" and right = "unavailable" - or - wrong = "unballance" and right = "unbalance" - or - wrong = "unbeknowst" and right = "unbeknownst" - or - wrong = "unbeleivable" and right = "unbelievable" - or - wrong = "uncertainity" and right = "uncertainty" - or - wrong = "unchallengable" and right = "unchallengeable" - or - wrong = "unchangable" and right = "unchangeable" - or - wrong = "uncompetive" and right = "uncompetitive" - or - wrong = "unconcious" and right = "unconscious" - or - wrong = "unconciousness" and right = "unconsciousness" - or - wrong = "unconfortability" and right = "discomfort" - or - wrong = "uncontitutional" and right = "unconstitutional" - or - wrong = "unconvential" and right = "unconventional" - or - wrong = "undecideable" and right = "undecidable" - or - wrong = "understoon" and right = "understood" - or - wrong = "undesireable" and right = "undesirable" - or - wrong = "undetecable" and right = "undetectable" - or - wrong = "undoubtely" and right = "undoubtedly" - or - wrong = "undreground" and right = "underground" - or - wrong = "uneccesary" and right = "unnecessary" - or - wrong = "unecessary" and right = "unnecessary" - or - wrong = "unequalities" and right = "inequalities" - or - wrong = "unforetunately" and right = "unfortunately" - or - wrong = "unforgetable" and right = "unforgettable" - or - wrong = "unforgiveable" and right = "unforgivable" - or - wrong = "unforseen" and right = "unforeseen" - or - wrong = "unfortunatley" and right = "unfortunately" - or - wrong = "unfortunatly" and right = "unfortunately" - or - wrong = "unfourtunately" and right = "unfortunately" - or - wrong = "unihabited" and right = "uninhabited" - or - wrong = "unilateraly" and right = "unilaterally" - or - wrong = "unilatreal" and right = "unilateral" - or - wrong = "unilatreally" and right = "unilaterally" - or - wrong = "uninterruped" and right = "uninterrupted" - or - wrong = "uninterupted" and right = "uninterrupted" - or - wrong = "unintialized" and right = "uninitialized" - or - wrong = "unitesstates" and right = "unitedstates" - or - wrong = "univeral" and right = "universal" - or - wrong = "univeristies" and right = "universities" - or - wrong = "univeristy" and right = "university" - or - wrong = "univerity" and right = "university" - or - wrong = "universtiy" and right = "university" - or - wrong = "univesities" and right = "universities" - or - wrong = "univesity" and right = "university" - or - wrong = "unkown" and right = "unknown" - or - wrong = "unlikey" and right = "unlikely" - or - wrong = "unmanouverable" and right = "unmaneuverable" - or - wrong = "unmanouverable" and right = "unmanoeuvrable" - or - wrong = "unmistakeably" and right = "unmistakably" - or - wrong = "unneccesarily" and right = "unnecessarily" - or - wrong = "unneccesary" and right = "unnecessary" - or - wrong = "unneccessarily" and right = "unnecessarily" - or - wrong = "unneccessary" and right = "unnecessary" - or - wrong = "unnecesarily" and right = "unnecessarily" - or - wrong = "unnecesary" and right = "unnecessary" - or - wrong = "unoffical" and right = "unofficial" - or - wrong = "unoperational" and right = "nonoperational" - or - wrong = "unoticeable" and right = "unnoticeable" - or - wrong = "unplease" and right = "displease" - or - wrong = "unplesant" and right = "unpleasant" - or - wrong = "unprecendented" and right = "unprecedented" - or - wrong = "unprecidented" and right = "unprecedented" - or - wrong = "unrepentent" and right = "unrepentant" - or - wrong = "unrepetant" and right = "unrepentant" - or - wrong = "unrepetent" and right = "unrepentant" - or - wrong = "unsed" and right = "unsaid" - or - wrong = "unsed" and right = "unused" - or - wrong = "unsed" and right = "used" - or - wrong = "unsubstanciated" and right = "unsubstantiated" - or - wrong = "unsuccesful" and right = "unsuccessful" - or - wrong = "unsuccesfully" and right = "unsuccessfully" - or - wrong = "unsuccessfull" and right = "unsuccessful" - or - wrong = "unsucesful" and right = "unsuccessful" - or - wrong = "unsucesfuly" and right = "unsuccessfully" - or - wrong = "unsucessful" and right = "unsuccessful" - or - wrong = "unsucessfull" and right = "unsuccessful" - or - wrong = "unsucessfully" and right = "unsuccessfully" - or - wrong = "unsuprised" and right = "unsurprised" - or - wrong = "unsuprising" and right = "unsurprising" - or - wrong = "unsuprisingly" and right = "unsurprisingly" - or - wrong = "unsuprized" and right = "unsurprised" - or - wrong = "unsuprizing" and right = "unsurprising" - or - wrong = "unsuprizingly" and right = "unsurprisingly" - or - wrong = "unsurprized" and right = "unsurprised" - or - wrong = "unsurprizing" and right = "unsurprising" - or - wrong = "unsurprizingly" and right = "unsurprisingly" - or - wrong = "untill" and right = "until" - or - wrong = "untranslateable" and right = "untranslatable" - or - wrong = "unuseable" and right = "unusable" - or - wrong = "unusuable" and right = "unusable" - or - wrong = "unviersity" and right = "university" - or - wrong = "unwarrented" and right = "unwarranted" - or - wrong = "unweildly" and right = "unwieldy" - or - wrong = "unwieldly" and right = "unwieldy" - or - wrong = "upcomming" and right = "upcoming" - or - wrong = "upgradded" and right = "upgraded" - or - wrong = "usally" and right = "usually" - or - wrong = "useage" and right = "usage" - or - wrong = "usefull" and right = "useful" - or - wrong = "usefuly" and right = "usefully" - or - wrong = "useing" and right = "using" - or - wrong = "usualy" and right = "usually" - or - wrong = "ususally" and right = "usually" - or - wrong = "vaccum" and right = "vacuum" - or - wrong = "vaccume" and right = "vacuum" - or - wrong = "vacinity" and right = "vicinity" - or - wrong = "vaguaries" and right = "vagaries" - or - wrong = "vaieties" and right = "varieties" - or - wrong = "vailidty" and right = "validity" - or - wrong = "valetta" and right = "valletta" - or - wrong = "valuble" and right = "valuable" - or - wrong = "valueable" and right = "valuable" - or - wrong = "varations" and right = "variations" - or - wrong = "varient" and right = "variant" - or - wrong = "variey" and right = "variety" - or - wrong = "varing" and right = "varying" - or - wrong = "varities" and right = "varieties" - or - wrong = "varity" and right = "variety" - or - wrong = "vasall" and right = "vassal" - or - wrong = "vasalls" and right = "vassals" - or - wrong = "vaule" and right = "value" - or - wrong = "vegatarian" and right = "vegetarian" - or - wrong = "vegitable" and right = "vegetable" - or - wrong = "vegitables" and right = "vegetables" - or - wrong = "vegtable" and right = "vegetable" - or - wrong = "vehicule" and right = "vehicle" - or - wrong = "vell" and right = "well" - or - wrong = "venemous" and right = "venomous" - or - wrong = "vengance" and right = "vengeance" - or - wrong = "vengence" and right = "vengeance" - or - wrong = "verfication" and right = "verification" - or - wrong = "verison" and right = "version" - or - wrong = "verisons" and right = "versions" - or - wrong = "vermillion" and right = "vermilion" - or - wrong = "versitilaty" and right = "versatility" - or - wrong = "versitlity" and right = "versatility" - or - wrong = "vetween" and right = "between" - or - wrong = "veyr" and right = "very" - or - wrong = "vigeur" and right = "vigor" - or - wrong = "vigeur" and right = "vigour" - or - wrong = "vigeur" and right = "vigueur" - or - wrong = "vigilence" and right = "vigilance" - or - wrong = "vigourous" and right = "vigorous" - or - wrong = "villian" and right = "villain" - or - wrong = "villification" and right = "vilification" - or - wrong = "villify" and right = "vilify" - or - wrong = "villin" and right = "villain" - or - wrong = "villin" and right = "villein" - or - wrong = "villin" and right = "villi" - or - wrong = "vincinity" and right = "vicinity" - or - wrong = "violentce" and right = "violence" - or - wrong = "virtualy" and right = "virtually" - or - wrong = "virutal" and right = "virtual" - or - wrong = "virutally" and right = "virtually" - or - wrong = "visable" and right = "visible" - or - wrong = "visably" and right = "visibly" - or - wrong = "visting" and right = "visiting" - or - wrong = "vistors" and right = "visitors" - or - wrong = "vitories" and right = "victories" - or - wrong = "volcanoe" and right = "volcano" - or - wrong = "voleyball" and right = "volleyball" - or - wrong = "volontary" and right = "voluntary" - or - wrong = "volonteer" and right = "volunteer" - or - wrong = "volonteered" and right = "volunteered" - or - wrong = "volonteering" and right = "volunteering" - or - wrong = "volonteers" and right = "volunteers" - or - wrong = "volounteer" and right = "volunteer" - or - wrong = "volounteered" and right = "volunteered" - or - wrong = "volounteering" and right = "volunteering" - or - wrong = "volounteers" and right = "volunteers" - or - wrong = "volumne" and right = "volume" - or - wrong = "vreity" and right = "variety" - or - wrong = "vrey" and right = "very" - or - wrong = "vriety" and right = "variety" - or - wrong = "vulnerablility" and right = "vulnerability" - or - wrong = "vyer" and right = "very" - or - wrong = "vyre" and right = "very" - or - wrong = "waht" and right = "what" - or - wrong = "warantee" and right = "warranty" - or - wrong = "wardobe" and right = "wardrobe" - or - wrong = "warrent" and right = "warrant" - or - wrong = "warrriors" and right = "warriors" - or - wrong = "wass" and right = "was" - or - wrong = "watn" and right = "want" - or - wrong = "wayword" and right = "wayward" - or - wrong = "weaponary" and right = "weaponry" - or - wrong = "weas" and right = "was" - or - wrong = "wehn" and right = "when" - or - wrong = "weild" and right = "wield" - or - wrong = "weild" and right = "wild" - or - wrong = "weilded" and right = "wielded" - or - wrong = "wendsay" and right = "wednesday" - or - wrong = "wensday" and right = "wednesday" - or - wrong = "wereabouts" and right = "whereabouts" - or - wrong = "whant" and right = "want" - or - wrong = "whants" and right = "wants" - or - wrong = "whcih" and right = "which" - or - wrong = "wheras" and right = "whereas" - or - wrong = "wherease" and right = "whereas" - or - wrong = "whereever" and right = "wherever" - or - wrong = "whic" and right = "which" - or - wrong = "whihc" and right = "which" - or - wrong = "whith" and right = "with" - or - wrong = "whlch" and right = "which" - or - wrong = "whn" and right = "when" - or - wrong = "wholey" and right = "wholly" - or - wrong = "wholy" and right = "holy" - or - wrong = "wholy" and right = "wholly" - or - wrong = "whta" and right = "what" - or - wrong = "whther" and right = "whether" - or - wrong = "wich" and right = "which" - or - wrong = "wich" and right = "witch" - or - wrong = "widesread" and right = "widespread" - or - wrong = "wief" and right = "wife" - or - wrong = "wierd" and right = "weird" - or - wrong = "wiew" and right = "view" - or - wrong = "wih" and right = "with" - or - wrong = "wiht" and right = "with" - or - wrong = "wille" and right = "will" - or - wrong = "willingless" and right = "willingness" - or - wrong = "willk" and right = "will" - or - wrong = "wirting" and right = "writing" - or - wrong = "withdrawl" and right = "withdraw" - or - wrong = "withdrawl" and right = "withdrawal" - or - wrong = "witheld" and right = "withheld" - or - wrong = "withh" and right = "with" - or - wrong = "withing" and right = "within" - or - wrong = "withold" and right = "withhold" - or - wrong = "witht" and right = "with" - or - wrong = "witn" and right = "with" - or - wrong = "wiull" and right = "will" - or - wrong = "wnat" and right = "want" - or - wrong = "wnated" and right = "wanted" - or - wrong = "wnats" and right = "wants" - or - wrong = "wohle" and right = "whole" - or - wrong = "wokr" and right = "work" - or - wrong = "wokring" and right = "working" - or - wrong = "wonderfull" and right = "wonderful" - or - wrong = "wordlwide" and right = "worldwide" - or - wrong = "workststion" and right = "workstation" - or - wrong = "worls" and right = "world" - or - wrong = "worstened" and right = "worsened" - or - wrong = "woudl" and right = "would" - or - wrong = "wresters" and right = "wrestlers" - or - wrong = "wriet" and right = "write" - or - wrong = "writen" and right = "written" - or - wrong = "wroet" and right = "wrote" - or - wrong = "wrok" and right = "work" - or - wrong = "wroking" and right = "working" - or - wrong = "wtih" and right = "with" - or - wrong = "wupport" and right = "support" - or - wrong = "xenophoby" and right = "xenophobia" - or - wrong = "yaching" and right = "yachting" - or - wrong = "yaer" and right = "year" - or - wrong = "yaerly" and right = "yearly" - or - wrong = "yaers" and right = "years" - or - wrong = "yatch" and right = "yacht" - or - wrong = "yearm" and right = "year" - or - wrong = "yeasr" and right = "years" - or - wrong = "yeild" and right = "yield" - or - wrong = "yeilding" and right = "yielding" - or - wrong = "yementite" and right = "yemeni" - or - wrong = "yementite" and right = "yemenite" - or - wrong = "yera" and right = "year" - or - wrong = "yeras" and right = "years" - or - wrong = "yersa" and right = "years" - or - wrong = "yotube" and right = "youtube" - or - wrong = "youseff" and right = "yousef" - or - wrong = "youself" and right = "yourself" - or - wrong = "yrea" and right = "year" - or - wrong = "ytou" and right = "you" - or - wrong = "yuo" and right = "you" - or - wrong = "zeebra" and right = "zebra" -} +import codeql.typos.TypoDatabase as DB + +/** DEPRECATED: Use the `codeql/typos` pack instead. */ +deprecated predicate typos = DB::typos/2; diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index b371302105e..a364849d264 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -9,3 +9,4 @@ defaultSuiteFile: codeql-suites/javascript-code-scanning.qls dependencies: codeql/javascript-all: "*" codeql/suite-helpers: "*" + codeql/typos: "*" diff --git a/ql/ql/src/codeql_ql/style/MisspellingQuery.qll b/ql/ql/src/codeql_ql/style/MisspellingQuery.qll index 822a1cfcb07..ad1fd800fb3 100644 --- a/ql/ql/src/codeql_ql/style/MisspellingQuery.qll +++ b/ql/ql/src/codeql_ql/style/MisspellingQuery.qll @@ -1,6 +1,6 @@ import ql private import NodeName -private import TypoDatabase +private import codeql.typos.TypoDatabase predicate misspelling(string wrong, string right, string mistake) { mistake = "common misspelling" and diff --git a/ql/ql/src/codeql_ql/style/TypoDatabase.qll b/ql/ql/src/codeql_ql/style/TypoDatabase.qll index a41f003a8c0..f480b9ebc8b 100644 --- a/ql/ql/src/codeql_ql/style/TypoDatabase.qll +++ b/ql/ql/src/codeql_ql/style/TypoDatabase.qll @@ -1,9035 +1,4 @@ -/** - * Holds if `wrong` is a common misspelling of `right`. - * - * This predicate was automatically generated by - * python buildutils-internal/scripts/generate-typos.py - * which uses http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines (with custom additions) on 2018-01-19. - * - * This file is available under the Creative Commons Attribution-ShareAlike License - * (https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License). - */ -predicate typos(string wrong, string right) { - wrong = "abandonned" and right = "abandoned" - or - wrong = "abbout" and right = "about" - or - wrong = "aberation" and right = "aberration" - or - wrong = "abilityes" and right = "abilities" - or - wrong = "abilties" and right = "abilities" - or - wrong = "abilty" and right = "ability" - or - wrong = "abondon" and right = "abandon" - or - wrong = "abondoned" and right = "abandoned" - or - wrong = "abondoning" and right = "abandoning" - or - wrong = "abondons" and right = "abandons" - or - wrong = "aborigene" and right = "aborigine" - or - wrong = "abortificant" and right = "abortifacient" - or - wrong = "abotu" and right = "about" - or - wrong = "abreviate" and right = "abbreviate" - or - wrong = "abreviated" and right = "abbreviated" - or - wrong = "abreviation" and right = "abbreviation" - or - wrong = "abritrary" and right = "arbitrary" - or - wrong = "absail" and right = "abseil" - or - wrong = "absailing" and right = "abseiling" - or - wrong = "abscence" and right = "absence" - or - wrong = "absense" and right = "absence" - or - wrong = "absolutly" and right = "absolutely" - or - wrong = "absorbsion" and right = "absorption" - or - wrong = "absorbtion" and right = "absorption" - or - wrong = "abudance" and right = "abundance" - or - wrong = "abundacies" and right = "abundances" - or - wrong = "abundancies" and right = "abundances" - or - wrong = "abundunt" and right = "abundant" - or - wrong = "abutts" and right = "abuts" - or - wrong = "acadamy" and right = "academy" - or - wrong = "acadmic" and right = "academic" - or - wrong = "accademic" and right = "academic" - or - wrong = "accademy" and right = "academy" - or - wrong = "acccess" and right = "access" - or - wrong = "acccused" and right = "accused" - or - wrong = "accelleration" and right = "acceleration" - or - wrong = "accension" and right = "accession" - or - wrong = "accension" and right = "ascension" - or - wrong = "acceptence" and right = "acceptance" - or - wrong = "acceptible" and right = "acceptable" - or - wrong = "accesories" and right = "accessories" - or - wrong = "accessable" and right = "accessible" - or - wrong = "accidant" and right = "accident" - or - wrong = "accidentaly" and right = "accidentally" - or - wrong = "accidently" and right = "accidentally" - or - wrong = "acclimitization" and right = "acclimatization" - or - wrong = "accomadate" and right = "accommodate" - or - wrong = "accomadated" and right = "accommodated" - or - wrong = "accomadates" and right = "accommodates" - or - wrong = "accomadating" and right = "accommodating" - or - wrong = "accomadation" and right = "accommodation" - or - wrong = "accomadations" and right = "accommodations" - or - wrong = "accomdate" and right = "accommodate" - or - wrong = "accomodate" and right = "accommodate" - or - wrong = "accomodated" and right = "accommodated" - or - wrong = "accomodates" and right = "accommodates" - or - wrong = "accomodating" and right = "accommodating" - or - wrong = "accomodation" and right = "accommodation" - or - wrong = "accomodations" and right = "accommodations" - or - wrong = "accompanyed" and right = "accompanied" - or - wrong = "accordeon" and right = "accordion" - or - wrong = "accordian" and right = "accordion" - or - wrong = "accoring" and right = "according" - or - wrong = "accoustic" and right = "acoustic" - or - wrong = "accquainted" and right = "acquainted" - or - wrong = "accrediation" and right = "accreditation" - or - wrong = "accredidation" and right = "accreditation" - or - wrong = "accross" and right = "across" - or - wrong = "accussed" and right = "accused" - or - wrong = "acedemic" and right = "academic" - or - wrong = "acheive" and right = "achieve" - or - wrong = "acheived" and right = "achieved" - or - wrong = "acheivement" and right = "achievement" - or - wrong = "acheivements" and right = "achievements" - or - wrong = "acheives" and right = "achieves" - or - wrong = "acheiving" and right = "achieving" - or - wrong = "acheivment" and right = "achievement" - or - wrong = "acheivments" and right = "achievements" - or - wrong = "achievment" and right = "achievement" - or - wrong = "achievments" and right = "achievements" - or - wrong = "achive" and right = "achieve" - or - wrong = "achive" and right = "archive" - or - wrong = "achived" and right = "achieved" - or - wrong = "achived" and right = "archived" - or - wrong = "achivement" and right = "achievement" - or - wrong = "achivements" and right = "achievements" - or - wrong = "acident" and right = "accident" - or - wrong = "acknowldeged" and right = "acknowledged" - or - wrong = "acknowledgeing" and right = "acknowledging" - or - wrong = "ackward" and right = "awkward" - or - wrong = "ackward" and right = "backward" - or - wrong = "acommodate" and right = "accommodate" - or - wrong = "acomplish" and right = "accomplish" - or - wrong = "acomplished" and right = "accomplished" - or - wrong = "acomplishment" and right = "accomplishment" - or - wrong = "acomplishments" and right = "accomplishments" - or - wrong = "acording" and right = "according" - or - wrong = "acordingly" and right = "accordingly" - or - wrong = "acquaintence" and right = "acquaintance" - or - wrong = "acquaintences" and right = "acquaintances" - or - wrong = "acquiantence" and right = "acquaintance" - or - wrong = "acquiantences" and right = "acquaintances" - or - wrong = "acquited" and right = "acquitted" - or - wrong = "activites" and right = "activities" - or - wrong = "activly" and right = "actively" - or - wrong = "actualy" and right = "actually" - or - wrong = "acuracy" and right = "accuracy" - or - wrong = "acused" and right = "accused" - or - wrong = "acustom" and right = "accustom" - or - wrong = "acustommed" and right = "accustomed" - or - wrong = "adapater" and right = "adapter" - or - wrong = "adavanced" and right = "advanced" - or - wrong = "adbandon" and right = "abandon" - or - wrong = "addional" and right = "additional" - or - wrong = "addionally" and right = "additionally" - or - wrong = "additinally" and right = "additionally" - or - wrong = "additionaly" and right = "additionally" - or - wrong = "additonal" and right = "additional" - or - wrong = "additonally" and right = "additionally" - or - wrong = "addmission" and right = "admission" - or - wrong = "addopt" and right = "adopt" - or - wrong = "addopted" and right = "adopted" - or - wrong = "addoptive" and right = "adoptive" - or - wrong = "addres" and right = "adders" - or - wrong = "addres" and right = "address" - or - wrong = "addresable" and right = "addressable" - or - wrong = "addresed" and right = "addressed" - or - wrong = "addresing" and right = "addressing" - or - wrong = "addressess" and right = "addresses" - or - wrong = "addtion" and right = "addition" - or - wrong = "addtional" and right = "additional" - or - wrong = "adecuate" and right = "adequate" - or - wrong = "adequit" and right = "adequate" - or - wrong = "adhearing" and right = "adhering" - or - wrong = "adherance" and right = "adherence" - or - wrong = "admendment" and right = "amendment" - or - wrong = "admininistrative" and right = "administrative" - or - wrong = "adminstered" and right = "administered" - or - wrong = "adminstrate" and right = "administrate" - or - wrong = "adminstration" and right = "administration" - or - wrong = "adminstrative" and right = "administrative" - or - wrong = "adminstrator" and right = "administrator" - or - wrong = "admissability" and right = "admissibility" - or - wrong = "admissable" and right = "admissible" - or - wrong = "admited" and right = "admitted" - or - wrong = "admitedly" and right = "admittedly" - or - wrong = "adn" and right = "and" - or - wrong = "adolecent" and right = "adolescent" - or - wrong = "adquire" and right = "acquire" - or - wrong = "adquired" and right = "acquired" - or - wrong = "adquires" and right = "acquires" - or - wrong = "adquiring" and right = "acquiring" - or - wrong = "adres" and right = "address" - or - wrong = "adresable" and right = "addressable" - or - wrong = "adresing" and right = "addressing" - or - wrong = "adress" and right = "address" - or - wrong = "adressable" and right = "addressable" - or - wrong = "adressed" and right = "addressed" - or - wrong = "adressing" and right = "addressing" - or - wrong = "adressing" and right = "dressing" - or - wrong = "adventrous" and right = "adventurous" - or - wrong = "advertisment" and right = "advertisement" - or - wrong = "advertisments" and right = "advertisements" - or - wrong = "advesary" and right = "adversary" - or - wrong = "adviced" and right = "advised" - or - wrong = "aeriel" and right = "aerial" - or - wrong = "aeriels" and right = "aerials" - or - wrong = "afair" and right = "affair" - or - wrong = "afficianados" and right = "aficionados" - or - wrong = "afficionado" and right = "aficionado" - or - wrong = "afficionados" and right = "aficionados" - or - wrong = "affilate" and right = "affiliate" - or - wrong = "affilliate" and right = "affiliate" - or - wrong = "affort" and right = "afford" - or - wrong = "affort" and right = "effort" - or - wrong = "aforememtioned" and right = "aforementioned" - or - wrong = "againnst" and right = "against" - or - wrong = "agains" and right = "against" - or - wrong = "agaisnt" and right = "against" - or - wrong = "aganist" and right = "against" - or - wrong = "aggaravates" and right = "aggravates" - or - wrong = "aggreed" and right = "agreed" - or - wrong = "aggreement" and right = "agreement" - or - wrong = "aggregious" and right = "egregious" - or - wrong = "aggresive" and right = "aggressive" - or - wrong = "agian" and right = "again" - or - wrong = "agianst" and right = "against" - or - wrong = "agin" and right = "again" - or - wrong = "agina" and right = "again" - or - wrong = "agina" and right = "angina" - or - wrong = "aginst" and right = "against" - or - wrong = "agravate" and right = "aggravate" - or - wrong = "agre" and right = "agree" - or - wrong = "agred" and right = "agreed" - or - wrong = "agreeement" and right = "agreement" - or - wrong = "agreemnt" and right = "agreement" - or - wrong = "agregate" and right = "aggregate" - or - wrong = "agregates" and right = "aggregates" - or - wrong = "agreing" and right = "agreeing" - or - wrong = "agression" and right = "aggression" - or - wrong = "agressive" and right = "aggressive" - or - wrong = "agressively" and right = "aggressively" - or - wrong = "agressor" and right = "aggressor" - or - wrong = "agricultue" and right = "agriculture" - or - wrong = "agriculure" and right = "agriculture" - or - wrong = "agricuture" and right = "agriculture" - or - wrong = "agrieved" and right = "aggrieved" - or - wrong = "agrument" and right = "argument" - or - wrong = "agruments" and right = "arguments" - or - wrong = "ahev" and right = "have" - or - wrong = "ahppen" and right = "happen" - or - wrong = "ahve" and right = "have" - or - wrong = "aicraft" and right = "aircraft" - or - wrong = "aiport" and right = "airport" - or - wrong = "airbourne" and right = "airborne" - or - wrong = "aircaft" and right = "aircraft" - or - wrong = "aircrafts" and right = "aircraft" - or - wrong = "airporta" and right = "airports" - or - wrong = "airrcraft" and right = "aircraft" - or - wrong = "aisian" and right = "asian" - or - wrong = "albiet" and right = "albeit" - or - wrong = "alchohol" and right = "alcohol" - or - wrong = "alchoholic" and right = "alcoholic" - or - wrong = "alchol" and right = "alcohol" - or - wrong = "alcholic" and right = "alcoholic" - or - wrong = "alcohal" and right = "alcohol" - or - wrong = "alcoholical" and right = "alcoholic" - or - wrong = "aledge" and right = "allege" - or - wrong = "aledged" and right = "alleged" - or - wrong = "aledges" and right = "alleges" - or - wrong = "alege" and right = "allege" - or - wrong = "aleged" and right = "alleged" - or - wrong = "alegience" and right = "allegiance" - or - wrong = "algebraical" and right = "algebraic" - or - wrong = "algorhitms" and right = "algorithms" - or - wrong = "algoritm" and right = "algorithm" - or - wrong = "algoritms" and right = "algorithms" - or - wrong = "alientating" and right = "alienating" - or - wrong = "alledge" and right = "allege" - or - wrong = "alledged" and right = "alleged" - or - wrong = "alledgedly" and right = "allegedly" - or - wrong = "alledges" and right = "alleges" - or - wrong = "allegedely" and right = "allegedly" - or - wrong = "allegedy" and right = "allegedly" - or - wrong = "allegely" and right = "allegedly" - or - wrong = "allegence" and right = "allegiance" - or - wrong = "allegience" and right = "allegiance" - or - wrong = "allign" and right = "align" - or - wrong = "alligned" and right = "aligned" - or - wrong = "alliviate" and right = "alleviate" - or - wrong = "allopone" and right = "allophone" - or - wrong = "allopones" and right = "allophones" - or - wrong = "allready" and right = "already" - or - wrong = "allthough" and right = "although" - or - wrong = "alltogether" and right = "altogether" - or - wrong = "almsot" and right = "almost" - or - wrong = "alochol" and right = "alcohol" - or - wrong = "alomst" and right = "almost" - or - wrong = "alot" and right = "allot" - or - wrong = "alotted" and right = "allotted" - or - wrong = "alowed" and right = "allowed" - or - wrong = "alowing" and right = "allowing" - or - wrong = "alreayd" and right = "already" - or - wrong = "alse" and right = "else" - or - wrong = "alsot" and right = "also" - or - wrong = "alternitives" and right = "alternatives" - or - wrong = "altho" and right = "although" - or - wrong = "althought" and right = "although" - or - wrong = "altough" and right = "although" - or - wrong = "alusion" and right = "allusion" - or - wrong = "alusion" and right = "illusion" - or - wrong = "alwasy" and right = "always" - or - wrong = "alwyas" and right = "always" - or - wrong = "amalgomated" and right = "amalgamated" - or - wrong = "amatuer" and right = "amateur" - or - wrong = "amature" and right = "amateur" - or - wrong = "amature" and right = "armature" - or - wrong = "amendmant" and right = "amendment" - or - wrong = "amercia" and right = "america" - or - wrong = "amerliorate" and right = "ameliorate" - or - wrong = "amke" and right = "make" - or - wrong = "amking" and right = "making" - or - wrong = "ammend" and right = "amend" - or - wrong = "ammended" and right = "amended" - or - wrong = "ammendment" and right = "amendment" - or - wrong = "ammendments" and right = "amendments" - or - wrong = "ammount" and right = "amount" - or - wrong = "ammused" and right = "amused" - or - wrong = "amoung" and right = "among" - or - wrong = "amoungst" and right = "amongst" - or - wrong = "amung" and right = "among" - or - wrong = "amunition" and right = "ammunition" - or - wrong = "analagous" and right = "analogous" - or - wrong = "analitic" and right = "analytic" - or - wrong = "analogeous" and right = "analogous" - or - wrong = "anarchim" and right = "anarchism" - or - wrong = "anarchistm" and right = "anarchism" - or - wrong = "anbd" and right = "and" - or - wrong = "ancestory" and right = "ancestry" - or - wrong = "ancilliary" and right = "ancillary" - or - wrong = "andd" and right = "and" - or - wrong = "androgenous" and right = "androgynous" - or - wrong = "androgeny" and right = "androgyny" - or - wrong = "anihilation" and right = "annihilation" - or - wrong = "aniversary" and right = "anniversary" - or - wrong = "annoint" and right = "anoint" - or - wrong = "annointed" and right = "anointed" - or - wrong = "annointing" and right = "anointing" - or - wrong = "annoints" and right = "anoints" - or - wrong = "annouced" and right = "announced" - or - wrong = "annualy" and right = "annually" - or - wrong = "annuled" and right = "annulled" - or - wrong = "anohter" and right = "another" - or - wrong = "anomolies" and right = "anomalies" - or - wrong = "anomolous" and right = "anomalous" - or - wrong = "anomoly" and right = "anomaly" - or - wrong = "anonimity" and right = "anonymity" - or - wrong = "anounced" and right = "announced" - or - wrong = "anouncement" and right = "announcement" - or - wrong = "ansalisation" and right = "nasalisation" - or - wrong = "ansalization" and right = "nasalization" - or - wrong = "ansestors" and right = "ancestors" - or - wrong = "antartic" and right = "antarctic" - or - wrong = "anthromorphization" and right = "anthropomorphization" - or - wrong = "anthropolgist" and right = "anthropologist" - or - wrong = "anthropolgy" and right = "anthropology" - or - wrong = "anual" and right = "annual" - or - wrong = "anulled" and right = "annulled" - or - wrong = "anwsered" and right = "answered" - or - wrong = "anyhwere" and right = "anywhere" - or - wrong = "anytying" and right = "anything" - or - wrong = "aparent" and right = "apparent" - or - wrong = "aparment" and right = "apartment" - or - wrong = "apenines" and right = "apennines" - or - wrong = "aplication" and right = "application" - or - wrong = "aplied" and right = "applied" - or - wrong = "apolegetics" and right = "apologetics" - or - wrong = "apon" and right = "apron" - or - wrong = "apon" and right = "upon" - or - wrong = "apparant" and right = "apparent" - or - wrong = "apparantly" and right = "apparently" - or - wrong = "appart" and right = "apart" - or - wrong = "appartment" and right = "apartment" - or - wrong = "appartments" and right = "apartments" - or - wrong = "appealling" and right = "appalling" - or - wrong = "appealling" and right = "appealing" - or - wrong = "appeareance" and right = "appearance" - or - wrong = "appearence" and right = "appearance" - or - wrong = "appearences" and right = "appearances" - or - wrong = "appenines" and right = "apennines" - or - wrong = "apperance" and right = "appearance" - or - wrong = "apperances" and right = "appearances" - or - wrong = "appereance" and right = "appearance" - or - wrong = "appereances" and right = "appearances" - or - wrong = "applicaiton" and right = "application" - or - wrong = "applicaitons" and right = "applications" - or - wrong = "appologies" and right = "apologies" - or - wrong = "appology" and right = "apology" - or - wrong = "apprearance" and right = "appearance" - or - wrong = "apprieciate" and right = "appreciate" - or - wrong = "approachs" and right = "approaches" - or - wrong = "appropiate" and right = "appropriate" - or - wrong = "appropraite" and right = "appropriate" - or - wrong = "appropropiate" and right = "appropriate" - or - wrong = "approproximate" and right = "approximate" - or - wrong = "approxamately" and right = "approximately" - or - wrong = "approxiately" and right = "approximately" - or - wrong = "approximitely" and right = "approximately" - or - wrong = "aprehensive" and right = "apprehensive" - or - wrong = "apropriate" and right = "appropriate" - or - wrong = "aproval" and right = "approval" - or - wrong = "aproximate" and right = "approximate" - or - wrong = "aproximately" and right = "approximately" - or - wrong = "aquaduct" and right = "aqueduct" - or - wrong = "aquaintance" and right = "acquaintance" - or - wrong = "aquainted" and right = "acquainted" - or - wrong = "aquiantance" and right = "acquaintance" - or - wrong = "aquire" and right = "acquire" - or - wrong = "aquired" and right = "acquired" - or - wrong = "aquiring" and right = "acquiring" - or - wrong = "aquisition" and right = "acquisition" - or - wrong = "aquitted" and right = "acquitted" - or - wrong = "aranged" and right = "arranged" - or - wrong = "arangement" and right = "arrangement" - or - wrong = "arbitarily" and right = "arbitrarily" - or - wrong = "arbitary" and right = "arbitrary" - or - wrong = "archaelogical" and right = "archaeological" - or - wrong = "archaelogists" and right = "archaeologists" - or - wrong = "archaelogy" and right = "archaeology" - or - wrong = "archaoelogy" and right = "archaeology" - or - wrong = "archaoelogy" and right = "archeology" - or - wrong = "archaology" and right = "archaeology" - or - wrong = "archaology" and right = "archeology" - or - wrong = "archeaologist" and right = "archaeologist" - or - wrong = "archeaologist" and right = "archeologist" - or - wrong = "archeaologists" and right = "archaeologists" - or - wrong = "archeaologists" and right = "archeologists" - or - wrong = "archetect" and right = "architect" - or - wrong = "archetects" and right = "architects" - or - wrong = "archetectural" and right = "architectural" - or - wrong = "archetecturally" and right = "architecturally" - or - wrong = "archetecture" and right = "architecture" - or - wrong = "archiac" and right = "archaic" - or - wrong = "archictect" and right = "architect" - or - wrong = "archimedian" and right = "archimedean" - or - wrong = "architecht" and right = "architect" - or - wrong = "architechturally" and right = "architecturally" - or - wrong = "architechture" and right = "architecture" - or - wrong = "architechtures" and right = "architectures" - or - wrong = "architectual" and right = "architectural" - or - wrong = "archtype" and right = "archetype" - or - wrong = "archtypes" and right = "archetypes" - or - wrong = "aready" and right = "already" - or - wrong = "areodynamics" and right = "aerodynamics" - or - wrong = "argubly" and right = "arguably" - or - wrong = "arguement" and right = "argument" - or - wrong = "arguements" and right = "arguments" - or - wrong = "arised" and right = "arose" - or - wrong = "arival" and right = "arrival" - or - wrong = "armamant" and right = "armament" - or - wrong = "armistace" and right = "armistice" - or - wrong = "arogant" and right = "arrogant" - or - wrong = "arogent" and right = "arrogant" - or - wrong = "aroud" and right = "around" - or - wrong = "arrangment" and right = "arrangement" - or - wrong = "arrangments" and right = "arrangements" - or - wrong = "arrengement" and right = "arrangement" - or - wrong = "arrengements" and right = "arrangements" - or - wrong = "arround" and right = "around" - or - wrong = "artcile" and right = "article" - or - wrong = "artical" and right = "article" - or - wrong = "artice" and right = "article" - or - wrong = "articel" and right = "article" - or - wrong = "artifical" and right = "artificial" - or - wrong = "artifically" and right = "artificially" - or - wrong = "artillary" and right = "artillery" - or - wrong = "arund" and right = "around" - or - wrong = "asetic" and right = "ascetic" - or - wrong = "asign" and right = "assign" - or - wrong = "aslo" and right = "also" - or - wrong = "asnyc" and right = "async" - or - wrong = "asociated" and right = "associated" - or - wrong = "asorbed" and right = "absorbed" - or - wrong = "asphyxation" and right = "asphyxiation" - or - wrong = "assasin" and right = "assassin" - or - wrong = "assasinate" and right = "assassinate" - or - wrong = "assasinated" and right = "assassinated" - or - wrong = "assasinates" and right = "assassinates" - or - wrong = "assasination" and right = "assassination" - or - wrong = "assasinations" and right = "assassinations" - or - wrong = "assasined" and right = "assassinated" - or - wrong = "assasins" and right = "assassins" - or - wrong = "assassintation" and right = "assassination" - or - wrong = "assemple" and right = "assemble" - or - wrong = "assertation" and right = "assertion" - or - wrong = "asside" and right = "aside" - or - wrong = "assisnate" and right = "assassinate" - or - wrong = "assit" and right = "assist" - or - wrong = "assitant" and right = "assistant" - or - wrong = "assocation" and right = "association" - or - wrong = "assoicate" and right = "associate" - or - wrong = "assoicated" and right = "associated" - or - wrong = "assoicates" and right = "associates" - or - wrong = "assosication" and right = "assassination" - or - wrong = "asssassans" and right = "assassins" - or - wrong = "assualt" and right = "assault" - or - wrong = "assualted" and right = "assaulted" - or - wrong = "assymetric" and right = "asymmetric" - or - wrong = "assymetrical" and right = "asymmetrical" - or - wrong = "asteriod" and right = "asteroid" - or - wrong = "asthetic" and right = "aesthetic" - or - wrong = "asthetical" and right = "aesthetical" - or - wrong = "asthetically" and right = "aesthetically" - or - wrong = "asume" and right = "assume" - or - wrong = "atain" and right = "attain" - or - wrong = "atempting" and right = "attempting" - or - wrong = "atheistical" and right = "atheistic" - or - wrong = "athenean" and right = "athenian" - or - wrong = "atheneans" and right = "athenians" - or - wrong = "athiesm" and right = "atheism" - or - wrong = "athiest" and right = "atheist" - or - wrong = "atorney" and right = "attorney" - or - wrong = "atribute" and right = "attribute" - or - wrong = "atributed" and right = "attributed" - or - wrong = "atributes" and right = "attributes" - or - wrong = "attaindre" and right = "attainder" - or - wrong = "attaindre" and right = "attained" - or - wrong = "attemp" and right = "attempt" - or - wrong = "attemped" and right = "attempted" - or - wrong = "attemt" and right = "attempt" - or - wrong = "attemted" and right = "attempted" - or - wrong = "attemting" and right = "attempting" - or - wrong = "attemts" and right = "attempts" - or - wrong = "attendence" and right = "attendance" - or - wrong = "attendent" and right = "attendant" - or - wrong = "attendents" and right = "attendants" - or - wrong = "attened" and right = "attended" - or - wrong = "attension" and right = "attention" - or - wrong = "attitide" and right = "attitude" - or - wrong = "attributred" and right = "attributed" - or - wrong = "attrocities" and right = "atrocities" - or - wrong = "audeince" and right = "audience" - or - wrong = "auromated" and right = "automated" - or - wrong = "austrailia" and right = "australia" - or - wrong = "austrailian" and right = "australian" - or - wrong = "auther" and right = "author" - or - wrong = "authobiographic" and right = "autobiographic" - or - wrong = "authobiography" and right = "autobiography" - or - wrong = "authorative" and right = "authoritative" - or - wrong = "authorites" and right = "authorities" - or - wrong = "authorithy" and right = "authority" - or - wrong = "authoritiers" and right = "authorities" - or - wrong = "authoritive" and right = "authoritative" - or - wrong = "authrorities" and right = "authorities" - or - wrong = "autochtonous" and right = "autochthonous" - or - wrong = "autoctonous" and right = "autochthonous" - or - wrong = "automaticly" and right = "automatically" - or - wrong = "automibile" and right = "automobile" - or - wrong = "automonomous" and right = "autonomous" - or - wrong = "autor" and right = "author" - or - wrong = "autority" and right = "authority" - or - wrong = "auxilary" and right = "auxiliary" - or - wrong = "auxillaries" and right = "auxiliaries" - or - wrong = "auxillary" and right = "auxiliary" - or - wrong = "auxilliaries" and right = "auxiliaries" - or - wrong = "auxilliary" and right = "auxiliary" - or - wrong = "availabe" and right = "available" - or - wrong = "availablity" and right = "availability" - or - wrong = "availaible" and right = "available" - or - wrong = "availble" and right = "available" - or - wrong = "availiable" and right = "available" - or - wrong = "availible" and right = "available" - or - wrong = "avalable" and right = "available" - or - wrong = "avalance" and right = "avalanche" - or - wrong = "avaliable" and right = "available" - or - wrong = "avation" and right = "aviation" - or - wrong = "averageed" and right = "averaged" - or - wrong = "avilable" and right = "available" - or - wrong = "awared" and right = "awarded" - or - wrong = "awya" and right = "away" - or - wrong = "baceause" and right = "because" - or - wrong = "backgorund" and right = "background" - or - wrong = "backrounds" and right = "backgrounds" - or - wrong = "bakc" and right = "back" - or - wrong = "banannas" and right = "bananas" - or - wrong = "bandwith" and right = "bandwidth" - or - wrong = "bankrupcy" and right = "bankruptcy" - or - wrong = "banruptcy" and right = "bankruptcy" - or - wrong = "baout" and right = "about" - or - wrong = "baout" and right = "bout" - or - wrong = "basicaly" and right = "basically" - or - wrong = "basicly" and right = "basically" - or - wrong = "bcak" and right = "back" - or - wrong = "beachead" and right = "beachhead" - or - wrong = "beacuse" and right = "because" - or - wrong = "beastiality" and right = "bestiality" - or - wrong = "beatiful" and right = "beautiful" - or - wrong = "beaurocracy" and right = "bureaucracy" - or - wrong = "beaurocratic" and right = "bureaucratic" - or - wrong = "beautyfull" and right = "beautiful" - or - wrong = "becamae" and right = "became" - or - wrong = "becames" and right = "became" - or - wrong = "becames" and right = "becomes" - or - wrong = "becasue" and right = "because" - or - wrong = "beccause" and right = "because" - or - wrong = "becomeing" and right = "becoming" - or - wrong = "becomming" and right = "becoming" - or - wrong = "becouse" and right = "because" - or - wrong = "becuase" and right = "because" - or - wrong = "bedore" and right = "before" - or - wrong = "beeing" and right = "being" - or - wrong = "befoer" and right = "before" - or - wrong = "beggin" and right = "begging" - or - wrong = "beggin" and right = "begin" - or - wrong = "begginer" and right = "beginner" - or - wrong = "begginers" and right = "beginners" - or - wrong = "beggining" and right = "beginning" - or - wrong = "begginings" and right = "beginnings" - or - wrong = "beggins" and right = "begins" - or - wrong = "begining" and right = "beginning" - or - wrong = "beginnig" and right = "beginning" - or - wrong = "behavour" and right = "behavior" - or - wrong = "behavour" and right = "behaviour" - or - wrong = "beleagured" and right = "beleaguered" - or - wrong = "beleif" and right = "belief" - or - wrong = "beleive" and right = "believe" - or - wrong = "beleived" and right = "believed" - or - wrong = "beleives" and right = "believes" - or - wrong = "beleiving" and right = "believing" - or - wrong = "beligum" and right = "belgium" - or - wrong = "belive" and right = "believe" - or - wrong = "belived" and right = "believed" - or - wrong = "belived" and right = "beloved" - or - wrong = "belives" and right = "beliefs" - or - wrong = "belives" and right = "believes" - or - wrong = "belligerant" and right = "belligerent" - or - wrong = "bellweather" and right = "bellwether" - or - wrong = "bemusemnt" and right = "bemusement" - or - wrong = "beneficary" and right = "beneficiary" - or - wrong = "beng" and right = "being" - or - wrong = "benificial" and right = "beneficial" - or - wrong = "benifit" and right = "benefit" - or - wrong = "benifits" and right = "benefits" - or - wrong = "bergamont" and right = "bergamot" - or - wrong = "bernouilli" and right = "bernoulli" - or - wrong = "beseige" and right = "besiege" - or - wrong = "beseiged" and right = "besieged" - or - wrong = "beseiging" and right = "besieging" - or - wrong = "beteen" and right = "between" - or - wrong = "betwen" and right = "between" - or - wrong = "beween" and right = "between" - or - wrong = "bewteen" and right = "between" - or - wrong = "bigining" and right = "beginning" - or - wrong = "biginning" and right = "beginning" - or - wrong = "bilateraly" and right = "bilaterally" - or - wrong = "billingualism" and right = "bilingualism" - or - wrong = "binominal" and right = "binomial" - or - wrong = "bizzare" and right = "bizarre" - or - wrong = "blaim" and right = "blame" - or - wrong = "blaimed" and right = "blamed" - or - wrong = "blessure" and right = "blessing" - or - wrong = "blitzkreig" and right = "blitzkrieg" - or - wrong = "boaut" and right = "about" - or - wrong = "boaut" and right = "boat" - or - wrong = "boaut" and right = "bout" - or - wrong = "bodydbuilder" and right = "bodybuilder" - or - wrong = "bolean" and right = "boolean" - or - wrong = "bombardement" and right = "bombardment" - or - wrong = "bombarment" and right = "bombardment" - or - wrong = "bondary" and right = "boundary" - or - wrong = "bonnano" and right = "bonanno" - or - wrong = "boook" and right = "book" - or - wrong = "borke" and right = "broke" - or - wrong = "boundry" and right = "boundary" - or - wrong = "bouyancy" and right = "buoyancy" - or - wrong = "bouyant" and right = "buoyant" - or - wrong = "boyant" and right = "buoyant" - or - wrong = "bradcast" and right = "broadcast" - or - wrong = "brasillian" and right = "brazilian" - or - wrong = "breakthough" and right = "breakthrough" - or - wrong = "breakthroughts" and right = "breakthroughs" - or - wrong = "breif" and right = "brief" - or - wrong = "breifly" and right = "briefly" - or - wrong = "brethen" and right = "brethren" - or - wrong = "bretheren" and right = "brethren" - or - wrong = "briliant" and right = "brilliant" - or - wrong = "brillant" and right = "brilliant" - or - wrong = "brimestone" and right = "brimstone" - or - wrong = "britian" and right = "britain" - or - wrong = "brittish" and right = "british" - or - wrong = "broacasted" and right = "broadcast" - or - wrong = "broadacasting" and right = "broadcasting" - or - wrong = "broady" and right = "broadly" - or - wrong = "buddah" and right = "buddha" - or - wrong = "buddist" and right = "buddhist" - or - wrong = "buisness" and right = "business" - or - wrong = "buisnessman" and right = "businessman" - or - wrong = "buoancy" and right = "buoyancy" - or - wrong = "buring" and right = "burin" - or - wrong = "buring" and right = "burning" - or - wrong = "buring" and right = "burying" - or - wrong = "buring" and right = "during" - or - wrong = "burried" and right = "buried" - or - wrong = "busines" and right = "business" - or - wrong = "busineses" and right = "business" - or - wrong = "busineses" and right = "businesses" - or - wrong = "busness" and right = "business" - or - wrong = "bussiness" and right = "business" - or - wrong = "caculater" and right = "calculator" - or - wrong = "cacuses" and right = "caucuses" - or - wrong = "cahracters" and right = "characters" - or - wrong = "calaber" and right = "caliber" - or - wrong = "calander" and right = "calendar" - or - wrong = "calander" and right = "calender" - or - wrong = "calander" and right = "colander" - or - wrong = "calculater" and right = "calculator" - or - wrong = "calculs" and right = "calculus" - or - wrong = "calender" and right = "calendar" - or - wrong = "calenders" and right = "calendars" - or - wrong = "caligraphy" and right = "calligraphy" - or - wrong = "caluclate" and right = "calculate" - or - wrong = "caluclated" and right = "calculated" - or - wrong = "caluculate" and right = "calculate" - or - wrong = "caluculated" and right = "calculated" - or - wrong = "calulate" and right = "calculate" - or - wrong = "calulated" and right = "calculated" - or - wrong = "calulater" and right = "calculator" - or - wrong = "cambrige" and right = "cambridge" - or - wrong = "camoflage" and right = "camouflage" - or - wrong = "campagin" and right = "campaign" - or - wrong = "campain" and right = "campaign" - or - wrong = "campains" and right = "campaigns" - or - wrong = "candadate" and right = "candidate" - or - wrong = "candiate" and right = "candidate" - or - wrong = "candidiate" and right = "candidate" - or - wrong = "cannister" and right = "canister" - or - wrong = "cannisters" and right = "canisters" - or - wrong = "cannnot" and right = "cannot" - or - wrong = "cannonical" and right = "canonical" - or - wrong = "cannotation" and right = "connotation" - or - wrong = "cannotations" and right = "connotations" - or - wrong = "caost" and right = "coast" - or - wrong = "caperbility" and right = "capability" - or - wrong = "capible" and right = "capable" - or - wrong = "captial" and right = "capital" - or - wrong = "captued" and right = "captured" - or - wrong = "capturd" and right = "captured" - or - wrong = "carachter" and right = "character" - or - wrong = "caracterized" and right = "characterized" - or - wrong = "carcas" and right = "caracas" - or - wrong = "carcas" and right = "carcass" - or - wrong = "carefull" and right = "careful" - or - wrong = "careing" and right = "caring" - or - wrong = "carismatic" and right = "charismatic" - or - wrong = "carmalite" and right = "carmelite" - or - wrong = "carnagie" and right = "carnegie" - or - wrong = "carnege" and right = "carnage" - or - wrong = "carnege" and right = "carnegie" - or - wrong = "carnige" and right = "carnage" - or - wrong = "carnige" and right = "carnegie" - or - wrong = "carnigie" and right = "carnegie" - or - wrong = "carreer" and right = "career" - or - wrong = "carrers" and right = "careers" - or - wrong = "carribbean" and right = "caribbean" - or - wrong = "carribean" and right = "caribbean" - or - wrong = "carryng" and right = "carrying" - or - wrong = "cartdridge" and right = "cartridge" - or - wrong = "carthagian" and right = "carthaginian" - or - wrong = "carthographer" and right = "cartographer" - or - wrong = "cartilege" and right = "cartilage" - or - wrong = "cartilidge" and right = "cartilage" - or - wrong = "cartrige" and right = "cartridge" - or - wrong = "casette" and right = "cassette" - or - wrong = "casion" and right = "caisson" - or - wrong = "cassawory" and right = "cassowary" - or - wrong = "cassowarry" and right = "cassowary" - or - wrong = "casue" and right = "cause" - or - wrong = "casued" and right = "caused" - or - wrong = "casues" and right = "causes" - or - wrong = "casuing" and right = "causing" - or - wrong = "casulaties" and right = "casualties" - or - wrong = "casulaty" and right = "casualty" - or - wrong = "catagories" and right = "categories" - or - wrong = "catagorized" and right = "categorized" - or - wrong = "catagory" and right = "category" - or - wrong = "cataline" and right = "catalina" - or - wrong = "cataline" and right = "catiline" - or - wrong = "catapillar" and right = "caterpillar" - or - wrong = "catapillars" and right = "caterpillars" - or - wrong = "catapiller" and right = "caterpillar" - or - wrong = "catapillers" and right = "caterpillars" - or - wrong = "catepillar" and right = "caterpillar" - or - wrong = "catepillars" and right = "caterpillars" - or - wrong = "catergorize" and right = "categorize" - or - wrong = "catergorized" and right = "categorized" - or - wrong = "caterpilar" and right = "caterpillar" - or - wrong = "caterpilars" and right = "caterpillars" - or - wrong = "caterpiller" and right = "caterpillar" - or - wrong = "caterpillers" and right = "caterpillars" - or - wrong = "cathlic" and right = "catholic" - or - wrong = "catholocism" and right = "catholicism" - or - wrong = "catterpilar" and right = "caterpillar" - or - wrong = "catterpilars" and right = "caterpillars" - or - wrong = "catterpillar" and right = "caterpillar" - or - wrong = "catterpillars" and right = "caterpillars" - or - wrong = "cattleship" and right = "battleship" - or - wrong = "causalities" and right = "casualties" - or - wrong = "ceasar" and right = "caesar" - or - wrong = "celcius" and right = "celsius" - or - wrong = "cellpading" and right = "cellpadding" - or - wrong = "cementary" and right = "cemetery" - or - wrong = "cemetarey" and right = "cemetery" - or - wrong = "cemetaries" and right = "cemeteries" - or - wrong = "cemetary" and right = "cemetery" - or - wrong = "cencus" and right = "census" - or - wrong = "censur" and right = "censor" - or - wrong = "censur" and right = "censure" - or - wrong = "cententenial" and right = "centennial" - or - wrong = "centruies" and right = "centuries" - or - wrong = "centruy" and right = "century" - or - wrong = "centuties" and right = "centuries" - or - wrong = "centuty" and right = "century" - or - wrong = "ceratin" and right = "certain" - or - wrong = "ceratin" and right = "keratin" - or - wrong = "cerimonial" and right = "ceremonial" - or - wrong = "cerimonies" and right = "ceremonies" - or - wrong = "cerimonious" and right = "ceremonious" - or - wrong = "cerimony" and right = "ceremony" - or - wrong = "ceromony" and right = "ceremony" - or - wrong = "certainity" and right = "certainty" - or - wrong = "certian" and right = "certain" - or - wrong = "cervial" and right = "cervical" - or - wrong = "cervial" and right = "serval" - or - wrong = "cervial" and right = "servile" - or - wrong = "chalenging" and right = "challenging" - or - wrong = "challange" and right = "challenge" - or - wrong = "challanged" and right = "challenged" - or - wrong = "challege" and right = "challenge" - or - wrong = "champange" and right = "champagne" - or - wrong = "changable" and right = "changeable" - or - wrong = "charachter" and right = "character" - or - wrong = "charachters" and right = "characters" - or - wrong = "charactersistic" and right = "characteristic" - or - wrong = "charactor" and right = "character" - or - wrong = "charactors" and right = "characters" - or - wrong = "charasmatic" and right = "charismatic" - or - wrong = "charaterized" and right = "characterized" - or - wrong = "chariman" and right = "chairman" - or - wrong = "charistics" and right = "characteristics" - or - wrong = "chasr" and right = "chase" - or - wrong = "chasr" and right = "chaser" - or - wrong = "cheif" and right = "chief" - or - wrong = "cheifs" and right = "chiefs" - or - wrong = "chemcial" and right = "chemical" - or - wrong = "chemcially" and right = "chemically" - or - wrong = "chemestry" and right = "chemistry" - or - wrong = "chemicaly" and right = "chemically" - or - wrong = "childbird" and right = "childbirth" - or - wrong = "childen" and right = "children" - or - wrong = "choclate" and right = "chocolate" - or - wrong = "choosen" and right = "chosen" - or - wrong = "chracter" and right = "character" - or - wrong = "chuch" and right = "church" - or - wrong = "churchs" and right = "churches" - or - wrong = "cincinatti" and right = "cincinnati" - or - wrong = "cincinnatti" and right = "cincinnati" - or - wrong = "circulaton" and right = "circulation" - or - wrong = "circumsicion" and right = "circumcision" - or - wrong = "circut" and right = "circuit" - or - wrong = "ciricuit" and right = "circuit" - or - wrong = "ciriculum" and right = "curriculum" - or - wrong = "civillian" and right = "civilian" - or - wrong = "claer" and right = "clear" - or - wrong = "claerer" and right = "clearer" - or - wrong = "claerly" and right = "clearly" - or - wrong = "claimes" and right = "claims" - or - wrong = "clas" and right = "class" - or - wrong = "clasic" and right = "classic" - or - wrong = "clasical" and right = "classical" - or - wrong = "clasically" and right = "classically" - or - wrong = "cleareance" and right = "clearance" - or - wrong = "clera" and right = "clear" - or - wrong = "clera" and right = "sclera" - or - wrong = "clincial" and right = "clinical" - or - wrong = "clinicaly" and right = "clinically" - or - wrong = "cmo" and right = "com" - or - wrong = "cmoputer" and right = "computer" - or - wrong = "coctail" and right = "cocktail" - or - wrong = "coform" and right = "conform" - or - wrong = "cognizent" and right = "cognizant" - or - wrong = "coincedentally" and right = "coincidentally" - or - wrong = "colaborations" and right = "collaborations" - or - wrong = "colateral" and right = "collateral" - or - wrong = "colelctive" and right = "collective" - or - wrong = "collaberative" and right = "collaborative" - or - wrong = "collecton" and right = "collection" - or - wrong = "collegue" and right = "colleague" - or - wrong = "collegues" and right = "colleagues" - or - wrong = "collonade" and right = "colonnade" - or - wrong = "collonies" and right = "colonies" - or - wrong = "collony" and right = "colony" - or - wrong = "collosal" and right = "colossal" - or - wrong = "colonizators" and right = "colonizers" - or - wrong = "comander" and right = "commandeer" - or - wrong = "comander" and right = "commander" - or - wrong = "comando" and right = "commando" - or - wrong = "comandos" and right = "commandos" - or - wrong = "comany" and right = "company" - or - wrong = "comapany" and right = "company" - or - wrong = "comback" and right = "comeback" - or - wrong = "combanations" and right = "combinations" - or - wrong = "combinatins" and right = "combinations" - or - wrong = "combusion" and right = "combustion" - or - wrong = "comdemnation" and right = "condemnation" - or - wrong = "comemmorates" and right = "commemorates" - or - wrong = "comemoretion" and right = "commemoration" - or - wrong = "comision" and right = "commission" - or - wrong = "comisioned" and right = "commissioned" - or - wrong = "comisioner" and right = "commissioner" - or - wrong = "comisioning" and right = "commissioning" - or - wrong = "comisions" and right = "commissions" - or - wrong = "comission" and right = "commission" - or - wrong = "comissioned" and right = "commissioned" - or - wrong = "comissioner" and right = "commissioner" - or - wrong = "comissioning" and right = "commissioning" - or - wrong = "comissions" and right = "commissions" - or - wrong = "comited" and right = "committed" - or - wrong = "comiting" and right = "committing" - or - wrong = "comitted" and right = "committed" - or - wrong = "comittee" and right = "committee" - or - wrong = "comitting" and right = "committing" - or - wrong = "commandoes" and right = "commandos" - or - wrong = "commedic" and right = "comedic" - or - wrong = "commemerative" and right = "commemorative" - or - wrong = "commemmorate" and right = "commemorate" - or - wrong = "commemmorating" and right = "commemorating" - or - wrong = "commerical" and right = "commercial" - or - wrong = "commerically" and right = "commercially" - or - wrong = "commericial" and right = "commercial" - or - wrong = "commericially" and right = "commercially" - or - wrong = "commerorative" and right = "commemorative" - or - wrong = "comming" and right = "coming" - or - wrong = "comminication" and right = "communication" - or - wrong = "commision" and right = "commission" - or - wrong = "commisioned" and right = "commissioned" - or - wrong = "commisioner" and right = "commissioner" - or - wrong = "commisioning" and right = "commissioning" - or - wrong = "commisions" and right = "commissions" - or - wrong = "commited" and right = "committed" - or - wrong = "commitee" and right = "committee" - or - wrong = "commiting" and right = "committing" - or - wrong = "committe" and right = "committee" - or - wrong = "committment" and right = "commitment" - or - wrong = "committments" and right = "commitments" - or - wrong = "commmemorated" and right = "commemorated" - or - wrong = "commongly" and right = "commonly" - or - wrong = "commonweath" and right = "commonwealth" - or - wrong = "commuications" and right = "communications" - or - wrong = "commuinications" and right = "communications" - or - wrong = "communciation" and right = "communication" - or - wrong = "communiation" and right = "communication" - or - wrong = "communites" and right = "communities" - or - wrong = "compability" and right = "compatibility" - or - wrong = "comparision" and right = "comparison" - or - wrong = "comparisions" and right = "comparisons" - or - wrong = "comparitive" and right = "comparative" - or - wrong = "comparitively" and right = "comparatively" - or - wrong = "compatabilities" and right = "compatibilities" - or - wrong = "compatability" and right = "compatibility" - or - wrong = "compatable" and right = "compatible" - or - wrong = "compatablities" and right = "compatibilities" - or - wrong = "compatablity" and right = "compatibility" - or - wrong = "compatiable" and right = "compatible" - or - wrong = "compatiblities" and right = "compatibilities" - or - wrong = "compatiblity" and right = "compatibility" - or - wrong = "compeitions" and right = "competitions" - or - wrong = "compensantion" and right = "compensation" - or - wrong = "competance" and right = "competence" - or - wrong = "competant" and right = "competent" - or - wrong = "competative" and right = "competitive" - or - wrong = "competion" and right = "competition" - or - wrong = "competion" and right = "completion" - or - wrong = "competitiion" and right = "competition" - or - wrong = "competive" and right = "competitive" - or - wrong = "competiveness" and right = "competitiveness" - or - wrong = "comphrehensive" and right = "comprehensive" - or - wrong = "compitent" and right = "competent" - or - wrong = "completelyl" and right = "completely" - or - wrong = "completetion" and right = "completion" - or - wrong = "complier" and right = "compiler" - or - wrong = "componant" and right = "component" - or - wrong = "comprable" and right = "comparable" - or - wrong = "comprimise" and right = "compromise" - or - wrong = "compulsary" and right = "compulsory" - or - wrong = "compulsery" and right = "compulsory" - or - wrong = "computarized" and right = "computerized" - or - wrong = "concensus" and right = "consensus" - or - wrong = "concider" and right = "consider" - or - wrong = "concidered" and right = "considered" - or - wrong = "concidering" and right = "considering" - or - wrong = "conciders" and right = "considers" - or - wrong = "concieted" and right = "conceited" - or - wrong = "concieved" and right = "conceived" - or - wrong = "concious" and right = "conscious" - or - wrong = "conciously" and right = "consciously" - or - wrong = "conciousness" and right = "consciousness" - or - wrong = "condamned" and right = "condemned" - or - wrong = "condemmed" and right = "condemned" - or - wrong = "condidtion" and right = "condition" - or - wrong = "condidtions" and right = "conditions" - or - wrong = "conected" and right = "connected" - or - wrong = "conection" and right = "connection" - or - wrong = "conesencus" and right = "consensus" - or - wrong = "confidental" and right = "confidential" - or - wrong = "confidentally" and right = "confidentially" - or - wrong = "confids" and right = "confides" - or - wrong = "configureable" and right = "configurable" - or - wrong = "confortable" and right = "comfortable" - or - wrong = "congradulations" and right = "congratulations" - or - wrong = "congresional" and right = "congressional" - or - wrong = "conived" and right = "connived" - or - wrong = "conjecutre" and right = "conjecture" - or - wrong = "conjuction" and right = "conjunction" - or - wrong = "connectinos" and right = "connections" - or - wrong = "conneticut" and right = "connecticut" - or - wrong = "conotations" and right = "connotations" - or - wrong = "conquerd" and right = "conquered" - or - wrong = "conquerer" and right = "conqueror" - or - wrong = "conquerers" and right = "conquerors" - or - wrong = "conqured" and right = "conquered" - or - wrong = "conscent" and right = "consent" - or - wrong = "consciouness" and right = "consciousness" - or - wrong = "consdider" and right = "consider" - or - wrong = "consdidered" and right = "considered" - or - wrong = "consdiered" and right = "considered" - or - wrong = "consectutive" and right = "consecutive" - or - wrong = "consenquently" and right = "consequently" - or - wrong = "consentrate" and right = "concentrate" - or - wrong = "consentrated" and right = "concentrated" - or - wrong = "consentrates" and right = "concentrates" - or - wrong = "consept" and right = "concept" - or - wrong = "consequentually" and right = "consequently" - or - wrong = "consequeseces" and right = "consequences" - or - wrong = "consern" and right = "concern" - or - wrong = "conserned" and right = "concerned" - or - wrong = "conserning" and right = "concerning" - or - wrong = "conservitive" and right = "conservative" - or - wrong = "consiciousness" and right = "consciousness" - or - wrong = "consicousness" and right = "consciousness" - or - wrong = "considerd" and right = "considered" - or - wrong = "consideres" and right = "considered" - or - wrong = "consious" and right = "conscious" - or - wrong = "consistant" and right = "consistent" - or - wrong = "consistantly" and right = "consistently" - or - wrong = "consituencies" and right = "constituencies" - or - wrong = "consituency" and right = "constituency" - or - wrong = "consituted" and right = "constituted" - or - wrong = "consitution" and right = "constitution" - or - wrong = "consitutional" and right = "constitutional" - or - wrong = "consolodate" and right = "consolidate" - or - wrong = "consolodated" and right = "consolidated" - or - wrong = "consonent" and right = "consonant" - or - wrong = "consonents" and right = "consonants" - or - wrong = "consorcium" and right = "consortium" - or - wrong = "conspiracys" and right = "conspiracies" - or - wrong = "conspiriator" and right = "conspirator" - or - wrong = "consructor" and right = "constructor" - or - wrong = "constaints" and right = "constraints" - or - wrong = "constanly" and right = "constantly" - or - wrong = "constarnation" and right = "consternation" - or - wrong = "constatn" and right = "constant" - or - wrong = "constinually" and right = "continually" - or - wrong = "constituant" and right = "constituent" - or - wrong = "constituants" and right = "constituents" - or - wrong = "constituion" and right = "constitution" - or - wrong = "constituional" and right = "constitutional" - or - wrong = "consttruction" and right = "construction" - or - wrong = "constuction" and right = "construction" - or - wrong = "consulant" and right = "consultant" - or - wrong = "consumate" and right = "consummate" - or - wrong = "consumated" and right = "consummated" - or - wrong = "contaiminate" and right = "contaminate" - or - wrong = "containes" and right = "contains" - or - wrong = "contamporaries" and right = "contemporaries" - or - wrong = "contamporary" and right = "contemporary" - or - wrong = "contempoary" and right = "contemporary" - or - wrong = "contemporaneus" and right = "contemporaneous" - or - wrong = "contempory" and right = "contemporary" - or - wrong = "contendor" and right = "contender" - or - wrong = "contian" and right = "contain" - or - wrong = "contians" and right = "contains" - or - wrong = "contibute" and right = "contribute" - or - wrong = "contibuted" and right = "contributed" - or - wrong = "contibutes" and right = "contributes" - or - wrong = "contigent" and right = "contingent" - or - wrong = "contined" and right = "continued" - or - wrong = "continential" and right = "continental" - or - wrong = "continous" and right = "continuous" - or - wrong = "continously" and right = "continuously" - or - wrong = "continueing" and right = "continuing" - or - wrong = "contravercial" and right = "controversial" - or - wrong = "contraversy" and right = "controversy" - or - wrong = "contributer" and right = "contributor" - or - wrong = "contributers" and right = "contributors" - or - wrong = "contritutions" and right = "contributions" - or - wrong = "controled" and right = "controlled" - or - wrong = "controling" and right = "controlling" - or - wrong = "controll" and right = "control" - or - wrong = "controlls" and right = "controls" - or - wrong = "controvercial" and right = "controversial" - or - wrong = "controvercy" and right = "controversy" - or - wrong = "controveries" and right = "controversies" - or - wrong = "controversal" and right = "controversial" - or - wrong = "controversey" and right = "controversy" - or - wrong = "controvertial" and right = "controversial" - or - wrong = "controvery" and right = "controversy" - or - wrong = "contruction" and right = "construction" - or - wrong = "contructor" and right = "constructor" - or - wrong = "contstruction" and right = "construction" - or - wrong = "conveinent" and right = "convenient" - or - wrong = "convenant" and right = "covenant" - or - wrong = "convential" and right = "conventional" - or - wrong = "convertables" and right = "convertibles" - or - wrong = "convertion" and right = "conversion" - or - wrong = "conviced" and right = "convinced" - or - wrong = "convienient" and right = "convenient" - or - wrong = "coordiantion" and right = "coordination" - or - wrong = "coorperation" and right = "cooperation" - or - wrong = "coorperation" and right = "corporation" - or - wrong = "coorperations" and right = "corporations" - or - wrong = "copmetitors" and right = "competitors" - or - wrong = "coputer" and right = "computer" - or - wrong = "copywrite" and right = "copyright" - or - wrong = "coridal" and right = "cordial" - or - wrong = "cornmitted" and right = "committed" - or - wrong = "corosion" and right = "corrosion" - or - wrong = "corparate" and right = "corporate" - or - wrong = "corperations" and right = "corporations" - or - wrong = "correcters" and right = "correctors" - or - wrong = "correponding" and right = "corresponding" - or - wrong = "correposding" and right = "corresponding" - or - wrong = "correspondant" and right = "correspondent" - or - wrong = "correspondants" and right = "correspondents" - or - wrong = "corridoors" and right = "corridors" - or - wrong = "corrispond" and right = "correspond" - or - wrong = "corrispondant" and right = "correspondent" - or - wrong = "corrispondants" and right = "correspondents" - or - wrong = "corrisponded" and right = "corresponded" - or - wrong = "corrisponding" and right = "corresponding" - or - wrong = "corrisponds" and right = "corresponds" - or - wrong = "costitution" and right = "constitution" - or - wrong = "coucil" and right = "council" - or - wrong = "coudl" and right = "cloud" - or - wrong = "coudl" and right = "could" - or - wrong = "councellor" and right = "councillor" - or - wrong = "councellor" and right = "councilor" - or - wrong = "councellor" and right = "counselor" - or - wrong = "councellors" and right = "councillors" - or - wrong = "councellors" and right = "councilors" - or - wrong = "councellors" and right = "counselors" - or - wrong = "counries" and right = "countries" - or - wrong = "countains" and right = "contains" - or - wrong = "countires" and right = "countries" - or - wrong = "coururier" and right = "courier" - or - wrong = "coururier" and right = "couturier" - or - wrong = "coverted" and right = "converted" - or - wrong = "coverted" and right = "covered" - or - wrong = "coverted" and right = "coveted" - or - wrong = "cpoy" and right = "copy" - or - wrong = "cpoy" and right = "coy" - or - wrong = "creaeted" and right = "created" - or - wrong = "creedence" and right = "credence" - or - wrong = "critereon" and right = "criterion" - or - wrong = "criterias" and right = "criteria" - or - wrong = "criticists" and right = "critics" - or - wrong = "critising" and right = "criticising" - or - wrong = "critising" and right = "criticizing" - or - wrong = "critisising" and right = "criticising" - or - wrong = "critisism" and right = "criticism" - or - wrong = "critisisms" and right = "criticisms" - or - wrong = "critisize" and right = "criticise" - or - wrong = "critisize" and right = "criticize" - or - wrong = "critisized" and right = "criticised" - or - wrong = "critisized" and right = "criticized" - or - wrong = "critisizes" and right = "criticises" - or - wrong = "critisizes" and right = "criticizes" - or - wrong = "critisizing" and right = "criticising" - or - wrong = "critisizing" and right = "criticizing" - or - wrong = "critized" and right = "criticized" - or - wrong = "critizing" and right = "criticizing" - or - wrong = "crockodiles" and right = "crocodiles" - or - wrong = "crowm" and right = "crown" - or - wrong = "crtical" and right = "critical" - or - wrong = "crticised" and right = "criticised" - or - wrong = "crucifiction" and right = "crucifixion" - or - wrong = "crusies" and right = "cruises" - or - wrong = "crutial" and right = "crucial" - or - wrong = "crystalisation" and right = "crystallisation" - or - wrong = "culiminating" and right = "culminating" - or - wrong = "cumulatative" and right = "cumulative" - or - wrong = "curch" and right = "church" - or - wrong = "curcuit" and right = "circuit" - or - wrong = "currenly" and right = "currently" - or - wrong = "curriculem" and right = "curriculum" - or - wrong = "cxan" and right = "cyan" - or - wrong = "cyclinder" and right = "cylinder" - or - wrong = "dacquiri" and right = "daiquiri" - or - wrong = "daed" and right = "dead" - or - wrong = "dael" and right = "dahl" - or - wrong = "dael" and right = "deal" - or - wrong = "dael" and right = "dial" - or - wrong = "dalmation" and right = "dalmatian" - or - wrong = "damenor" and right = "demeanor" - or - wrong = "dammage" and right = "damage" - or - wrong = "dardenelles" and right = "dardanelles" - or - wrong = "daugher" and right = "daughter" - or - wrong = "deafult" and right = "default" - or - wrong = "debateable" and right = "debatable" - or - wrong = "decendant" and right = "descendant" - or - wrong = "decendants" and right = "descendants" - or - wrong = "decendent" and right = "descendant" - or - wrong = "decendents" and right = "descendants" - or - wrong = "decideable" and right = "decidable" - or - wrong = "decidely" and right = "decidedly" - or - wrong = "decieved" and right = "deceived" - or - wrong = "decison" and right = "decision" - or - wrong = "decomissioned" and right = "decommissioned" - or - wrong = "decomposit" and right = "decompose" - or - wrong = "decomposited" and right = "decomposed" - or - wrong = "decompositing" and right = "decomposing" - or - wrong = "decomposits" and right = "decomposes" - or - wrong = "decress" and right = "decrees" - or - wrong = "decribe" and right = "describe" - or - wrong = "decribed" and right = "described" - or - wrong = "decribes" and right = "describes" - or - wrong = "decribing" and right = "describing" - or - wrong = "dectect" and right = "detect" - or - wrong = "defendent" and right = "defendant" - or - wrong = "defendents" and right = "defendants" - or - wrong = "deffensively" and right = "defensively" - or - wrong = "deffine" and right = "define" - or - wrong = "deffined" and right = "defined" - or - wrong = "definance" and right = "defiance" - or - wrong = "definate" and right = "definite" - or - wrong = "definately" and right = "definitely" - or - wrong = "definatly" and right = "definitely" - or - wrong = "definetly" and right = "definitely" - or - wrong = "definining" and right = "defining" - or - wrong = "definit" and right = "definite" - or - wrong = "definitly" and right = "definitely" - or - wrong = "definiton" and right = "definition" - or - wrong = "defintion" and right = "definition" - or - wrong = "defualt" and right = "default" - or - wrong = "defult" and right = "default" - or - wrong = "degrate" and right = "degrade" - or - wrong = "delagates" and right = "delegates" - or - wrong = "delapidated" and right = "dilapidated" - or - wrong = "delerious" and right = "delirious" - or - wrong = "delevopment" and right = "development" - or - wrong = "deliberatly" and right = "deliberately" - or - wrong = "delusionally" and right = "delusively" - or - wrong = "demenor" and right = "demeanor" - or - wrong = "demographical" and right = "demographic" - or - wrong = "demolision" and right = "demolition" - or - wrong = "demorcracy" and right = "democracy" - or - wrong = "demostration" and right = "demonstration" - or - wrong = "denegrating" and right = "denigrating" - or - wrong = "densly" and right = "densely" - or - wrong = "deparment" and right = "department" - or - wrong = "deparmental" and right = "departmental" - or - wrong = "deparments" and right = "departments" - or - wrong = "dependance" and right = "dependence" - or - wrong = "dependancy" and right = "dependency" - or - wrong = "deram" and right = "dram" - or - wrong = "deram" and right = "dream" - or - wrong = "deriviated" and right = "derived" - or - wrong = "derivitive" and right = "derivative" - or - wrong = "derogitory" and right = "derogatory" - or - wrong = "descendands" and right = "descendants" - or - wrong = "descibed" and right = "described" - or - wrong = "desciptors" and right = "descriptors" - or - wrong = "descision" and right = "decision" - or - wrong = "descisions" and right = "decisions" - or - wrong = "descriibes" and right = "describes" - or - wrong = "descripters" and right = "descriptors" - or - wrong = "descripton" and right = "description" - or - wrong = "desctruction" and right = "destruction" - or - wrong = "descuss" and right = "discuss" - or - wrong = "desgined" and right = "designed" - or - wrong = "deside" and right = "decide" - or - wrong = "desigining" and right = "designing" - or - wrong = "desinations" and right = "destinations" - or - wrong = "desintegrated" and right = "disintegrated" - or - wrong = "desintegration" and right = "disintegration" - or - wrong = "desireable" and right = "desirable" - or - wrong = "desitned" and right = "destined" - or - wrong = "desktiop" and right = "desktop" - or - wrong = "desorder" and right = "disorder" - or - wrong = "desoriented" and right = "disoriented" - or - wrong = "desparate" and right = "desperate" - or - wrong = "desparate" and right = "disparate" - or - wrong = "despict" and right = "depict" - or - wrong = "despiration" and right = "desperation" - or - wrong = "dessicated" and right = "desiccated" - or - wrong = "dessigned" and right = "designed" - or - wrong = "destablized" and right = "destabilized" - or - wrong = "destory" and right = "destroy" - or - wrong = "desugered" and right = "desugared" - or - wrong = "detailled" and right = "detailed" - or - wrong = "detatched" and right = "detached" - or - wrong = "deteoriated" and right = "deteriorated" - or - wrong = "deteriate" and right = "deteriorate" - or - wrong = "deterioriating" and right = "deteriorating" - or - wrong = "determinining" and right = "determining" - or - wrong = "detremental" and right = "detrimental" - or - wrong = "devasted" and right = "devastated" - or - wrong = "develope" and right = "develop" - or - wrong = "developement" and right = "development" - or - wrong = "developped" and right = "developed" - or - wrong = "develpment" and right = "development" - or - wrong = "devels" and right = "delves" - or - wrong = "devestated" and right = "devastated" - or - wrong = "devestating" and right = "devastating" - or - wrong = "devide" and right = "divide" - or - wrong = "devided" and right = "divided" - or - wrong = "devistating" and right = "devastating" - or - wrong = "devolopement" and right = "development" - or - wrong = "diablical" and right = "diabolical" - or - wrong = "diamons" and right = "diamonds" - or - wrong = "diaster" and right = "disaster" - or - wrong = "dichtomy" and right = "dichotomy" - or - wrong = "diconnects" and right = "disconnects" - or - wrong = "dicover" and right = "discover" - or - wrong = "dicovered" and right = "discovered" - or - wrong = "dicovering" and right = "discovering" - or - wrong = "dicovers" and right = "discovers" - or - wrong = "dicovery" and right = "discovery" - or - wrong = "dictionarys" and right = "dictionaries" - or - wrong = "dicussed" and right = "discussed" - or - wrong = "diea" and right = "die" - or - wrong = "diea" and right = "idea" - or - wrong = "dieing" and right = "dyeing" - or - wrong = "dieing" and right = "dying" - or - wrong = "dieties" and right = "deities" - or - wrong = "diety" and right = "deity" - or - wrong = "diferent" and right = "different" - or - wrong = "diferrent" and right = "different" - or - wrong = "differentiatiations" and right = "differentiations" - or - wrong = "differnt" and right = "different" - or - wrong = "difficulity" and right = "difficulty" - or - wrong = "diffrent" and right = "different" - or - wrong = "dificulties" and right = "difficulties" - or - wrong = "dificulty" and right = "difficulty" - or - wrong = "dimenions" and right = "dimensions" - or - wrong = "dimention" and right = "dimension" - or - wrong = "dimentional" and right = "dimensional" - or - wrong = "dimentions" and right = "dimensions" - or - wrong = "dimesnional" and right = "dimensional" - or - wrong = "diminuitive" and right = "diminutive" - or - wrong = "dimunitive" and right = "diminutive" - or - wrong = "diosese" and right = "diocese" - or - wrong = "diphtong" and right = "diphthong" - or - wrong = "diphtongs" and right = "diphthongs" - or - wrong = "diplomancy" and right = "diplomacy" - or - wrong = "dipthong" and right = "diphthong" - or - wrong = "dipthongs" and right = "diphthongs" - or - wrong = "directoty" and right = "directory" - or - wrong = "dirived" and right = "derived" - or - wrong = "disagreeed" and right = "disagreed" - or - wrong = "disapeared" and right = "disappeared" - or - wrong = "disapointing" and right = "disappointing" - or - wrong = "disappearred" and right = "disappeared" - or - wrong = "disaproval" and right = "disapproval" - or - wrong = "disasterous" and right = "disastrous" - or - wrong = "disatisfaction" and right = "dissatisfaction" - or - wrong = "disatisfied" and right = "dissatisfied" - or - wrong = "disatrous" and right = "disastrous" - or - wrong = "discontentment" and right = "discontent" - or - wrong = "discribe" and right = "describe" - or - wrong = "discribed" and right = "described" - or - wrong = "discribes" and right = "describes" - or - wrong = "discribing" and right = "describing" - or - wrong = "disctinction" and right = "distinction" - or - wrong = "disctinctive" and right = "distinctive" - or - wrong = "disemination" and right = "dissemination" - or - wrong = "disenchanged" and right = "disenchanted" - or - wrong = "disiplined" and right = "disciplined" - or - wrong = "disobediance" and right = "disobedience" - or - wrong = "disobediant" and right = "disobedient" - or - wrong = "disolved" and right = "dissolved" - or - wrong = "disover" and right = "discover" - or - wrong = "dispair" and right = "despair" - or - wrong = "disparingly" and right = "disparagingly" - or - wrong = "dispence" and right = "dispense" - or - wrong = "dispenced" and right = "dispensed" - or - wrong = "dispencing" and right = "dispensing" - or - wrong = "dispicable" and right = "despicable" - or - wrong = "dispite" and right = "despite" - or - wrong = "dispostion" and right = "disposition" - or - wrong = "disproportiate" and right = "disproportionate" - or - wrong = "disputandem" and right = "disputandum" - or - wrong = "disricts" and right = "districts" - or - wrong = "dissagreement" and right = "disagreement" - or - wrong = "dissapear" and right = "disappear" - or - wrong = "dissapearance" and right = "disappearance" - or - wrong = "dissapeared" and right = "disappeared" - or - wrong = "dissapearing" and right = "disappearing" - or - wrong = "dissapears" and right = "disappears" - or - wrong = "dissappear" and right = "disappear" - or - wrong = "dissappears" and right = "disappears" - or - wrong = "dissappointed" and right = "disappointed" - or - wrong = "dissarray" and right = "disarray" - or - wrong = "dissobediance" and right = "disobedience" - or - wrong = "dissobediant" and right = "disobedient" - or - wrong = "dissobedience" and right = "disobedience" - or - wrong = "dissobedient" and right = "disobedient" - or - wrong = "distiction" and right = "distinction" - or - wrong = "distingish" and right = "distinguish" - or - wrong = "distingished" and right = "distinguished" - or - wrong = "distingishes" and right = "distinguishes" - or - wrong = "distingishing" and right = "distinguishing" - or - wrong = "distingquished" and right = "distinguished" - or - wrong = "distrubution" and right = "distribution" - or - wrong = "distruction" and right = "destruction" - or - wrong = "distructive" and right = "destructive" - or - wrong = "ditributed" and right = "distributed" - or - wrong = "diversed" and right = "diverged" - or - wrong = "diversed" and right = "diverse" - or - wrong = "divice" and right = "device" - or - wrong = "divinition" and right = "divination" - or - wrong = "divison" and right = "division" - or - wrong = "divisons" and right = "divisions" - or - wrong = "doccument" and right = "document" - or - wrong = "doccumented" and right = "documented" - or - wrong = "doccuments" and right = "documents" - or - wrong = "docrines" and right = "doctrines" - or - wrong = "doctines" and right = "doctrines" - or - wrong = "documenatry" and right = "documentary" - or - wrong = "doens" and right = "does" - or - wrong = "doign" and right = "doing" - or - wrong = "dominaton" and right = "domination" - or - wrong = "dominent" and right = "dominant" - or - wrong = "dominiant" and right = "dominant" - or - wrong = "donig" and right = "doing" - or - wrong = "doub" and right = "daub" - or - wrong = "doub" and right = "doubt" - or - wrong = "doulbe" and right = "double" - or - wrong = "dowloads" and right = "downloads" - or - wrong = "dramtic" and right = "dramatic" - or - wrong = "draughtman" and right = "draughtsman" - or - wrong = "dravadian" and right = "dravidian" - or - wrong = "dreasm" and right = "dreams" - or - wrong = "driectly" and right = "directly" - or - wrong = "drnik" and right = "drink" - or - wrong = "druming" and right = "drumming" - or - wrong = "drummless" and right = "drumless" - or - wrong = "dum" and right = "dumb" - or - wrong = "dupicate" and right = "duplicate" - or - wrong = "durig" and right = "during" - or - wrong = "durring" and right = "during" - or - wrong = "duting" and right = "during" - or - wrong = "dyas" and right = "dryas" - or - wrong = "eahc" and right = "each" - or - wrong = "ealier" and right = "earlier" - or - wrong = "earlies" and right = "earliest" - or - wrong = "earnt" and right = "earned" - or - wrong = "ecclectic" and right = "eclectic" - or - wrong = "eceonomy" and right = "economy" - or - wrong = "ecidious" and right = "deciduous" - or - wrong = "eclispe" and right = "eclipse" - or - wrong = "ecomonic" and right = "economic" - or - wrong = "ect" and right = "etc" - or - wrong = "editting" and right = "editing" - or - wrong = "eearly" and right = "early" - or - wrong = "efel" and right = "evil" - or - wrong = "effeciency" and right = "efficiency" - or - wrong = "effecient" and right = "efficient" - or - wrong = "effeciently" and right = "efficiently" - or - wrong = "efficency" and right = "efficiency" - or - wrong = "efficent" and right = "efficient" - or - wrong = "efficently" and right = "efficiently" - or - wrong = "efford" and right = "afford" - or - wrong = "efford" and right = "effort" - or - wrong = "effords" and right = "affords" - or - wrong = "effords" and right = "efforts" - or - wrong = "effulence" and right = "effluence" - or - wrong = "eigth" and right = "eight" - or - wrong = "eigth" and right = "eighth" - or - wrong = "eiter" and right = "either" - or - wrong = "elction" and right = "election" - or - wrong = "electic" and right = "eclectic" - or - wrong = "electic" and right = "electric" - or - wrong = "electon" and right = "election" - or - wrong = "electon" and right = "electron" - or - wrong = "electrial" and right = "electrical" - or - wrong = "electricly" and right = "electrically" - or - wrong = "electricty" and right = "electricity" - or - wrong = "elementay" and right = "elementary" - or - wrong = "eleminated" and right = "eliminated" - or - wrong = "eleminating" and right = "eliminating" - or - wrong = "eles" and right = "eels" - or - wrong = "eletricity" and right = "electricity" - or - wrong = "elicided" and right = "elicited" - or - wrong = "eligable" and right = "eligible" - or - wrong = "elimentary" and right = "elementary" - or - wrong = "ellected" and right = "elected" - or - wrong = "elphant" and right = "elephant" - or - wrong = "embarass" and right = "embarrass" - or - wrong = "embarassed" and right = "embarrassed" - or - wrong = "embarassing" and right = "embarrassing" - or - wrong = "embarassment" and right = "embarrassment" - or - wrong = "embargos" and right = "embargoes" - or - wrong = "embarras" and right = "embarrass" - or - wrong = "embarrased" and right = "embarrassed" - or - wrong = "embarrasing" and right = "embarrassing" - or - wrong = "embarrasment" and right = "embarrassment" - or - wrong = "embezelled" and right = "embezzled" - or - wrong = "emblamatic" and right = "emblematic" - or - wrong = "eminate" and right = "emanate" - or - wrong = "eminated" and right = "emanated" - or - wrong = "emision" and right = "emission" - or - wrong = "emited" and right = "emitted" - or - wrong = "emiting" and right = "emitting" - or - wrong = "emition" and right = "emission" - or - wrong = "emition" and right = "emotion" - or - wrong = "emmediately" and right = "immediately" - or - wrong = "emmigrated" and right = "emigrated" - or - wrong = "emmigrated" and right = "immigrated" - or - wrong = "emminent" and right = "eminent" - or - wrong = "emminent" and right = "imminent" - or - wrong = "emminently" and right = "eminently" - or - wrong = "emmisaries" and right = "emissaries" - or - wrong = "emmisarries" and right = "emissaries" - or - wrong = "emmisarry" and right = "emissary" - or - wrong = "emmisary" and right = "emissary" - or - wrong = "emmision" and right = "emission" - or - wrong = "emmisions" and right = "emissions" - or - wrong = "emmited" and right = "emitted" - or - wrong = "emmiting" and right = "emitting" - or - wrong = "emmitted" and right = "emitted" - or - wrong = "emmitting" and right = "emitting" - or - wrong = "emnity" and right = "enmity" - or - wrong = "emperical" and right = "empirical" - or - wrong = "emphaised" and right = "emphasised" - or - wrong = "emphsis" and right = "emphasis" - or - wrong = "emphysyma" and right = "emphysema" - or - wrong = "empirial" and right = "empirical" - or - wrong = "empirial" and right = "imperial" - or - wrong = "emporer" and right = "emperor" - or - wrong = "emprisoned" and right = "imprisoned" - or - wrong = "enameld" and right = "enameled" - or - wrong = "enchancement" and right = "enhancement" - or - wrong = "encouraing" and right = "encouraging" - or - wrong = "encryptiion" and right = "encryption" - or - wrong = "encylopedia" and right = "encyclopedia" - or - wrong = "endevors" and right = "endeavors" - or - wrong = "endevour" and right = "endeavour" - or - wrong = "endig" and right = "ending" - or - wrong = "endolithes" and right = "endoliths" - or - wrong = "enduce" and right = "induce" - or - wrong = "ened" and right = "need" - or - wrong = "enforceing" and right = "enforcing" - or - wrong = "engagment" and right = "engagement" - or - wrong = "engeneer" and right = "engineer" - or - wrong = "engeneering" and right = "engineering" - or - wrong = "engieneer" and right = "engineer" - or - wrong = "engieneers" and right = "engineers" - or - wrong = "enlargment" and right = "enlargement" - or - wrong = "enlargments" and right = "enlargements" - or - wrong = "enlish" and right = "english" - or - wrong = "enlish" and right = "enlist" - or - wrong = "enourmous" and right = "enormous" - or - wrong = "enourmously" and right = "enormously" - or - wrong = "ensconsed" and right = "ensconced" - or - wrong = "entaglements" and right = "entanglements" - or - wrong = "enteratinment" and right = "entertainment" - or - wrong = "enthusiatic" and right = "enthusiastic" - or - wrong = "entitity" and right = "entity" - or - wrong = "entitlied" and right = "entitled" - or - wrong = "entrepeneur" and right = "entrepreneur" - or - wrong = "entrepeneurs" and right = "entrepreneurs" - or - wrong = "enviorment" and right = "environment" - or - wrong = "enviormental" and right = "environmental" - or - wrong = "enviormentally" and right = "environmentally" - or - wrong = "enviorments" and right = "environments" - or - wrong = "enviornment" and right = "environment" - or - wrong = "enviornmental" and right = "environmental" - or - wrong = "enviornmentalist" and right = "environmentalist" - or - wrong = "enviornmentally" and right = "environmentally" - or - wrong = "enviornments" and right = "environments" - or - wrong = "enviroment" and right = "environment" - or - wrong = "enviromental" and right = "environmental" - or - wrong = "enviromentalist" and right = "environmentalist" - or - wrong = "enviromentally" and right = "environmentally" - or - wrong = "enviroments" and right = "environments" - or - wrong = "environemnt" and right = "environment" - or - wrong = "envolutionary" and right = "evolutionary" - or - wrong = "envrionments" and right = "environments" - or - wrong = "enxt" and right = "next" - or - wrong = "epidsodes" and right = "episodes" - or - wrong = "epsiode" and right = "episode" - or - wrong = "equialent" and right = "equivalent" - or - wrong = "equilibium" and right = "equilibrium" - or - wrong = "equilibrum" and right = "equilibrium" - or - wrong = "equiped" and right = "equipped" - or - wrong = "equippment" and right = "equipment" - or - wrong = "equitorial" and right = "equatorial" - or - wrong = "equivelant" and right = "equivalent" - or - wrong = "equivelent" and right = "equivalent" - or - wrong = "equivilant" and right = "equivalent" - or - wrong = "equivilent" and right = "equivalent" - or - wrong = "equivlalent" and right = "equivalent" - or - wrong = "erally" and right = "orally" - or - wrong = "erally" and right = "really" - or - wrong = "eratic" and right = "erratic" - or - wrong = "eratically" and right = "erratically" - or - wrong = "eraticly" and right = "erratically" - or - wrong = "erested" and right = "arrested" - or - wrong = "erested" and right = "erected" - or - wrong = "errupted" and right = "erupted" - or - wrong = "esential" and right = "essential" - or - wrong = "esitmated" and right = "estimated" - or - wrong = "esle" and right = "else" - or - wrong = "especialy" and right = "especially" - or - wrong = "essencial" and right = "essential" - or - wrong = "essense" and right = "essence" - or - wrong = "essentail" and right = "essential" - or - wrong = "essentialy" and right = "essentially" - or - wrong = "essentual" and right = "essential" - or - wrong = "essesital" and right = "essential" - or - wrong = "estabishes" and right = "establishes" - or - wrong = "establising" and right = "establishing" - or - wrong = "ethnocentricm" and right = "ethnocentrism" - or - wrong = "ethose" and right = "ethos" - or - wrong = "ethose" and right = "those" - or - wrong = "europian" and right = "european" - or - wrong = "europians" and right = "europeans" - or - wrong = "eurpean" and right = "european" - or - wrong = "eurpoean" and right = "european" - or - wrong = "evenhtually" and right = "eventually" - or - wrong = "eventally" and right = "eventually" - or - wrong = "eventially" and right = "eventually" - or - wrong = "eventualy" and right = "eventually" - or - wrong = "everthing" and right = "everything" - or - wrong = "everyting" and right = "everything" - or - wrong = "eveyr" and right = "every" - or - wrong = "evidentally" and right = "evidently" - or - wrong = "exagerate" and right = "exaggerate" - or - wrong = "exagerated" and right = "exaggerated" - or - wrong = "exagerates" and right = "exaggerates" - or - wrong = "exagerating" and right = "exaggerating" - or - wrong = "exagerrate" and right = "exaggerate" - or - wrong = "exagerrated" and right = "exaggerated" - or - wrong = "exagerrates" and right = "exaggerates" - or - wrong = "exagerrating" and right = "exaggerating" - or - wrong = "examinated" and right = "examined" - or - wrong = "exampt" and right = "exempt" - or - wrong = "exapansion" and right = "expansion" - or - wrong = "excact" and right = "exact" - or - wrong = "excange" and right = "exchange" - or - wrong = "excecute" and right = "execute" - or - wrong = "excecuted" and right = "executed" - or - wrong = "excecutes" and right = "executes" - or - wrong = "excecuting" and right = "executing" - or - wrong = "excecution" and right = "execution" - or - wrong = "excedded" and right = "exceeded" - or - wrong = "excelent" and right = "excellent" - or - wrong = "excell" and right = "excel" - or - wrong = "excellance" and right = "excellence" - or - wrong = "excellant" and right = "excellent" - or - wrong = "excells" and right = "excels" - or - wrong = "excercise" and right = "exercise" - or - wrong = "exchanching" and right = "exchanging" - or - wrong = "excisted" and right = "existed" - or - wrong = "exculsivly" and right = "exclusively" - or - wrong = "execising" and right = "exercising" - or - wrong = "exection" and right = "execution" - or - wrong = "exectued" and right = "executed" - or - wrong = "exeedingly" and right = "exceedingly" - or - wrong = "exelent" and right = "excellent" - or - wrong = "exellent" and right = "excellent" - or - wrong = "exemple" and right = "example" - or - wrong = "exept" and right = "except" - or - wrong = "exeptional" and right = "exceptional" - or - wrong = "exerbate" and right = "exacerbate" - or - wrong = "exerbated" and right = "exacerbated" - or - wrong = "exerciese" and right = "exercises" - or - wrong = "exerpt" and right = "excerpt" - or - wrong = "exerpts" and right = "excerpts" - or - wrong = "exersize" and right = "exercise" - or - wrong = "exerternal" and right = "external" - or - wrong = "exhalted" and right = "exalted" - or - wrong = "exhibtion" and right = "exhibition" - or - wrong = "exibition" and right = "exhibition" - or - wrong = "exibitions" and right = "exhibitions" - or - wrong = "exicting" and right = "exciting" - or - wrong = "exinct" and right = "extinct" - or - wrong = "existance" and right = "existence" - or - wrong = "existant" and right = "existent" - or - wrong = "existince" and right = "existence" - or - wrong = "exliled" and right = "exiled" - or - wrong = "exludes" and right = "excludes" - or - wrong = "exmaple" and right = "example" - or - wrong = "exonorate" and right = "exonerate" - or - wrong = "exoskelaton" and right = "exoskeleton" - or - wrong = "expalin" and right = "explain" - or - wrong = "expatriot" and right = "expatriate" - or - wrong = "expeced" and right = "expected" - or - wrong = "expecially" and right = "especially" - or - wrong = "expeditonary" and right = "expeditionary" - or - wrong = "expeiments" and right = "experiments" - or - wrong = "expell" and right = "expel" - or - wrong = "expells" and right = "expels" - or - wrong = "experiance" and right = "experience" - or - wrong = "experianced" and right = "experienced" - or - wrong = "expession" and right = "expression" - or - wrong = "expessions" and right = "expressions" - or - wrong = "expiditions" and right = "expeditions" - or - wrong = "expierence" and right = "experience" - or - wrong = "explaination" and right = "explanation" - or - wrong = "explaning" and right = "explaining" - or - wrong = "explictly" and right = "explicitly" - or - wrong = "exploititive" and right = "exploitative" - or - wrong = "explotation" and right = "exploitation" - or - wrong = "expropiated" and right = "expropriated" - or - wrong = "expropiation" and right = "expropriation" - or - wrong = "exressed" and right = "expressed" - or - wrong = "extemely" and right = "extremely" - or - wrong = "extened" and right = "extended" - or - wrong = "extention" and right = "extension" - or - wrong = "extentions" and right = "extensions" - or - wrong = "extered" and right = "exerted" - or - wrong = "extermist" and right = "extremist" - or - wrong = "extint" and right = "extant" - or - wrong = "extint" and right = "extinct" - or - wrong = "extracter" and right = "extractor" - or - wrong = "extradiction" and right = "extradition" - or - wrong = "extraterrestial" and right = "extraterrestrial" - or - wrong = "extraterrestials" and right = "extraterrestrials" - or - wrong = "extravagent" and right = "extravagant" - or - wrong = "extrememly" and right = "extremely" - or - wrong = "extremeophile" and right = "extremophile" - or - wrong = "extremly" and right = "extremely" - or - wrong = "extrordinarily" and right = "extraordinarily" - or - wrong = "extrordinary" and right = "extraordinary" - or - wrong = "eyar" and right = "eyas" - or - wrong = "eyar" and right = "year" - or - wrong = "eyars" and right = "eyas" - or - wrong = "eyars" and right = "years" - or - wrong = "eyasr" and right = "eyas" - or - wrong = "eyasr" and right = "years" - or - wrong = "faciliate" and right = "facilitate" - or - wrong = "faciliated" and right = "facilitated" - or - wrong = "faciliates" and right = "facilitates" - or - wrong = "facilites" and right = "facilities" - or - wrong = "facillitate" and right = "facilitate" - or - wrong = "facinated" and right = "fascinated" - or - wrong = "facist" and right = "fascist" - or - wrong = "familes" and right = "families" - or - wrong = "familliar" and right = "familiar" - or - wrong = "famoust" and right = "famous" - or - wrong = "fanatism" and right = "fanaticism" - or - wrong = "farenheit" and right = "fahrenheit" - or - wrong = "fatc" and right = "fact" - or - wrong = "faught" and right = "fought" - or - wrong = "favoutrable" and right = "favourable" - or - wrong = "feasable" and right = "feasible" - or - wrong = "febuary" and right = "february" - or - wrong = "feburary" and right = "february" - or - wrong = "fedreally" and right = "federally" - or - wrong = "femminist" and right = "feminist" - or - wrong = "feromone" and right = "pheromone" - or - wrong = "fertily" and right = "fertility" - or - wrong = "fianite" and right = "finite" - or - wrong = "fianlly" and right = "finally" - or - wrong = "ficticious" and right = "fictitious" - or - wrong = "fictious" and right = "fictitious" - or - wrong = "fidn" and right = "find" - or - wrong = "fiel" and right = "feel" - or - wrong = "fiel" and right = "field" - or - wrong = "fiel" and right = "file" - or - wrong = "fiel" and right = "phial" - or - wrong = "fiels" and right = "feels" - or - wrong = "fiels" and right = "fields" - or - wrong = "fiels" and right = "files" - or - wrong = "fiels" and right = "phials" - or - wrong = "fiercly" and right = "fiercely" - or - wrong = "fightings" and right = "fighting" - or - wrong = "filiament" and right = "filament" - or - wrong = "fimilies" and right = "families" - or - wrong = "finacial" and right = "financial" - or - wrong = "finaly" and right = "finally" - or - wrong = "financialy" and right = "financially" - or - wrong = "firends" and right = "friends" - or - wrong = "firts" and right = "first" - or - wrong = "firts" and right = "flirts" - or - wrong = "fisionable" and right = "fissionable" - or - wrong = "flamable" and right = "flammable" - or - wrong = "flawess" and right = "flawless" - or - wrong = "fleed" and right = "fled" - or - wrong = "fleed" and right = "freed" - or - wrong = "flemmish" and right = "flemish" - or - wrong = "florescent" and right = "fluorescent" - or - wrong = "flourescent" and right = "fluorescent" - or - wrong = "flourine" and right = "fluorine" - or - wrong = "flourishment" and right = "flourishing" - or - wrong = "fluorish" and right = "flourish" - or - wrong = "follwoing" and right = "following" - or - wrong = "folowing" and right = "following" - or - wrong = "fomed" and right = "formed" - or - wrong = "fomr" and right = "form" - or - wrong = "fomr" and right = "from" - or - wrong = "fonetic" and right = "phonetic" - or - wrong = "fontrier" and right = "fontier" - or - wrong = "foootball" and right = "football" - or - wrong = "forbad" and right = "forbade" - or - wrong = "forbiden" and right = "forbidden" - or - wrong = "foreward" and right = "foreword" - or - wrong = "forfiet" and right = "forfeit" - or - wrong = "forhead" and right = "forehead" - or - wrong = "foriegn" and right = "foreign" - or - wrong = "formalhaut" and right = "fomalhaut" - or - wrong = "formallize" and right = "formalize" - or - wrong = "formallized" and right = "formalized" - or - wrong = "formaly" and right = "formally" - or - wrong = "formaly" and right = "formerly" - or - wrong = "formelly" and right = "formerly" - or - wrong = "formidible" and right = "formidable" - or - wrong = "formost" and right = "foremost" - or - wrong = "forsaw" and right = "foresaw" - or - wrong = "forseeable" and right = "foreseeable" - or - wrong = "fortelling" and right = "foretelling" - or - wrong = "forunner" and right = "forerunner" - or - wrong = "foucs" and right = "focus" - or - wrong = "foudn" and right = "found" - or - wrong = "fougth" and right = "fought" - or - wrong = "foundaries" and right = "foundries" - or - wrong = "foundary" and right = "foundry" - or - wrong = "foundland" and right = "newfoundland" - or - wrong = "fourties" and right = "forties" - or - wrong = "fourty" and right = "forty" - or - wrong = "fouth" and right = "fourth" - or - wrong = "foward" and right = "forward" - or - wrong = "framwork" and right = "framework" - or - wrong = "fransiscan" and right = "franciscan" - or - wrong = "fransiscans" and right = "franciscans" - or - wrong = "freind" and right = "friend" - or - wrong = "freindly" and right = "friendly" - or - wrong = "frequentily" and right = "frequently" - or - wrong = "frome" and right = "from" - or - wrong = "fromed" and right = "formed" - or - wrong = "froniter" and right = "frontier" - or - wrong = "fucntion" and right = "function" - or - wrong = "fucntioning" and right = "functioning" - or - wrong = "fufill" and right = "fulfill" - or - wrong = "fufilled" and right = "fulfilled" - or - wrong = "fulfiled" and right = "fulfilled" - or - wrong = "fullfill" and right = "fulfill" - or - wrong = "fullfilled" and right = "fulfilled" - or - wrong = "funcion" and right = "function" - or - wrong = "fundametal" and right = "fundamental" - or - wrong = "fundametals" and right = "fundamentals" - or - wrong = "funguses" and right = "fungi" - or - wrong = "funtion" and right = "function" - or - wrong = "funtions" and right = "functions" - or - wrong = "furuther" and right = "further" - or - wrong = "futher" and right = "further" - or - wrong = "futhermore" and right = "furthermore" - or - wrong = "futhroc" and right = "futhark" - or - wrong = "futhroc" and right = "futhorc" - or - wrong = "gae" and right = "gael" - or - wrong = "gae" and right = "gale" - or - wrong = "gae" and right = "game" - or - wrong = "galatic" and right = "galactic" - or - wrong = "galations" and right = "galatians" - or - wrong = "gallaxies" and right = "galaxies" - or - wrong = "galvinized" and right = "galvanized" - or - wrong = "ganerate" and right = "generate" - or - wrong = "ganes" and right = "games" - or - wrong = "ganster" and right = "gangster" - or - wrong = "garantee" and right = "guarantee" - or - wrong = "garanteed" and right = "guaranteed" - or - wrong = "garantees" and right = "guarantees" - or - wrong = "garnison" and right = "garrison" - or - wrong = "gaurantee" and right = "guarantee" - or - wrong = "gauranteed" and right = "guaranteed" - or - wrong = "gaurantees" and right = "guarantees" - or - wrong = "gaurd" and right = "gourd" - or - wrong = "gaurd" and right = "guard" - or - wrong = "gaurentee" and right = "guarantee" - or - wrong = "gaurenteed" and right = "guaranteed" - or - wrong = "gaurentees" and right = "guarantees" - or - wrong = "geneological" and right = "genealogical" - or - wrong = "geneologies" and right = "genealogies" - or - wrong = "geneology" and right = "genealogy" - or - wrong = "generaly" and right = "generally" - or - wrong = "generatting" and right = "generating" - or - wrong = "genialia" and right = "genitalia" - or - wrong = "geographicial" and right = "geographical" - or - wrong = "geometrician" and right = "geometer" - or - wrong = "geometricians" and right = "geometers" - or - wrong = "gerat" and right = "great" - or - wrong = "ghandi" and right = "gandhi" - or - wrong = "glamourous" and right = "glamorous" - or - wrong = "glight" and right = "flight" - or - wrong = "gnawwed" and right = "gnawed" - or - wrong = "godess" and right = "goddess" - or - wrong = "godesses" and right = "goddesses" - or - wrong = "godounov" and right = "godunov" - or - wrong = "gogin" and right = "gauguin" - or - wrong = "gogin" and right = "going" - or - wrong = "goign" and right = "going" - or - wrong = "gonig" and right = "going" - or - wrong = "gothenberg" and right = "gothenburg" - or - wrong = "gottleib" and right = "gottlieb" - or - wrong = "gouvener" and right = "governor" - or - wrong = "govement" and right = "government" - or - wrong = "govenment" and right = "government" - or - wrong = "govenrment" and right = "government" - or - wrong = "goverance" and right = "governance" - or - wrong = "goverment" and right = "government" - or - wrong = "govermental" and right = "governmental" - or - wrong = "governer" and right = "governor" - or - wrong = "governmnet" and right = "government" - or - wrong = "govorment" and right = "government" - or - wrong = "govormental" and right = "governmental" - or - wrong = "govornment" and right = "government" - or - wrong = "gracefull" and right = "graceful" - or - wrong = "graet" and right = "great" - or - wrong = "grafitti" and right = "graffiti" - or - wrong = "gramatically" and right = "grammatically" - or - wrong = "grammaticaly" and right = "grammatically" - or - wrong = "grammer" and right = "grammar" - or - wrong = "grat" and right = "great" - or - wrong = "gratuitious" and right = "gratuitous" - or - wrong = "greatful" and right = "grateful" - or - wrong = "greatfully" and right = "gratefully" - or - wrong = "greif" and right = "grief" - or - wrong = "gridles" and right = "griddles" - or - wrong = "gropu" and right = "group" - or - wrong = "grwo" and right = "grow" - or - wrong = "guaduloupe" and right = "guadalupe" - or - wrong = "guaduloupe" and right = "guadeloupe" - or - wrong = "guadulupe" and right = "guadalupe" - or - wrong = "guadulupe" and right = "guadeloupe" - or - wrong = "guage" and right = "gauge" - or - wrong = "guarentee" and right = "guarantee" - or - wrong = "guarenteed" and right = "guaranteed" - or - wrong = "guarentees" and right = "guarantees" - or - wrong = "guatamala" and right = "guatemala" - or - wrong = "guatamalan" and right = "guatemalan" - or - wrong = "guerrila" and right = "guerrilla" - or - wrong = "guerrilas" and right = "guerrillas" - or - wrong = "guidence" and right = "guidance" - or - wrong = "guilia" and right = "giulia" - or - wrong = "guilio" and right = "giulio" - or - wrong = "guiness" and right = "guinness" - or - wrong = "guiseppe" and right = "giuseppe" - or - wrong = "gunanine" and right = "guanine" - or - wrong = "gurantee" and right = "guarantee" - or - wrong = "guranteed" and right = "guaranteed" - or - wrong = "gurantees" and right = "guarantees" - or - wrong = "guttaral" and right = "guttural" - or - wrong = "gutteral" and right = "guttural" - or - wrong = "habaeus" and right = "habeas" - or - wrong = "habeus" and right = "habeas" - or - wrong = "habsbourg" and right = "habsburg" - or - wrong = "haemorrage" and right = "haemorrhage" - or - wrong = "haev" and right = "have" - or - wrong = "haev" and right = "heave" - or - wrong = "halarious" and right = "hilarious" - or - wrong = "hallowean" and right = "halloween" - or - wrong = "halp" and right = "help" - or - wrong = "hander" and right = "handler" - or - wrong = "hapen" and right = "happen" - or - wrong = "hapened" and right = "happened" - or - wrong = "hapening" and right = "happening" - or - wrong = "happend" and right = "happened" - or - wrong = "happended" and right = "happened" - or - wrong = "happenned" and right = "happened" - or - wrong = "harased" and right = "harassed" - or - wrong = "harases" and right = "harasses" - or - wrong = "harasment" and right = "harassment" - or - wrong = "harasments" and right = "harassments" - or - wrong = "harassement" and right = "harassment" - or - wrong = "harras" and right = "harass" - or - wrong = "harrased" and right = "harassed" - or - wrong = "harrases" and right = "harasses" - or - wrong = "harrasing" and right = "harassing" - or - wrong = "harrasment" and right = "harassment" - or - wrong = "harrasments" and right = "harassments" - or - wrong = "harrassed" and right = "harassed" - or - wrong = "harrasses" and right = "harassed" - or - wrong = "harrassing" and right = "harassing" - or - wrong = "harrassment" and right = "harassment" - or - wrong = "harrassments" and right = "harassments" - or - wrong = "hatian" and right = "haitian" - or - wrong = "haviest" and right = "heaviest" - or - wrong = "headquarer" and right = "headquarter" - or - wrong = "headquater" and right = "headquarter" - or - wrong = "headquatered" and right = "headquartered" - or - wrong = "headquaters" and right = "headquarters" - or - wrong = "healthercare" and right = "healthcare" - or - wrong = "heared" and right = "heard" - or - wrong = "heathy" and right = "healthy" - or - wrong = "heidelburg" and right = "heidelberg" - or - wrong = "heigher" and right = "higher" - or - wrong = "heirarchy" and right = "hierarchy" - or - wrong = "heiroglyphics" and right = "hieroglyphics" - or - wrong = "helment" and right = "helmet" - or - wrong = "helpfull" and right = "helpful" - or - wrong = "helpped" and right = "helped" - or - wrong = "hemmorhage" and right = "hemorrhage" - or - wrong = "herad" and right = "heard" - or - wrong = "herad" and right = "hera" - or - wrong = "heridity" and right = "heredity" - or - wrong = "heroe" and right = "hero" - or - wrong = "heros" and right = "heroes" - or - wrong = "hertiage" and right = "heritage" - or - wrong = "hertzs" and right = "hertz" - or - wrong = "hesistant" and right = "hesitant" - or - wrong = "heterogenous" and right = "heterogeneous" - or - wrong = "hieght" and right = "height" - or - wrong = "hierachical" and right = "hierarchical" - or - wrong = "hierachies" and right = "hierarchies" - or - wrong = "hierachy" and right = "hierarchy" - or - wrong = "hierarcical" and right = "hierarchical" - or - wrong = "hierarcy" and right = "hierarchy" - or - wrong = "hieroglph" and right = "hieroglyph" - or - wrong = "hieroglphs" and right = "hieroglyphs" - or - wrong = "higer" and right = "higher" - or - wrong = "higest" and right = "highest" - or - wrong = "higway" and right = "highway" - or - wrong = "hillarious" and right = "hilarious" - or - wrong = "himselv" and right = "himself" - or - wrong = "hinderance" and right = "hindrance" - or - wrong = "hinderence" and right = "hindrance" - or - wrong = "hindrence" and right = "hindrance" - or - wrong = "hipopotamus" and right = "hippopotamus" - or - wrong = "hismelf" and right = "himself" - or - wrong = "histocompatability" and right = "histocompatibility" - or - wrong = "historicians" and right = "historians" - or - wrong = "holf" and right = "hold" - or - wrong = "holliday" and right = "holiday" - or - wrong = "homogeneize" and right = "homogenize" - or - wrong = "homogeneized" and right = "homogenized" - or - wrong = "honory" and right = "honorary" - or - wrong = "horrifing" and right = "horrifying" - or - wrong = "hosited" and right = "hoisted" - or - wrong = "hospitible" and right = "hospitable" - or - wrong = "hounour" and right = "honour" - or - wrong = "housr" and right = "hours" - or - wrong = "housr" and right = "house" - or - wrong = "howver" and right = "however" - or - wrong = "hsitorians" and right = "historians" - or - wrong = "hstory" and right = "history" - or - wrong = "hten" and right = "hen" - or - wrong = "hten" and right = "the" - or - wrong = "hten" and right = "then" - or - wrong = "htere" and right = "here" - or - wrong = "htere" and right = "there" - or - wrong = "htey" and right = "they" - or - wrong = "htikn" and right = "think" - or - wrong = "hting" and right = "thing" - or - wrong = "htink" and right = "think" - or - wrong = "htis" and right = "this" - or - wrong = "humer" and right = "humor" - or - wrong = "humer" and right = "humour" - or - wrong = "humerous" and right = "humerus" - or - wrong = "humerous" and right = "humorous" - or - wrong = "huminoid" and right = "humanoid" - or - wrong = "humoural" and right = "humoral" - or - wrong = "humurous" and right = "humorous" - or - wrong = "husban" and right = "husband" - or - wrong = "hvae" and right = "have" - or - wrong = "hvaing" and right = "having" - or - wrong = "hvea" and right = "have" - or - wrong = "hvea" and right = "heave" - or - wrong = "hwihc" and right = "which" - or - wrong = "hwile" and right = "while" - or - wrong = "hwole" and right = "whole" - or - wrong = "hydogen" and right = "hydrogen" - or - wrong = "hydropile" and right = "hydrophile" - or - wrong = "hydropilic" and right = "hydrophilic" - or - wrong = "hydropobe" and right = "hydrophobe" - or - wrong = "hydropobic" and right = "hydrophobic" - or - wrong = "hygeine" and right = "hygiene" - or - wrong = "hyjack" and right = "hijack" - or - wrong = "hyjacking" and right = "hijacking" - or - wrong = "hypocracy" and right = "hypocrisy" - or - wrong = "hypocrasy" and right = "hypocrisy" - or - wrong = "hypocricy" and right = "hypocrisy" - or - wrong = "hypocrit" and right = "hypocrite" - or - wrong = "hypocrits" and right = "hypocrites" - or - wrong = "iconclastic" and right = "iconoclastic" - or - wrong = "idaeidae" and right = "idea" - or - wrong = "idaes" and right = "ideas" - or - wrong = "idealogies" and right = "ideologies" - or - wrong = "idealogy" and right = "ideology" - or - wrong = "identicial" and right = "identical" - or - wrong = "identifers" and right = "identifiers" - or - wrong = "ideosyncratic" and right = "idiosyncratic" - or - wrong = "idesa" and right = "ideas" - or - wrong = "idesa" and right = "ides" - or - wrong = "idiosyncracy" and right = "idiosyncrasy" - or - wrong = "ihaca" and right = "ithaca" - or - wrong = "illegimacy" and right = "illegitimacy" - or - wrong = "illegitmate" and right = "illegitimate" - or - wrong = "illess" and right = "illness" - or - wrong = "illiegal" and right = "illegal" - or - wrong = "illution" and right = "illusion" - or - wrong = "ilness" and right = "illness" - or - wrong = "ilogical" and right = "illogical" - or - wrong = "imagenary" and right = "imaginary" - or - wrong = "imagin" and right = "imagine" - or - wrong = "imaginery" and right = "imagery" - or - wrong = "imaginery" and right = "imaginary" - or - wrong = "imanent" and right = "eminent" - or - wrong = "imanent" and right = "imminent" - or - wrong = "imcomplete" and right = "incomplete" - or - wrong = "imediately" and right = "immediately" - or - wrong = "imense" and right = "immense" - or - wrong = "imigrant" and right = "emigrant" - or - wrong = "imigrant" and right = "immigrant" - or - wrong = "imigrated" and right = "emigrated" - or - wrong = "imigrated" and right = "immigrated" - or - wrong = "imigration" and right = "emigration" - or - wrong = "imigration" and right = "immigration" - or - wrong = "iminent" and right = "eminent" - or - wrong = "iminent" and right = "immanent" - or - wrong = "iminent" and right = "imminent" - or - wrong = "immediatley" and right = "immediately" - or - wrong = "immediatly" and right = "immediately" - or - wrong = "immidately" and right = "immediately" - or - wrong = "immidiately" and right = "immediately" - or - wrong = "immitate" and right = "imitate" - or - wrong = "immitated" and right = "imitated" - or - wrong = "immitating" and right = "imitating" - or - wrong = "immitator" and right = "imitator" - or - wrong = "immunosupressant" and right = "immunosuppressant" - or - wrong = "impecabbly" and right = "impeccably" - or - wrong = "impedence" and right = "impedance" - or - wrong = "implamenting" and right = "implementing" - or - wrong = "impliment" and right = "implement" - or - wrong = "implimented" and right = "implemented" - or - wrong = "imploys" and right = "employs" - or - wrong = "importamt" and right = "important" - or - wrong = "impressario" and right = "impresario" - or - wrong = "imprioned" and right = "imprisoned" - or - wrong = "imprisonned" and right = "imprisoned" - or - wrong = "improvision" and right = "improvisation" - or - wrong = "improvments" and right = "improvements" - or - wrong = "inablility" and right = "inability" - or - wrong = "inaccessable" and right = "inaccessible" - or - wrong = "inadiquate" and right = "inadequate" - or - wrong = "inadquate" and right = "inadequate" - or - wrong = "inadvertant" and right = "inadvertent" - or - wrong = "inadvertantly" and right = "inadvertently" - or - wrong = "inagurated" and right = "inaugurated" - or - wrong = "inaguration" and right = "inauguration" - or - wrong = "inappropiate" and right = "inappropriate" - or - wrong = "inaugures" and right = "inaugurates" - or - wrong = "inbalance" and right = "imbalance" - or - wrong = "inbalanced" and right = "imbalanced" - or - wrong = "inbetween" and right = "between" - or - wrong = "incarcirated" and right = "incarcerated" - or - wrong = "incidentially" and right = "incidentally" - or - wrong = "incidently" and right = "incidentally" - or - wrong = "inclreased" and right = "increased" - or - wrong = "includ" and right = "include" - or - wrong = "includng" and right = "including" - or - wrong = "incompatabilities" and right = "incompatibilities" - or - wrong = "incompatability" and right = "incompatibility" - or - wrong = "incompatable" and right = "incompatible" - or - wrong = "incompatablities" and right = "incompatibilities" - or - wrong = "incompatablity" and right = "incompatibility" - or - wrong = "incompatiblities" and right = "incompatibilities" - or - wrong = "incompatiblity" and right = "incompatibility" - or - wrong = "incompetance" and right = "incompetence" - or - wrong = "incompetant" and right = "incompetent" - or - wrong = "incomptable" and right = "incompatible" - or - wrong = "incomptetent" and right = "incompetent" - or - wrong = "inconsistant" and right = "inconsistent" - or - wrong = "incoroporated" and right = "incorporated" - or - wrong = "incorperation" and right = "incorporation" - or - wrong = "incorportaed" and right = "incorporated" - or - wrong = "incorprates" and right = "incorporates" - or - wrong = "incorruptable" and right = "incorruptible" - or - wrong = "incramentally" and right = "incrementally" - or - wrong = "increadible" and right = "incredible" - or - wrong = "incredable" and right = "incredible" - or - wrong = "inctroduce" and right = "introduce" - or - wrong = "inctroduced" and right = "introduced" - or - wrong = "incuding" and right = "including" - or - wrong = "incunabla" and right = "incunabula" - or - wrong = "indefinately" and right = "indefinitely" - or - wrong = "indefineable" and right = "undefinable" - or - wrong = "indefinitly" and right = "indefinitely" - or - wrong = "indentical" and right = "identical" - or - wrong = "indepedantly" and right = "independently" - or - wrong = "indepedence" and right = "independence" - or - wrong = "independance" and right = "independence" - or - wrong = "independant" and right = "independent" - or - wrong = "independantly" and right = "independently" - or - wrong = "independece" and right = "independence" - or - wrong = "independendet" and right = "independent" - or - wrong = "indespensable" and right = "indispensable" - or - wrong = "indespensible" and right = "indispensable" - or - wrong = "indictement" and right = "indictment" - or - wrong = "indigineous" and right = "indigenous" - or - wrong = "indipendence" and right = "independence" - or - wrong = "indipendent" and right = "independent" - or - wrong = "indipendently" and right = "independently" - or - wrong = "indispensible" and right = "indispensable" - or - wrong = "indisputible" and right = "indisputable" - or - wrong = "indisputibly" and right = "indisputably" - or - wrong = "indite" and right = "indict" - or - wrong = "individualy" and right = "individually" - or - wrong = "indpendent" and right = "independent" - or - wrong = "indpendently" and right = "independently" - or - wrong = "indulgue" and right = "indulge" - or - wrong = "indutrial" and right = "industrial" - or - wrong = "indviduals" and right = "individuals" - or - wrong = "inefficienty" and right = "inefficiently" - or - wrong = "inevatible" and right = "inevitable" - or - wrong = "inevitible" and right = "inevitable" - or - wrong = "inevititably" and right = "inevitably" - or - wrong = "infalability" and right = "infallibility" - or - wrong = "infallable" and right = "infallible" - or - wrong = "infectuous" and right = "infectious" - or - wrong = "infered" and right = "inferred" - or - wrong = "infilitrate" and right = "infiltrate" - or - wrong = "infilitrated" and right = "infiltrated" - or - wrong = "infilitration" and right = "infiltration" - or - wrong = "infinit" and right = "infinite" - or - wrong = "inflamation" and right = "inflammation" - or - wrong = "influencial" and right = "influential" - or - wrong = "influented" and right = "influenced" - or - wrong = "infomation" and right = "information" - or - wrong = "informtion" and right = "information" - or - wrong = "infrantryman" and right = "infantryman" - or - wrong = "infrigement" and right = "infringement" - or - wrong = "ingenius" and right = "ingenious" - or - wrong = "ingreediants" and right = "ingredients" - or - wrong = "inhabitans" and right = "inhabitants" - or - wrong = "inherantly" and right = "inherently" - or - wrong = "inheritage" and right = "heritage" - or - wrong = "inheritage" and right = "inheritance" - or - wrong = "inheritence" and right = "inheritance" - or - wrong = "inital" and right = "initial" - or - wrong = "initalize" and right = "initialize" - or - wrong = "initally" and right = "initially" - or - wrong = "initation" and right = "initiation" - or - wrong = "initiaitive" and right = "initiative" - or - wrong = "inlcuding" and right = "including" - or - wrong = "inmigrant" and right = "immigrant" - or - wrong = "inmigrants" and right = "immigrants" - or - wrong = "innoculated" and right = "inoculated" - or - wrong = "inocence" and right = "innocence" - or - wrong = "inofficial" and right = "unofficial" - or - wrong = "inot" and right = "into" - or - wrong = "inpeach" and right = "impeach" - or - wrong = "inpending" and right = "impending" - or - wrong = "inpenetrable" and right = "impenetrable" - or - wrong = "inpolite" and right = "impolite" - or - wrong = "inprisonment" and right = "imprisonment" - or - wrong = "inproving" and right = "improving" - or - wrong = "insectiverous" and right = "insectivorous" - or - wrong = "insensative" and right = "insensitive" - or - wrong = "inseperable" and right = "inseparable" - or - wrong = "insistance" and right = "insistence" - or - wrong = "insitution" and right = "institution" - or - wrong = "insitutions" and right = "institutions" - or - wrong = "inspite" and right = "inspire" - or - wrong = "instade" and right = "instead" - or - wrong = "instatance" and right = "instance" - or - wrong = "institue" and right = "institute" - or - wrong = "instuction" and right = "instruction" - or - wrong = "instuments" and right = "instruments" - or - wrong = "instutionalized" and right = "institutionalized" - or - wrong = "instutions" and right = "intuitions" - or - wrong = "insurence" and right = "insurance" - or - wrong = "intelectual" and right = "intellectual" - or - wrong = "inteligence" and right = "intelligence" - or - wrong = "inteligent" and right = "intelligent" - or - wrong = "intenational" and right = "international" - or - wrong = "intented" and right = "indented" - or - wrong = "intented" and right = "intended" - or - wrong = "intepretation" and right = "interpretation" - or - wrong = "intepretator" and right = "interpretor" - or - wrong = "interational" and right = "international" - or - wrong = "interbread" and right = "interbred" - or - wrong = "interbread" and right = "interbreed" - or - wrong = "interchangable" and right = "interchangeable" - or - wrong = "interchangably" and right = "interchangeably" - or - wrong = "intercontinential" and right = "intercontinental" - or - wrong = "intercontinetal" and right = "intercontinental" - or - wrong = "intered" and right = "interned" - or - wrong = "intered" and right = "interred" - or - wrong = "interelated" and right = "interrelated" - or - wrong = "interferance" and right = "interference" - or - wrong = "interfereing" and right = "interfering" - or - wrong = "intergrated" and right = "integrated" - or - wrong = "intergration" and right = "integration" - or - wrong = "interm" and right = "interim" - or - wrong = "internation" and right = "international" - or - wrong = "interpet" and right = "interpret" - or - wrong = "interrim" and right = "interim" - or - wrong = "interrugum" and right = "interregnum" - or - wrong = "intertaining" and right = "entertaining" - or - wrong = "interupt" and right = "interrupt" - or - wrong = "intervines" and right = "intervenes" - or - wrong = "intevene" and right = "intervene" - or - wrong = "intial" and right = "initial" - or - wrong = "intialize" and right = "initialize" - or - wrong = "intialized" and right = "initialized" - or - wrong = "intially" and right = "initially" - or - wrong = "intrduced" and right = "introduced" - or - wrong = "intrest" and right = "interest" - or - wrong = "introdued" and right = "introduced" - or - wrong = "intruduced" and right = "introduced" - or - wrong = "intrument" and right = "instrument" - or - wrong = "intrumental" and right = "instrumental" - or - wrong = "intruments" and right = "instruments" - or - wrong = "intrusted" and right = "entrusted" - or - wrong = "intutive" and right = "intuitive" - or - wrong = "intutively" and right = "intuitively" - or - wrong = "inudstry" and right = "industry" - or - wrong = "inumerable" and right = "enumerable" - or - wrong = "inumerable" and right = "innumerable" - or - wrong = "inventer" and right = "inventor" - or - wrong = "invertibrates" and right = "invertebrates" - or - wrong = "investingate" and right = "investigate" - or - wrong = "involvment" and right = "involvement" - or - wrong = "irelevent" and right = "irrelevant" - or - wrong = "iresistable" and right = "irresistible" - or - wrong = "iresistably" and right = "irresistibly" - or - wrong = "iresistible" and right = "irresistible" - or - wrong = "iresistibly" and right = "irresistibly" - or - wrong = "iritable" and right = "irritable" - or - wrong = "iritated" and right = "irritated" - or - wrong = "ironicly" and right = "ironically" - or - wrong = "irregardless" and right = "regardless" - or - wrong = "irrelevent" and right = "irrelevant" - or - wrong = "irreplacable" and right = "irreplaceable" - or - wrong = "irresistable" and right = "irresistible" - or - wrong = "irresistably" and right = "irresistibly" - or - wrong = "israelies" and right = "israelis" - or - wrong = "issueing" and right = "issuing" - or - wrong = "itnroduced" and right = "introduced" - or - wrong = "iunior" and right = "junior" - or - wrong = "iwll" and right = "will" - or - wrong = "iwth" and right = "with" - or - wrong = "janurary" and right = "january" - or - wrong = "januray" and right = "january" - or - wrong = "japanes" and right = "japanese" - or - wrong = "jaques" and right = "jacques" - or - wrong = "jeapardy" and right = "jeopardy" - or - wrong = "jewllery" and right = "jewellery" - or - wrong = "johanine" and right = "johannine" - or - wrong = "jorunal" and right = "journal" - or - wrong = "jospeh" and right = "joseph" - or - wrong = "jouney" and right = "journey" - or - wrong = "journied" and right = "journeyed" - or - wrong = "journies" and right = "journeys" - or - wrong = "jstu" and right = "just" - or - wrong = "jsut" and right = "just" - or - wrong = "juadaism" and right = "judaism" - or - wrong = "juadism" and right = "judaism" - or - wrong = "judical" and right = "judicial" - or - wrong = "judisuary" and right = "judiciary" - or - wrong = "juducial" and right = "judicial" - or - wrong = "juristiction" and right = "jurisdiction" - or - wrong = "juristictions" and right = "jurisdictions" - or - wrong = "kindergarden" and right = "kindergarten" - or - wrong = "klenex" and right = "kleenex" - or - wrong = "knifes" and right = "knives" - or - wrong = "knive" and right = "knife" - or - wrong = "knowlege" and right = "knowledge" - or - wrong = "knowlegeable" and right = "knowledgeable" - or - wrong = "knwo" and right = "know" - or - wrong = "knwos" and right = "knows" - or - wrong = "konw" and right = "know" - or - wrong = "konws" and right = "knows" - or - wrong = "kwno" and right = "know" - or - wrong = "labatory" and right = "laboratory" - or - wrong = "labatory" and right = "lavatory" - or - wrong = "labled" and right = "labeled" - or - wrong = "labled" and right = "labelled" - or - wrong = "labratory" and right = "laboratory" - or - wrong = "laguage" and right = "language" - or - wrong = "laguages" and right = "languages" - or - wrong = "langage" and right = "language" - or - wrong = "langauge" and right = "language" - or - wrong = "larg" and right = "large" - or - wrong = "largst" and right = "largest" - or - wrong = "larrry" and right = "larry" - or - wrong = "lastr" and right = "last" - or - wrong = "lattitude" and right = "latitude" - or - wrong = "launchs" and right = "launch" - or - wrong = "launchs" and right = "launches" - or - wrong = "launhed" and right = "launched" - or - wrong = "lavae" and right = "larvae" - or - wrong = "layed" and right = "laid" - or - wrong = "lazyness" and right = "laziness" - or - wrong = "leage" and right = "league" - or - wrong = "leanr" and right = "lean" - or - wrong = "leanr" and right = "leaner" - or - wrong = "leanr" and right = "learn" - or - wrong = "leathal" and right = "lethal" - or - wrong = "lefted" and right = "left" - or - wrong = "legitamate" and right = "legitimate" - or - wrong = "legitmate" and right = "legitimate" - or - wrong = "leibnitz" and right = "leibniz" - or - wrong = "lengh" and right = "length" - or - wrong = "lenght" and right = "length" - or - wrong = "lengt" and right = "length" - or - wrong = "lenth" and right = "length" - or - wrong = "leran" and right = "learn" - or - wrong = "lerans" and right = "learns" - or - wrong = "leutenant" and right = "lieutenant" - or - wrong = "levetate" and right = "levitate" - or - wrong = "levetated" and right = "levitated" - or - wrong = "levetates" and right = "levitates" - or - wrong = "levetating" and right = "levitating" - or - wrong = "levle" and right = "level" - or - wrong = "liasion" and right = "liaison" - or - wrong = "liason" and right = "liaison" - or - wrong = "liasons" and right = "liaisons" - or - wrong = "libaries" and right = "libraries" - or - wrong = "libary" and right = "library" - or - wrong = "libell" and right = "libel" - or - wrong = "libguistic" and right = "linguistic" - or - wrong = "libguistics" and right = "linguistics" - or - wrong = "libitarianisn" and right = "libertarianism" - or - wrong = "lible" and right = "liable" - or - wrong = "lible" and right = "libel" - or - wrong = "lieing" and right = "lying" - or - wrong = "liek" and right = "like" - or - wrong = "liekd" and right = "liked" - or - wrong = "liesure" and right = "leisure" - or - wrong = "lieuenant" and right = "lieutenant" - or - wrong = "lieved" and right = "lived" - or - wrong = "liftime" and right = "lifetime" - or - wrong = "likelyhood" and right = "likelihood" - or - wrong = "linnaena" and right = "linnaean" - or - wrong = "lippizaner" and right = "lipizzaner" - or - wrong = "liquify" and right = "liquefy" - or - wrong = "liscense" and right = "licence" - or - wrong = "liscense" and right = "license" - or - wrong = "lisence" and right = "licence" - or - wrong = "lisence" and right = "license" - or - wrong = "lisense" and right = "licence" - or - wrong = "lisense" and right = "license" - or - wrong = "listners" and right = "listeners" - or - wrong = "litature" and right = "literature" - or - wrong = "literaly" and right = "literally" - or - wrong = "literture" and right = "literature" - or - wrong = "littel" and right = "little" - or - wrong = "litterally" and right = "literally" - or - wrong = "liuke" and right = "like" - or - wrong = "livley" and right = "lively" - or - wrong = "lmits" and right = "limits" - or - wrong = "loev" and right = "love" - or - wrong = "lonelyness" and right = "loneliness" - or - wrong = "longitudonal" and right = "longitudinal" - or - wrong = "lonley" and right = "lonely" - or - wrong = "lonly" and right = "lonely" - or - wrong = "lonly" and right = "only" - or - wrong = "loosing" and right = "losing" - or - wrong = "lotharingen" and right = "lothringen" - or - wrong = "lsat" and right = "last" - or - wrong = "lukid" and right = "likud" - or - wrong = "lveo" and right = "love" - or - wrong = "lvoe" and right = "love" - or - wrong = "lybia" and right = "libya" - or - wrong = "maching" and right = "machine" - or - wrong = "maching" and right = "marching" - or - wrong = "maching" and right = "matching" - or - wrong = "mackeral" and right = "mackerel" - or - wrong = "magasine" and right = "magazine" - or - wrong = "magincian" and right = "magician" - or - wrong = "magisine" and right = "magazine" - or - wrong = "magizine" and right = "magazine" - or - wrong = "magnificient" and right = "magnificent" - or - wrong = "magolia" and right = "magnolia" - or - wrong = "mailny" and right = "mainly" - or - wrong = "maintainance" and right = "maintenance" - or - wrong = "maintainence" and right = "maintenance" - or - wrong = "maintance" and right = "maintenance" - or - wrong = "maintenence" and right = "maintenance" - or - wrong = "maintinaing" and right = "maintaining" - or - wrong = "maintioned" and right = "mentioned" - or - wrong = "majoroty" and right = "majority" - or - wrong = "maked" and right = "made" - or - wrong = "maked" and right = "marked" - or - wrong = "makse" and right = "makes" - or - wrong = "malcom" and right = "malcolm" - or - wrong = "maltesian" and right = "maltese" - or - wrong = "mamal" and right = "mammal" - or - wrong = "mamalian" and right = "mammalian" - or - wrong = "managable" and right = "manageable" - or - wrong = "managable" and right = "manageably" - or - wrong = "managment" and right = "management" - or - wrong = "maneouvre" and right = "manoeuvre" - or - wrong = "maneouvred" and right = "manoeuvred" - or - wrong = "maneouvres" and right = "manoeuvres" - or - wrong = "maneouvring" and right = "manoeuvring" - or - wrong = "manisfestations" and right = "manifestations" - or - wrong = "manoeuverability" and right = "maneuverability" - or - wrong = "manouver" and right = "maneuver" - or - wrong = "manouver" and right = "manoeuvre" - or - wrong = "manouverability" and right = "maneuverability" - or - wrong = "manouverability" and right = "manoeuverability" - or - wrong = "manouverability" and right = "manoeuvrability" - or - wrong = "manouverable" and right = "maneuverable" - or - wrong = "manouverable" and right = "manoeuvrable" - or - wrong = "manouvers" and right = "maneuvers" - or - wrong = "manouvers" and right = "manoeuvres" - or - wrong = "mantained" and right = "maintained" - or - wrong = "manuever" and right = "maneuver" - or - wrong = "manuever" and right = "manoeuvre" - or - wrong = "manuevers" and right = "maneuvers" - or - wrong = "manuevers" and right = "manoeuvres" - or - wrong = "manufacturedd" and right = "manufactured" - or - wrong = "manufature" and right = "manufacture" - or - wrong = "manufatured" and right = "manufactured" - or - wrong = "manufaturing" and right = "manufacturing" - or - wrong = "manuver" and right = "maneuver" - or - wrong = "mariage" and right = "marriage" - or - wrong = "marjority" and right = "majority" - or - wrong = "markes" and right = "marks" - or - wrong = "marketting" and right = "marketing" - or - wrong = "marmelade" and right = "marmalade" - or - wrong = "marrage" and right = "marriage" - or - wrong = "marraige" and right = "marriage" - or - wrong = "marrtyred" and right = "martyred" - or - wrong = "marryied" and right = "married" - or - wrong = "massachussets" and right = "massachusetts" - or - wrong = "massachussetts" and right = "massachusetts" - or - wrong = "masterbation" and right = "masturbation" - or - wrong = "mataphysical" and right = "metaphysical" - or - wrong = "materalists" and right = "materialist" - or - wrong = "mathamatics" and right = "mathematics" - or - wrong = "mathematican" and right = "mathematician" - or - wrong = "mathematicas" and right = "mathematics" - or - wrong = "matheticians" and right = "mathematicians" - or - wrong = "mathmatically" and right = "mathematically" - or - wrong = "mathmatician" and right = "mathematician" - or - wrong = "mathmaticians" and right = "mathematicians" - or - wrong = "mccarthyst" and right = "mccarthyist" - or - wrong = "mchanics" and right = "mechanics" - or - wrong = "meaninng" and right = "meaning" - or - wrong = "mear" and right = "mare" - or - wrong = "mear" and right = "mere" - or - wrong = "mear" and right = "wear" - or - wrong = "mechandise" and right = "merchandise" - or - wrong = "medacine" and right = "medicine" - or - wrong = "medeival" and right = "medieval" - or - wrong = "medevial" and right = "medieval" - or - wrong = "mediciney" and right = "mediciny" - or - wrong = "medievel" and right = "medieval" - or - wrong = "mediterainnean" and right = "mediterranean" - or - wrong = "mediteranean" and right = "mediterranean" - or - wrong = "meerkrat" and right = "meerkat" - or - wrong = "melieux" and right = "milieux" - or - wrong = "membranaphone" and right = "membranophone" - or - wrong = "memeber" and right = "member" - or - wrong = "menally" and right = "mentally" - or - wrong = "meranda" and right = "miranda" - or - wrong = "meranda" and right = "veranda" - or - wrong = "mercentile" and right = "mercantile" - or - wrong = "mesage" and right = "message" - or - wrong = "messanger" and right = "messenger" - or - wrong = "messenging" and right = "messaging" - or - wrong = "messsage" and right = "message" - or - wrong = "metalic" and right = "metallic" - or - wrong = "metalurgic" and right = "metallurgic" - or - wrong = "metalurgical" and right = "metallurgical" - or - wrong = "metalurgy" and right = "metallurgy" - or - wrong = "metamorphysis" and right = "metamorphosis" - or - wrong = "metaphoricial" and right = "metaphorical" - or - wrong = "meterologist" and right = "meteorologist" - or - wrong = "meterology" and right = "meteorology" - or - wrong = "methaphor" and right = "metaphor" - or - wrong = "methaphors" and right = "metaphors" - or - wrong = "michagan" and right = "michigan" - or - wrong = "micoscopy" and right = "microscopy" - or - wrong = "midwifes" and right = "midwives" - or - wrong = "mileau" and right = "milieu" - or - wrong = "milennia" and right = "millennia" - or - wrong = "milennium" and right = "millennium" - or - wrong = "mileu" and right = "milieu" - or - wrong = "miliary" and right = "military" - or - wrong = "miligram" and right = "milligram" - or - wrong = "milion" and right = "million" - or - wrong = "miliraty" and right = "military" - or - wrong = "millenia" and right = "millennia" - or - wrong = "millenial" and right = "millennial" - or - wrong = "millenialism" and right = "millennialism" - or - wrong = "millenium" and right = "millennium" - or - wrong = "millepede" and right = "millipede" - or - wrong = "millioniare" and right = "millionaire" - or - wrong = "millitant" and right = "militant" - or - wrong = "millitary" and right = "military" - or - wrong = "millon" and right = "million" - or - wrong = "miltary" and right = "military" - or - wrong = "minature" and right = "miniature" - or - wrong = "minerial" and right = "mineral" - or - wrong = "ministery" and right = "ministry" - or - wrong = "minsitry" and right = "ministry" - or - wrong = "minstries" and right = "ministries" - or - wrong = "minstry" and right = "ministry" - or - wrong = "minumum" and right = "minimum" - or - wrong = "mirrorred" and right = "mirrored" - or - wrong = "miscelaneous" and right = "miscellaneous" - or - wrong = "miscellanious" and right = "miscellaneous" - or - wrong = "miscellanous" and right = "miscellaneous" - or - wrong = "mischeivous" and right = "mischievous" - or - wrong = "mischevious" and right = "mischievous" - or - wrong = "mischievious" and right = "mischievous" - or - wrong = "misdameanor" and right = "misdemeanor" - or - wrong = "misdameanors" and right = "misdemeanors" - or - wrong = "misdemenor" and right = "misdemeanor" - or - wrong = "misdemenors" and right = "misdemeanors" - or - wrong = "misfourtunes" and right = "misfortunes" - or - wrong = "misile" and right = "missile" - or - wrong = "misouri" and right = "missouri" - or - wrong = "mispell" and right = "misspell" - or - wrong = "mispelled" and right = "misspelled" - or - wrong = "mispelling" and right = "misspelling" - or - wrong = "missen" and right = "mizzen" - or - wrong = "missisipi" and right = "mississippi" - or - wrong = "missisippi" and right = "mississippi" - or - wrong = "missle" and right = "missile" - or - wrong = "missonary" and right = "missionary" - or - wrong = "misterious" and right = "mysterious" - or - wrong = "mistery" and right = "mystery" - or - wrong = "misteryous" and right = "mysterious" - or - wrong = "mkae" and right = "make" - or - wrong = "mkaes" and right = "makes" - or - wrong = "mkaing" and right = "making" - or - wrong = "mkea" and right = "make" - or - wrong = "moderm" and right = "modem" - or - wrong = "modle" and right = "model" - or - wrong = "moent" and right = "moment" - or - wrong = "moeny" and right = "money" - or - wrong = "mohammedans" and right = "muslims" - or - wrong = "moil" and right = "mohel" - or - wrong = "moil" and right = "soil" - or - wrong = "moleclues" and right = "molecules" - or - wrong = "momento" and right = "memento" - or - wrong = "monestaries" and right = "monasteries" - or - wrong = "monestary" and right = "monastery" - or - wrong = "monestary" and right = "monetary" - or - wrong = "monickers" and right = "monikers" - or - wrong = "monolite" and right = "monolithic" - or - wrong = "monserrat" and right = "montserrat" - or - wrong = "montains" and right = "mountains" - or - wrong = "montanous" and right = "mountainous" - or - wrong = "montnana" and right = "montana" - or - wrong = "monts" and right = "months" - or - wrong = "montypic" and right = "monotypic" - or - wrong = "moreso" and right = "more" - or - wrong = "morgage" and right = "mortgage" - or - wrong = "morisette" and right = "morissette" - or - wrong = "morrisette" and right = "morissette" - or - wrong = "morroccan" and right = "moroccan" - or - wrong = "morrocco" and right = "morocco" - or - wrong = "morroco" and right = "morocco" - or - wrong = "mortage" and right = "mortgage" - or - wrong = "mosture" and right = "moisture" - or - wrong = "motiviated" and right = "motivated" - or - wrong = "mounth" and right = "month" - or - wrong = "movei" and right = "movie" - or - wrong = "movment" and right = "movement" - or - wrong = "mroe" and right = "more" - or - wrong = "mucuous" and right = "mucous" - or - wrong = "muder" and right = "murder" - or - wrong = "mudering" and right = "murdering" - or - wrong = "muhammadan" and right = "muslim" - or - wrong = "multicultralism" and right = "multiculturalism" - or - wrong = "multipled" and right = "multiplied" - or - wrong = "multiplers" and right = "multipliers" - or - wrong = "munbers" and right = "numbers" - or - wrong = "muncipalities" and right = "municipalities" - or - wrong = "muncipality" and right = "municipality" - or - wrong = "munnicipality" and right = "municipality" - or - wrong = "muscels" and right = "muscles" - or - wrong = "muscels" and right = "mussels" - or - wrong = "muscial" and right = "musical" - or - wrong = "muscician" and right = "musician" - or - wrong = "muscicians" and right = "musicians" - or - wrong = "mutiliated" and right = "mutilated" - or - wrong = "mutiple" and right = "multiple" - or - wrong = "myraid" and right = "myriad" - or - wrong = "mysef" and right = "myself" - or - wrong = "mysogynist" and right = "misogynist" - or - wrong = "mysogyny" and right = "misogyny" - or - wrong = "mysterous" and right = "mysterious" - or - wrong = "mythraic" and right = "mithraic" - or - wrong = "naieve" and right = "naive" - or - wrong = "naploeon" and right = "napoleon" - or - wrong = "napolean" and right = "napoleon" - or - wrong = "napoleonian" and right = "napoleonic" - or - wrong = "naturaly" and right = "naturally" - or - wrong = "naturely" and right = "naturally" - or - wrong = "naturual" and right = "natural" - or - wrong = "naturually" and right = "naturally" - or - wrong = "nazereth" and right = "nazareth" - or - wrong = "neccesarily" and right = "necessarily" - or - wrong = "neccesary" and right = "necessary" - or - wrong = "neccessarily" and right = "necessarily" - or - wrong = "neccessary" and right = "necessary" - or - wrong = "neccessities" and right = "necessities" - or - wrong = "necesarily" and right = "necessarily" - or - wrong = "necesary" and right = "necessary" - or - wrong = "necessiate" and right = "necessitate" - or - wrong = "neglible" and right = "negligible" - or - wrong = "negligable" and right = "negligible" - or - wrong = "negociate" and right = "negotiate" - or - wrong = "negociation" and right = "negotiation" - or - wrong = "negociations" and right = "negotiations" - or - wrong = "negotation" and right = "negotiation" - or - wrong = "neice" and right = "nice" - or - wrong = "neice" and right = "niece" - or - wrong = "neigborhood" and right = "neighborhood" - or - wrong = "neigbour" and right = "neighbor" - or - wrong = "neigbour" and right = "neighbour" - or - wrong = "neigbourhood" and right = "neighbourhood" - or - wrong = "neigbouring" and right = "neighboring" - or - wrong = "neigbouring" and right = "neighbouring" - or - wrong = "neigbours" and right = "neighbors" - or - wrong = "neigbours" and right = "neighbours" - or - wrong = "neolitic" and right = "neolithic" - or - wrong = "nessasarily" and right = "necessarily" - or - wrong = "nessecary" and right = "necessary" - or - wrong = "nestin" and right = "nesting" - or - wrong = "neverthless" and right = "nevertheless" - or - wrong = "newletters" and right = "newsletters" - or - wrong = "nickle" and right = "nickel" - or - wrong = "nightime" and right = "nighttime" - or - wrong = "nineth" and right = "ninth" - or - wrong = "ninteenth" and right = "nineteenth" - or - wrong = "ninty" and right = "ninety" - or - wrong = "nkow" and right = "know" - or - wrong = "nkwo" and right = "know" - or - wrong = "nmae" and right = "name" - or - wrong = "noncombatents" and right = "noncombatants" - or - wrong = "nonsence" and right = "nonsense" - or - wrong = "nontheless" and right = "nonetheless" - or - wrong = "norhern" and right = "northern" - or - wrong = "northen" and right = "northern" - or - wrong = "northereastern" and right = "northeastern" - or - wrong = "notabley" and right = "notably" - or - wrong = "noteable" and right = "notable" - or - wrong = "noteably" and right = "notably" - or - wrong = "noteriety" and right = "notoriety" - or - wrong = "noth" and right = "north" - or - wrong = "nothern" and right = "northern" - or - wrong = "noticable" and right = "noticeable" - or - wrong = "noticably" and right = "noticeably" - or - wrong = "notications" and right = "notifications" - or - wrong = "noticeing" and right = "noticing" - or - wrong = "noticible" and right = "noticeable" - or - wrong = "notwhithstanding" and right = "notwithstanding" - or - wrong = "noveau" and right = "nouveau" - or - wrong = "novermber" and right = "november" - or - wrong = "nowdays" and right = "nowadays" - or - wrong = "nowe" and right = "now" - or - wrong = "nto" and right = "not" - or - wrong = "nubmer" and right = "number" - or - wrong = "nucular" and right = "nuclear" - or - wrong = "nuculear" and right = "nuclear" - or - wrong = "nuisanse" and right = "nuisance" - or - wrong = "nullabour" and right = "nullarbor" - or - wrong = "numberous" and right = "numerous" - or - wrong = "nuremburg" and right = "nuremberg" - or - wrong = "nusance" and right = "nuisance" - or - wrong = "nutritent" and right = "nutrient" - or - wrong = "nutritents" and right = "nutrients" - or - wrong = "nuturing" and right = "nurturing" - or - wrong = "obect" and right = "object" - or - wrong = "obediance" and right = "obedience" - or - wrong = "obediant" and right = "obedient" - or - wrong = "obejct" and right = "object" - or - wrong = "obession" and right = "obsession" - or - wrong = "obssessed" and right = "obsessed" - or - wrong = "obstacal" and right = "obstacle" - or - wrong = "obstancles" and right = "obstacles" - or - wrong = "obstruced" and right = "obstructed" - or - wrong = "ocasion" and right = "occasion" - or - wrong = "ocasional" and right = "occasional" - or - wrong = "ocasionally" and right = "occasionally" - or - wrong = "ocasionaly" and right = "occasionally" - or - wrong = "ocasioned" and right = "occasioned" - or - wrong = "ocasions" and right = "occasions" - or - wrong = "ocassion" and right = "occasion" - or - wrong = "ocassional" and right = "occasional" - or - wrong = "ocassionally" and right = "occasionally" - or - wrong = "ocassionaly" and right = "occasionally" - or - wrong = "ocassioned" and right = "occasioned" - or - wrong = "ocassions" and right = "occasions" - or - wrong = "occaison" and right = "occasion" - or - wrong = "occassion" and right = "occasion" - or - wrong = "occassional" and right = "occasional" - or - wrong = "occassionally" and right = "occasionally" - or - wrong = "occassionaly" and right = "occasionally" - or - wrong = "occassioned" and right = "occasioned" - or - wrong = "occassions" and right = "occasions" - or - wrong = "occationally" and right = "occasionally" - or - wrong = "occour" and right = "occur" - or - wrong = "occurance" and right = "occurrence" - or - wrong = "occurances" and right = "occurrences" - or - wrong = "occured" and right = "occurred" - or - wrong = "occurence" and right = "occurrence" - or - wrong = "occurences" and right = "occurrences" - or - wrong = "occuring" and right = "occurring" - or - wrong = "occurr" and right = "occur" - or - wrong = "occurrance" and right = "occurrence" - or - wrong = "occurrances" and right = "occurrences" - or - wrong = "octohedra" and right = "octahedra" - or - wrong = "octohedral" and right = "octahedral" - or - wrong = "octohedron" and right = "octahedron" - or - wrong = "ocuntries" and right = "countries" - or - wrong = "ocuntry" and right = "country" - or - wrong = "ocurr" and right = "occur" - or - wrong = "ocurrance" and right = "occurrence" - or - wrong = "ocurred" and right = "occurred" - or - wrong = "ocurrence" and right = "occurrence" - or - wrong = "offcers" and right = "officers" - or - wrong = "offcially" and right = "officially" - or - wrong = "offereings" and right = "offerings" - or - wrong = "offical" and right = "official" - or - wrong = "offically" and right = "officially" - or - wrong = "officals" and right = "officials" - or - wrong = "officaly" and right = "officially" - or - wrong = "officialy" and right = "officially" - or - wrong = "offred" and right = "offered" - or - wrong = "oftenly" and right = "often" - or - wrong = "oging" and right = "going" - or - wrong = "oging" and right = "ogling" - or - wrong = "oject" and right = "object" - or - wrong = "omision" and right = "omission" - or - wrong = "omited" and right = "omitted" - or - wrong = "omiting" and right = "omitting" - or - wrong = "omlette" and right = "omelette" - or - wrong = "ommision" and right = "omission" - or - wrong = "ommited" and right = "omitted" - or - wrong = "ommiting" and right = "omitting" - or - wrong = "ommitted" and right = "omitted" - or - wrong = "ommitting" and right = "omitting" - or - wrong = "omniverous" and right = "omnivorous" - or - wrong = "omniverously" and right = "omnivorously" - or - wrong = "omre" and right = "more" - or - wrong = "onot" and right = "not" - or - wrong = "onot" and right = "note" - or - wrong = "onyl" and right = "only" - or - wrong = "openess" and right = "openness" - or - wrong = "oponent" and right = "opponent" - or - wrong = "oportunity" and right = "opportunity" - or - wrong = "opose" and right = "oppose" - or - wrong = "oposite" and right = "opposite" - or - wrong = "oposition" and right = "opposition" - or - wrong = "oppenly" and right = "openly" - or - wrong = "oppinion" and right = "opinion" - or - wrong = "opponant" and right = "opponent" - or - wrong = "oppononent" and right = "opponent" - or - wrong = "oppositition" and right = "opposition" - or - wrong = "oppossed" and right = "opposed" - or - wrong = "opprotunity" and right = "opportunity" - or - wrong = "opression" and right = "oppression" - or - wrong = "opressive" and right = "oppressive" - or - wrong = "opthalmic" and right = "ophthalmic" - or - wrong = "opthalmologist" and right = "ophthalmologist" - or - wrong = "opthalmology" and right = "ophthalmology" - or - wrong = "opthamologist" and right = "ophthalmologist" - or - wrong = "optmizations" and right = "optimizations" - or - wrong = "optomism" and right = "optimism" - or - wrong = "orded" and right = "ordered" - or - wrong = "organim" and right = "organism" - or - wrong = "organistion" and right = "organisation" - or - wrong = "organiztion" and right = "organization" - or - wrong = "orgin" and right = "organ" - or - wrong = "orgin" and right = "origin" - or - wrong = "orginal" and right = "original" - or - wrong = "orginally" and right = "originally" - or - wrong = "orginize" and right = "organise" - or - wrong = "oridinarily" and right = "ordinarily" - or - wrong = "origanaly" and right = "originally" - or - wrong = "originall" and right = "original" - or - wrong = "originall" and right = "originally" - or - wrong = "originaly" and right = "originally" - or - wrong = "originially" and right = "originally" - or - wrong = "originnally" and right = "originally" - or - wrong = "origional" and right = "original" - or - wrong = "orignally" and right = "originally" - or - wrong = "orignially" and right = "originally" - or - wrong = "otehr" and right = "other" - or - wrong = "oublisher" and right = "publisher" - or - wrong = "ouevre" and right = "oeuvre" - or - wrong = "ouput" and right = "output" - or - wrong = "oustanding" and right = "outstanding" - or - wrong = "overriden" and right = "overridden" - or - wrong = "overshaddowed" and right = "overshadowed" - or - wrong = "overwelming" and right = "overwhelming" - or - wrong = "overwheliming" and right = "overwhelming" - or - wrong = "owrk" and right = "work" - or - wrong = "owudl" and right = "would" - or - wrong = "oxigen" and right = "oxygen" - or - wrong = "oximoron" and right = "oxymoron" - or - wrong = "p0enis" and right = "penis" - or - wrong = "paide" and right = "paid" - or - wrong = "paitience" and right = "patience" - or - wrong = "palce" and right = "palace" - or - wrong = "palce" and right = "place" - or - wrong = "paleolitic" and right = "paleolithic" - or - wrong = "paliamentarian" and right = "parliamentarian" - or - wrong = "palistian" and right = "palestinian" - or - wrong = "palistinian" and right = "palestinian" - or - wrong = "palistinians" and right = "palestinians" - or - wrong = "pallete" and right = "palette" - or - wrong = "pamflet" and right = "pamphlet" - or - wrong = "pamplet" and right = "pamphlet" - or - wrong = "pantomine" and right = "pantomime" - or - wrong = "papanicalou" and right = "papanicolaou" - or - wrong = "paralel" and right = "parallel" - or - wrong = "paralell" and right = "parallel" - or - wrong = "paralelly" and right = "parallelly" - or - wrong = "paralely" and right = "parallelly" - or - wrong = "parallely" and right = "parallelly" - or - wrong = "paramater" and right = "parameter" - or - wrong = "paramters" and right = "parameters" - or - wrong = "parametarized" and right = "parameterized" - or - wrong = "paranthesis" and right = "parenthesis" - or - wrong = "paraphenalia" and right = "paraphernalia" - or - wrong = "parellels" and right = "parallels" - or - wrong = "parisitic" and right = "parasitic" - or - wrong = "parituclar" and right = "particular" - or - wrong = "parliment" and right = "parliament" - or - wrong = "parrakeets" and right = "parakeets" - or - wrong = "parralel" and right = "parallel" - or - wrong = "parrallel" and right = "parallel" - or - wrong = "parrallell" and right = "parallel" - or - wrong = "parrallelly" and right = "parallelly" - or - wrong = "parrallely" and right = "parallelly" - or - wrong = "partialy" and right = "partially" - or - wrong = "particually" and right = "particularly" - or - wrong = "particualr" and right = "particular" - or - wrong = "particuarly" and right = "particularly" - or - wrong = "particularily" and right = "particularly" - or - wrong = "particulary" and right = "particularly" - or - wrong = "pary" and right = "party" - or - wrong = "pased" and right = "passed" - or - wrong = "pasengers" and right = "passengers" - or - wrong = "passerbys" and right = "passersby" - or - wrong = "pasttime" and right = "pastime" - or - wrong = "pastural" and right = "pastoral" - or - wrong = "paticular" and right = "particular" - or - wrong = "pattented" and right = "patented" - or - wrong = "pavillion" and right = "pavilion" - or - wrong = "payed" and right = "paid" - or - wrong = "pblisher" and right = "publisher" - or - wrong = "pbulisher" and right = "publisher" - or - wrong = "peageant" and right = "pageant" - or - wrong = "peaple" and right = "people" - or - wrong = "peaples" and right = "peoples" - or - wrong = "peculure" and right = "peculiar" - or - wrong = "pedestrain" and right = "pedestrian" - or - wrong = "peformed" and right = "performed" - or - wrong = "peice" and right = "piece" - or - wrong = "peloponnes" and right = "peloponnesus" - or - wrong = "penatly" and right = "penalty" - or - wrong = "penerator" and right = "penetrator" - or - wrong = "penisula" and right = "peninsula" - or - wrong = "penisular" and right = "peninsular" - or - wrong = "penninsula" and right = "peninsula" - or - wrong = "penninsular" and right = "peninsular" - or - wrong = "pennisula" and right = "peninsula" - or - wrong = "pennyslvania" and right = "pennsylvania" - or - wrong = "pensinula" and right = "peninsula" - or - wrong = "pensle" and right = "pencil" - or - wrong = "peom" and right = "poem" - or - wrong = "peoms" and right = "poems" - or - wrong = "peopel" and right = "people" - or - wrong = "peopels" and right = "peoples" - or - wrong = "peotry" and right = "poetry" - or - wrong = "perade" and right = "parade" - or - wrong = "percepted" and right = "perceived" - or - wrong = "percieve" and right = "perceive" - or - wrong = "percieved" and right = "perceived" - or - wrong = "perenially" and right = "perennially" - or - wrong = "peretrator" and right = "perpetrator" - or - wrong = "perfomance" and right = "performance" - or - wrong = "perfomers" and right = "performers" - or - wrong = "performence" and right = "performance" - or - wrong = "performes" and right = "performed" - or - wrong = "performes" and right = "performs" - or - wrong = "perhasp" and right = "perhaps" - or - wrong = "perheaps" and right = "perhaps" - or - wrong = "perhpas" and right = "perhaps" - or - wrong = "peripathetic" and right = "peripatetic" - or - wrong = "peristent" and right = "persistent" - or - wrong = "perjery" and right = "perjury" - or - wrong = "perjorative" and right = "pejorative" - or - wrong = "permanant" and right = "permanent" - or - wrong = "permenant" and right = "permanent" - or - wrong = "permenantly" and right = "permanently" - or - wrong = "permissable" and right = "permissible" - or - wrong = "perogative" and right = "prerogative" - or - wrong = "peronal" and right = "personal" - or - wrong = "perosnality" and right = "personality" - or - wrong = "perpertrated" and right = "perpetrated" - or - wrong = "perphas" and right = "perhaps" - or - wrong = "perpindicular" and right = "perpendicular" - or - wrong = "persan" and right = "person" - or - wrong = "perseverence" and right = "perseverance" - or - wrong = "persistance" and right = "persistence" - or - wrong = "persistant" and right = "persistent" - or - wrong = "personel" and right = "personal" - or - wrong = "personel" and right = "personnel" - or - wrong = "personell" and right = "personnel" - or - wrong = "personnell" and right = "personnel" - or - wrong = "persuded" and right = "persuaded" - or - wrong = "persue" and right = "pursue" - or - wrong = "persued" and right = "pursued" - or - wrong = "persuing" and right = "pursuing" - or - wrong = "persuit" and right = "pursuit" - or - wrong = "persuits" and right = "pursuits" - or - wrong = "pertubation" and right = "perturbation" - or - wrong = "pertubations" and right = "perturbations" - or - wrong = "pessiary" and right = "pessary" - or - wrong = "petetion" and right = "petition" - or - wrong = "pharoah" and right = "pharaoh" - or - wrong = "phenomenom" and right = "phenomenon" - or - wrong = "phenomenonal" and right = "phenomenal" - or - wrong = "phenomenonly" and right = "phenomenally" - or - wrong = "phenomonenon" and right = "phenomenon" - or - wrong = "phenomonon" and right = "phenomenon" - or - wrong = "phenonmena" and right = "phenomena" - or - wrong = "philipines" and right = "philippines" - or - wrong = "philisopher" and right = "philosopher" - or - wrong = "philisophical" and right = "philosophical" - or - wrong = "philisophy" and right = "philosophy" - or - wrong = "phillipine" and right = "philippine" - or - wrong = "phillipines" and right = "philippines" - or - wrong = "phillippines" and right = "philippines" - or - wrong = "phillosophically" and right = "philosophically" - or - wrong = "philospher" and right = "philosopher" - or - wrong = "philosphies" and right = "philosophies" - or - wrong = "philosphy" and right = "philosophy" - or - wrong = "phonecian" and right = "phoenecian" - or - wrong = "phongraph" and right = "phonograph" - or - wrong = "phylosophical" and right = "philosophical" - or - wrong = "physicaly" and right = "physically" - or - wrong = "piblisher" and right = "publisher" - or - wrong = "pich" and right = "pitch" - or - wrong = "pilgrimmage" and right = "pilgrimage" - or - wrong = "pilgrimmages" and right = "pilgrimages" - or - wrong = "pinapple" and right = "pineapple" - or - wrong = "pinnaple" and right = "pineapple" - or - wrong = "pinoneered" and right = "pioneered" - or - wrong = "plagarism" and right = "plagiarism" - or - wrong = "planation" and right = "plantation" - or - wrong = "planed" and right = "planned" - or - wrong = "plantiff" and right = "plaintiff" - or - wrong = "plateu" and right = "plateau" - or - wrong = "plausable" and right = "plausible" - or - wrong = "playright" and right = "playwright" - or - wrong = "playwrite" and right = "playwright" - or - wrong = "playwrites" and right = "playwrights" - or - wrong = "pleasent" and right = "pleasant" - or - wrong = "plebicite" and right = "plebiscite" - or - wrong = "plesant" and right = "pleasant" - or - wrong = "poenis" and right = "penis" - or - wrong = "poeoples" and right = "peoples" - or - wrong = "poety" and right = "poetry" - or - wrong = "poisin" and right = "poison" - or - wrong = "polical" and right = "political" - or - wrong = "polinator" and right = "pollinator" - or - wrong = "polinators" and right = "pollinators" - or - wrong = "politican" and right = "politician" - or - wrong = "politicans" and right = "politicians" - or - wrong = "poltical" and right = "political" - or - wrong = "polute" and right = "pollute" - or - wrong = "poluted" and right = "polluted" - or - wrong = "polutes" and right = "pollutes" - or - wrong = "poluting" and right = "polluting" - or - wrong = "polution" and right = "pollution" - or - wrong = "polyphonyic" and right = "polyphonic" - or - wrong = "polysaccaride" and right = "polysaccharide" - or - wrong = "polysaccharid" and right = "polysaccharide" - or - wrong = "pomegranite" and right = "pomegranate" - or - wrong = "pomotion" and right = "promotion" - or - wrong = "poportional" and right = "proportional" - or - wrong = "popoulation" and right = "population" - or - wrong = "popularaty" and right = "popularity" - or - wrong = "populare" and right = "popular" - or - wrong = "populer" and right = "popular" - or - wrong = "porshan" and right = "portion" - or - wrong = "porshon" and right = "portion" - or - wrong = "portait" and right = "portrait" - or - wrong = "portayed" and right = "portrayed" - or - wrong = "portraing" and right = "portraying" - or - wrong = "portugese" and right = "portuguese" - or - wrong = "portuguease" and right = "portuguese" - or - wrong = "portugues" and right = "portuguese" - or - wrong = "posess" and right = "possess" - or - wrong = "posessed" and right = "possessed" - or - wrong = "posesses" and right = "possesses" - or - wrong = "posessing" and right = "possessing" - or - wrong = "posession" and right = "possession" - or - wrong = "posessions" and right = "possessions" - or - wrong = "posion" and right = "poison" - or - wrong = "positon" and right = "position" - or - wrong = "positon" and right = "positron" - or - wrong = "possable" and right = "possible" - or - wrong = "possably" and right = "possibly" - or - wrong = "posseses" and right = "possesses" - or - wrong = "possesing" and right = "possessing" - or - wrong = "possesion" and right = "possession" - or - wrong = "possessess" and right = "possesses" - or - wrong = "possibile" and right = "possible" - or - wrong = "possibilty" and right = "possibility" - or - wrong = "possiblility" and right = "possibility" - or - wrong = "possiblilty" and right = "possibility" - or - wrong = "possiblities" and right = "possibilities" - or - wrong = "possiblity" and right = "possibility" - or - wrong = "possition" and right = "position" - or - wrong = "postdam" and right = "potsdam" - or - wrong = "posthomous" and right = "posthumous" - or - wrong = "postion" and right = "position" - or - wrong = "postive" and right = "positive" - or - wrong = "potatos" and right = "potatoes" - or - wrong = "potrait" and right = "portrait" - or - wrong = "potrayed" and right = "portrayed" - or - wrong = "poulations" and right = "populations" - or - wrong = "poverful" and right = "powerful" - or - wrong = "poweful" and right = "powerful" - or - wrong = "powerfull" and right = "powerful" - or - wrong = "ppublisher" and right = "publisher" - or - wrong = "practial" and right = "practical" - or - wrong = "practially" and right = "practically" - or - wrong = "practicaly" and right = "practically" - or - wrong = "practicioner" and right = "practitioner" - or - wrong = "practicioners" and right = "practitioners" - or - wrong = "practicly" and right = "practically" - or - wrong = "practioner" and right = "practitioner" - or - wrong = "practioners" and right = "practitioners" - or - wrong = "prairy" and right = "prairie" - or - wrong = "prarie" and right = "prairie" - or - wrong = "praries" and right = "prairies" - or - wrong = "pratice" and right = "practice" - or - wrong = "preample" and right = "preamble" - or - wrong = "precedessor" and right = "predecessor" - or - wrong = "preceed" and right = "precede" - or - wrong = "preceeded" and right = "preceded" - or - wrong = "preceeding" and right = "preceding" - or - wrong = "preceeds" and right = "precedes" - or - wrong = "precendence" and right = "precedence" - or - wrong = "precentage" and right = "percentage" - or - wrong = "precice" and right = "precise" - or - wrong = "precisly" and right = "precisely" - or - wrong = "precurser" and right = "precursor" - or - wrong = "predecesors" and right = "predecessors" - or - wrong = "predicatble" and right = "predictable" - or - wrong = "predicitons" and right = "predictions" - or - wrong = "predomiantly" and right = "predominately" - or - wrong = "prefered" and right = "preferred" - or - wrong = "prefering" and right = "preferring" - or - wrong = "preferrably" and right = "preferably" - or - wrong = "pregancies" and right = "pregnancies" - or - wrong = "preiod" and right = "period" - or - wrong = "preliferation" and right = "proliferation" - or - wrong = "premeire" and right = "premiere" - or - wrong = "premeired" and right = "premiered" - or - wrong = "premillenial" and right = "premillennial" - or - wrong = "preminence" and right = "preeminence" - or - wrong = "premission" and right = "permission" - or - wrong = "premonasterians" and right = "premonstratensians" - or - wrong = "preocupation" and right = "preoccupation" - or - wrong = "prepair" and right = "prepare" - or - wrong = "prepartion" and right = "preparation" - or - wrong = "prepatory" and right = "preparatory" - or - wrong = "preperation" and right = "preparation" - or - wrong = "preperations" and right = "preparations" - or - wrong = "preriod" and right = "period" - or - wrong = "presedential" and right = "presidential" - or - wrong = "presense" and right = "presence" - or - wrong = "presidenital" and right = "presidential" - or - wrong = "presidental" and right = "presidential" - or - wrong = "presitgious" and right = "prestigious" - or - wrong = "prespective" and right = "perspective" - or - wrong = "prestigeous" and right = "prestigious" - or - wrong = "prestigous" and right = "prestigious" - or - wrong = "presumabely" and right = "presumably" - or - wrong = "presumibly" and right = "presumably" - or - wrong = "pretection" and right = "protection" - or - wrong = "prevelant" and right = "prevalent" - or - wrong = "preverse" and right = "perverse" - or - wrong = "previvous" and right = "previous" - or - wrong = "pricipal" and right = "principal" - or - wrong = "priciple" and right = "principle" - or - wrong = "priestood" and right = "priesthood" - or - wrong = "primarly" and right = "primarily" - or - wrong = "primative" and right = "primitive" - or - wrong = "primatively" and right = "primitively" - or - wrong = "primatives" and right = "primitives" - or - wrong = "primordal" and right = "primordial" - or - wrong = "principaly" and right = "principality" - or - wrong = "principial" and right = "principal" - or - wrong = "principlaity" and right = "principality" - or - wrong = "principly" and right = "principally" - or - wrong = "prinicipal" and right = "principal" - or - wrong = "privalege" and right = "privilege" - or - wrong = "privaleges" and right = "privileges" - or - wrong = "priveledges" and right = "privileges" - or - wrong = "privelege" and right = "privilege" - or - wrong = "priveleged" and right = "privileged" - or - wrong = "priveleges" and right = "privileges" - or - wrong = "privelige" and right = "privilege" - or - wrong = "priveliged" and right = "privileged" - or - wrong = "priveliges" and right = "privileges" - or - wrong = "privelleges" and right = "privileges" - or - wrong = "privilage" and right = "privilege" - or - wrong = "priviledge" and right = "privilege" - or - wrong = "priviledges" and right = "privileges" - or - wrong = "privledge" and right = "privilege" - or - wrong = "privte" and right = "private" - or - wrong = "probabilaty" and right = "probability" - or - wrong = "probablistic" and right = "probabilistic" - or - wrong = "probablly" and right = "probably" - or - wrong = "probalibity" and right = "probability" - or - wrong = "probaly" and right = "probably" - or - wrong = "probelm" and right = "problem" - or - wrong = "proccess" and right = "process" - or - wrong = "proccessing" and right = "processing" - or - wrong = "procede" and right = "precede" - or - wrong = "procede" and right = "proceed" - or - wrong = "proceded" and right = "preceded" - or - wrong = "proceded" and right = "proceeded" - or - wrong = "procedes" and right = "precedes" - or - wrong = "procedes" and right = "proceeds" - or - wrong = "procedger" and right = "procedure" - or - wrong = "proceding" and right = "preceding" - or - wrong = "proceding" and right = "proceeding" - or - wrong = "procedings" and right = "proceedings" - or - wrong = "proceedure" and right = "procedure" - or - wrong = "proces" and right = "process" - or - wrong = "procesed" and right = "processed" - or - wrong = "processer" and right = "processor" - or - wrong = "proclaimation" and right = "proclamation" - or - wrong = "proclamed" and right = "proclaimed" - or - wrong = "proclaming" and right = "proclaiming" - or - wrong = "proclomation" and right = "proclamation" - or - wrong = "profesion" and right = "profession" - or - wrong = "profesion" and right = "profusion" - or - wrong = "profesor" and right = "professor" - or - wrong = "professer" and right = "professor" - or - wrong = "proffesed" and right = "professed" - or - wrong = "proffesion" and right = "profession" - or - wrong = "proffesional" and right = "professional" - or - wrong = "proffesor" and right = "professor" - or - wrong = "profilic" and right = "prolific" - or - wrong = "progessed" and right = "progressed" - or - wrong = "progidy" and right = "prodigy" - or - wrong = "programable" and right = "programmable" - or - wrong = "progrom" and right = "pogrom" - or - wrong = "progrom" and right = "program" - or - wrong = "progroms" and right = "pogroms" - or - wrong = "progroms" and right = "programs" - or - wrong = "prohabition" and right = "prohibition" - or - wrong = "prologomena" and right = "prolegomena" - or - wrong = "prominance" and right = "prominence" - or - wrong = "prominant" and right = "prominent" - or - wrong = "prominantly" and right = "prominently" - or - wrong = "prominately" and right = "predominately" - or - wrong = "prominately" and right = "prominently" - or - wrong = "promiscous" and right = "promiscuous" - or - wrong = "promotted" and right = "promoted" - or - wrong = "pronomial" and right = "pronominal" - or - wrong = "pronouced" and right = "pronounced" - or - wrong = "pronounched" and right = "pronounced" - or - wrong = "pronounciation" and right = "pronunciation" - or - wrong = "proove" and right = "prove" - or - wrong = "prooved" and right = "proved" - or - wrong = "prophacy" and right = "prophecy" - or - wrong = "propietary" and right = "proprietary" - or - wrong = "propmted" and right = "prompted" - or - wrong = "propoganda" and right = "propaganda" - or - wrong = "propogate" and right = "propagate" - or - wrong = "propogates" and right = "propagates" - or - wrong = "propogation" and right = "propagation" - or - wrong = "propostion" and right = "proposition" - or - wrong = "propotions" and right = "proportions" - or - wrong = "propper" and right = "proper" - or - wrong = "propperly" and right = "properly" - or - wrong = "proprietory" and right = "proprietary" - or - wrong = "proseletyzing" and right = "proselytizing" - or - wrong = "protaganist" and right = "protagonist" - or - wrong = "protaganists" and right = "protagonists" - or - wrong = "protocal" and right = "protocol" - or - wrong = "protoganist" and right = "protagonist" - or - wrong = "prototpe" and right = "prototype" - or - wrong = "protoype" and right = "prototype" - or - wrong = "protrayed" and right = "portrayed" - or - wrong = "protruberance" and right = "protuberance" - or - wrong = "protruberances" and right = "protuberances" - or - wrong = "prouncements" and right = "pronouncements" - or - wrong = "provacative" and right = "provocative" - or - wrong = "provded" and right = "provided" - or - wrong = "provicial" and right = "provincial" - or - wrong = "provinicial" and right = "provincial" - or - wrong = "provisiosn" and right = "provision" - or - wrong = "provisonal" and right = "provisional" - or - wrong = "proximty" and right = "proximity" - or - wrong = "pseudononymous" and right = "pseudonymous" - or - wrong = "pseudonyn" and right = "pseudonym" - or - wrong = "psuedo" and right = "pseudo" - or - wrong = "psycology" and right = "psychology" - or - wrong = "psyhic" and right = "psychic" - or - wrong = "pubilsher" and right = "publisher" - or - wrong = "pubisher" and right = "publisher" - or - wrong = "publiaher" and right = "publisher" - or - wrong = "publically" and right = "publicly" - or - wrong = "publicaly" and right = "publicly" - or - wrong = "publicher" and right = "publisher" - or - wrong = "publihser" and right = "publisher" - or - wrong = "publisehr" and right = "publisher" - or - wrong = "publiser" and right = "publisher" - or - wrong = "publisger" and right = "publisher" - or - wrong = "publisheed" and right = "published" - or - wrong = "publisherr" and right = "publisher" - or - wrong = "publishher" and right = "publisher" - or - wrong = "publishor" and right = "publisher" - or - wrong = "publishre" and right = "publisher" - or - wrong = "publissher" and right = "publisher" - or - wrong = "publlisher" and right = "publisher" - or - wrong = "publsiher" and right = "publisher" - or - wrong = "publusher" and right = "publisher" - or - wrong = "puchasing" and right = "purchasing" - or - wrong = "pucini" and right = "puccini" - or - wrong = "pulisher" and right = "publisher" - or - wrong = "pumkin" and right = "pumpkin" - or - wrong = "puplisher" and right = "publisher" - or - wrong = "puritannical" and right = "puritanical" - or - wrong = "purposedly" and right = "purposely" - or - wrong = "purpotedly" and right = "purportedly" - or - wrong = "pursuade" and right = "persuade" - or - wrong = "pursuaded" and right = "persuaded" - or - wrong = "pursuades" and right = "persuades" - or - wrong = "pususading" and right = "persuading" - or - wrong = "puting" and right = "putting" - or - wrong = "pwoer" and right = "power" - or - wrong = "pyscic" and right = "psychic" - or - wrong = "qtuie" and right = "quiet" - or - wrong = "qtuie" and right = "quite" - or - wrong = "quantaty" and right = "quantity" - or - wrong = "quantitiy" and right = "quantity" - or - wrong = "quarantaine" and right = "quarantine" - or - wrong = "queenland" and right = "queensland" - or - wrong = "questonable" and right = "questionable" - or - wrong = "quicklyu" and right = "quickly" - or - wrong = "quinessential" and right = "quintessential" - or - wrong = "quitted" and right = "quit" - or - wrong = "quizes" and right = "quizzes" - or - wrong = "qutie" and right = "quiet" - or - wrong = "qutie" and right = "quite" - or - wrong = "rabinnical" and right = "rabbinical" - or - wrong = "racaus" and right = "raucous" - or - wrong = "radiactive" and right = "radioactive" - or - wrong = "radify" and right = "ratify" - or - wrong = "raelly" and right = "really" - or - wrong = "rarified" and right = "rarefied" - or - wrong = "reaccurring" and right = "recurring" - or - wrong = "reacing" and right = "reaching" - or - wrong = "reacll" and right = "recall" - or - wrong = "readmition" and right = "readmission" - or - wrong = "realitvely" and right = "relatively" - or - wrong = "realsitic" and right = "realistic" - or - wrong = "realtions" and right = "relations" - or - wrong = "realy" and right = "really" - or - wrong = "realyl" and right = "really" - or - wrong = "reasearch" and right = "research" - or - wrong = "rebiulding" and right = "rebuilding" - or - wrong = "rebllions" and right = "rebellions" - or - wrong = "rebounce" and right = "rebound" - or - wrong = "reccomend" and right = "recommend" - or - wrong = "reccomendations" and right = "recommendations" - or - wrong = "reccomended" and right = "recommended" - or - wrong = "reccomending" and right = "recommending" - or - wrong = "reccommend" and right = "recommend" - or - wrong = "reccommended" and right = "recommended" - or - wrong = "reccommending" and right = "recommending" - or - wrong = "reccuring" and right = "recurring" - or - wrong = "receeded" and right = "receded" - or - wrong = "receeding" and right = "receding" - or - wrong = "recepient" and right = "recipient" - or - wrong = "recepients" and right = "recipients" - or - wrong = "receving" and right = "receiving" - or - wrong = "rechargable" and right = "rechargeable" - or - wrong = "reched" and right = "reached" - or - wrong = "recide" and right = "reside" - or - wrong = "recided" and right = "resided" - or - wrong = "recident" and right = "resident" - or - wrong = "recidents" and right = "residents" - or - wrong = "reciding" and right = "residing" - or - wrong = "reciepents" and right = "recipients" - or - wrong = "reciept" and right = "receipt" - or - wrong = "recieve" and right = "receive" - or - wrong = "recieved" and right = "received" - or - wrong = "reciever" and right = "receiver" - or - wrong = "recievers" and right = "receivers" - or - wrong = "recieves" and right = "receives" - or - wrong = "recieving" and right = "receiving" - or - wrong = "recipiant" and right = "recipient" - or - wrong = "recipiants" and right = "recipients" - or - wrong = "recived" and right = "received" - or - wrong = "recivership" and right = "receivership" - or - wrong = "recogise" and right = "recognise" - or - wrong = "recogize" and right = "recognize" - or - wrong = "recomend" and right = "recommend" - or - wrong = "recomended" and right = "recommended" - or - wrong = "recomending" and right = "recommending" - or - wrong = "recomends" and right = "recommends" - or - wrong = "recommedations" and right = "recommendations" - or - wrong = "recompence" and right = "recompense" - or - wrong = "reconaissance" and right = "reconnaissance" - or - wrong = "reconcilation" and right = "reconciliation" - or - wrong = "reconized" and right = "recognized" - or - wrong = "reconnaisance" and right = "reconnaissance" - or - wrong = "reconnaissence" and right = "reconnaissance" - or - wrong = "recontructed" and right = "reconstructed" - or - wrong = "recquired" and right = "required" - or - wrong = "recrational" and right = "recreational" - or - wrong = "recrod" and right = "record" - or - wrong = "recuiting" and right = "recruiting" - or - wrong = "recuring" and right = "recurring" - or - wrong = "recurrance" and right = "recurrence" - or - wrong = "rediculous" and right = "ridiculous" - or - wrong = "reedeming" and right = "redeeming" - or - wrong = "reenforced" and right = "reinforced" - or - wrong = "refect" and right = "reflect" - or - wrong = "refedendum" and right = "referendum" - or - wrong = "referal" and right = "referral" - or - wrong = "referece" and right = "reference" - or - wrong = "refereces" and right = "references" - or - wrong = "refered" and right = "referred" - or - wrong = "referemce" and right = "reference" - or - wrong = "referemces" and right = "references" - or - wrong = "referencs" and right = "references" - or - wrong = "referenece" and right = "reference" - or - wrong = "refereneced" and right = "referenced" - or - wrong = "refereneces" and right = "references" - or - wrong = "referiang" and right = "referring" - or - wrong = "refering" and right = "referring" - or - wrong = "refernce" and right = "reference" - or - wrong = "refernce" and right = "references" - or - wrong = "refernces" and right = "references" - or - wrong = "referrence" and right = "reference" - or - wrong = "referrences" and right = "references" - or - wrong = "referrs" and right = "refers" - or - wrong = "reffered" and right = "referred" - or - wrong = "refference" and right = "reference" - or - wrong = "reffering" and right = "referring" - or - wrong = "refrence" and right = "reference" - or - wrong = "refrences" and right = "references" - or - wrong = "refrers" and right = "refers" - or - wrong = "refridgeration" and right = "refrigeration" - or - wrong = "refridgerator" and right = "refrigerator" - or - wrong = "refromist" and right = "reformist" - or - wrong = "refusla" and right = "refusal" - or - wrong = "regardes" and right = "regards" - or - wrong = "regluar" and right = "regular" - or - wrong = "reguarly" and right = "regularly" - or - wrong = "regulaion" and right = "regulation" - or - wrong = "regulaotrs" and right = "regulators" - or - wrong = "regularily" and right = "regularly" - or - wrong = "rehersal" and right = "rehearsal" - or - wrong = "reicarnation" and right = "reincarnation" - or - wrong = "reigining" and right = "reigning" - or - wrong = "reknown" and right = "renown" - or - wrong = "reknowned" and right = "renowned" - or - wrong = "rela" and right = "real" - or - wrong = "relaly" and right = "really" - or - wrong = "relatiopnship" and right = "relationship" - or - wrong = "relativly" and right = "relatively" - or - wrong = "relected" and right = "reelected" - or - wrong = "releive" and right = "relieve" - or - wrong = "releived" and right = "relieved" - or - wrong = "releiver" and right = "reliever" - or - wrong = "releses" and right = "releases" - or - wrong = "relevence" and right = "relevance" - or - wrong = "relevent" and right = "relevant" - or - wrong = "reliablity" and right = "reliability" - or - wrong = "relient" and right = "reliant" - or - wrong = "religeous" and right = "religious" - or - wrong = "religous" and right = "religious" - or - wrong = "religously" and right = "religiously" - or - wrong = "relinqushment" and right = "relinquishment" - or - wrong = "relitavely" and right = "relatively" - or - wrong = "relized" and right = "realised" - or - wrong = "relized" and right = "realized" - or - wrong = "relpacement" and right = "replacement" - or - wrong = "remaing" and right = "remaining" - or - wrong = "remeber" and right = "remember" - or - wrong = "rememberable" and right = "memorable" - or - wrong = "rememberance" and right = "remembrance" - or - wrong = "remembrence" and right = "remembrance" - or - wrong = "remenant" and right = "remnant" - or - wrong = "remenicent" and right = "reminiscent" - or - wrong = "reminent" and right = "remnant" - or - wrong = "reminescent" and right = "reminiscent" - or - wrong = "reminscent" and right = "reminiscent" - or - wrong = "reminsicent" and right = "reminiscent" - or - wrong = "rendevous" and right = "rendezvous" - or - wrong = "rendezous" and right = "rendezvous" - or - wrong = "renedered" and right = "rende" - or - wrong = "renewl" and right = "renewal" - or - wrong = "rennovate" and right = "renovate" - or - wrong = "rennovated" and right = "renovated" - or - wrong = "rennovating" and right = "renovating" - or - wrong = "rennovation" and right = "renovation" - or - wrong = "rentors" and right = "renters" - or - wrong = "reoccurrence" and right = "recurrence" - or - wrong = "reorganision" and right = "reorganisation" - or - wrong = "repatition" and right = "repartition" - or - wrong = "repatition" and right = "repetition" - or - wrong = "repblic" and right = "republic" - or - wrong = "repblican" and right = "republican" - or - wrong = "repblicans" and right = "republicans" - or - wrong = "repblics" and right = "republics" - or - wrong = "repectively" and right = "respectively" - or - wrong = "repeition" and right = "repetition" - or - wrong = "repentence" and right = "repentance" - or - wrong = "repentent" and right = "repentant" - or - wrong = "repeteadly" and right = "repeatedly" - or - wrong = "repetion" and right = "repetition" - or - wrong = "repid" and right = "rapid" - or - wrong = "reponse" and right = "response" - or - wrong = "reponsible" and right = "responsible" - or - wrong = "reportadly" and right = "reportedly" - or - wrong = "represantative" and right = "representative" - or - wrong = "representive" and right = "representative" - or - wrong = "representives" and right = "representatives" - or - wrong = "reproducable" and right = "reproducible" - or - wrong = "reprtoire" and right = "repertoire" - or - wrong = "repsectively" and right = "respectively" - or - wrong = "reptition" and right = "repetition" - or - wrong = "repubic" and right = "republic" - or - wrong = "repubican" and right = "republican" - or - wrong = "repubicans" and right = "republicans" - or - wrong = "repubics" and right = "republics" - or - wrong = "republi" and right = "republic" - or - wrong = "republian" and right = "republican" - or - wrong = "republians" and right = "republicans" - or - wrong = "republis" and right = "republics" - or - wrong = "repulic" and right = "republic" - or - wrong = "repulican" and right = "republican" - or - wrong = "repulicans" and right = "republicans" - or - wrong = "repulics" and right = "republics" - or - wrong = "requirment" and right = "requirement" - or - wrong = "requred" and right = "required" - or - wrong = "resaurant" and right = "restaurant" - or - wrong = "resembelance" and right = "resemblance" - or - wrong = "resembes" and right = "resembles" - or - wrong = "resemblence" and right = "resemblance" - or - wrong = "resevoir" and right = "reservoir" - or - wrong = "residental" and right = "residential" - or - wrong = "resignement" and right = "resignment" - or - wrong = "resistable" and right = "resistible" - or - wrong = "resistence" and right = "resistance" - or - wrong = "resistent" and right = "resistant" - or - wrong = "respectivly" and right = "respectively" - or - wrong = "responce" and right = "response" - or - wrong = "responibilities" and right = "responsibilities" - or - wrong = "responisble" and right = "responsible" - or - wrong = "responnsibilty" and right = "responsibility" - or - wrong = "responsability" and right = "responsibility" - or - wrong = "responsibile" and right = "responsible" - or - wrong = "responsibilites" and right = "responsibilities" - or - wrong = "responsiblities" and right = "responsibilities" - or - wrong = "responsiblity" and right = "responsibility" - or - wrong = "ressemblance" and right = "resemblance" - or - wrong = "ressemble" and right = "resemble" - or - wrong = "ressembled" and right = "resembled" - or - wrong = "ressemblence" and right = "resemblance" - or - wrong = "ressembling" and right = "resembling" - or - wrong = "resssurecting" and right = "resurrecting" - or - wrong = "ressurect" and right = "resurrect" - or - wrong = "ressurected" and right = "resurrected" - or - wrong = "ressurection" and right = "resurrection" - or - wrong = "ressurrection" and right = "resurrection" - or - wrong = "restarant" and right = "restaurant" - or - wrong = "restarants" and right = "restaurants" - or - wrong = "restaraunt" and right = "restaurant" - or - wrong = "restaraunteur" and right = "restaurateur" - or - wrong = "restaraunteurs" and right = "restaurateurs" - or - wrong = "restaraunts" and right = "restaurants" - or - wrong = "restauranteurs" and right = "restaurateurs" - or - wrong = "restauration" and right = "restoration" - or - wrong = "restauraunt" and right = "restaurant" - or - wrong = "resteraunt" and right = "restaurant" - or - wrong = "resteraunts" and right = "restaurants" - or - wrong = "resticted" and right = "restricted" - or - wrong = "restraunt" and right = "restaurant" - or - wrong = "restraunt" and right = "restraint" - or - wrong = "resturant" and right = "restaurant" - or - wrong = "resturants" and right = "restaurants" - or - wrong = "resturaunt" and right = "restaurant" - or - wrong = "resturaunts" and right = "restaurants" - or - wrong = "resurecting" and right = "resurrecting" - or - wrong = "retalitated" and right = "retaliated" - or - wrong = "retalitation" and right = "retaliation" - or - wrong = "retreive" and right = "retrieve" - or - wrong = "retrive" and right = "retrieve" - or - wrong = "returnd" and right = "returned" - or - wrong = "revaluated" and right = "reevaluated" - or - wrong = "reveiw" and right = "review" - or - wrong = "reveral" and right = "reversal" - or - wrong = "reversable" and right = "reversible" - or - wrong = "revolutionar" and right = "revolutionary" - or - wrong = "rewitten" and right = "rewritten" - or - wrong = "rewriet" and right = "rewrite" - or - wrong = "rference" and right = "reference" - or - wrong = "rferences" and right = "references" - or - wrong = "rhymme" and right = "rhyme" - or - wrong = "rhythem" and right = "rhythm" - or - wrong = "rhythim" and right = "rhythm" - or - wrong = "rhytmic" and right = "rhythmic" - or - wrong = "rigeur" and right = "rigor" - or - wrong = "rigeur" and right = "rigour" - or - wrong = "rigeur" and right = "rigueur" - or - wrong = "rigourous" and right = "rigorous" - or - wrong = "rininging" and right = "ringing" - or - wrong = "rised" and right = "raised" - or - wrong = "rised" and right = "rose" - or - wrong = "rockerfeller" and right = "rockefeller" - or - wrong = "rococco" and right = "rococo" - or - wrong = "rocord" and right = "record" - or - wrong = "roomate" and right = "roommate" - or - wrong = "rougly" and right = "roughly" - or - wrong = "rucuperate" and right = "recuperate" - or - wrong = "rudimentatry" and right = "rudimentary" - or - wrong = "rulle" and right = "rule" - or - wrong = "runing" and right = "running" - or - wrong = "runnung" and right = "running" - or - wrong = "russina" and right = "russian" - or - wrong = "russion" and right = "russian" - or - wrong = "rwite" and right = "write" - or - wrong = "rythem" and right = "rhythm" - or - wrong = "rythim" and right = "rhythm" - or - wrong = "rythm" and right = "rhythm" - or - wrong = "rythmic" and right = "rhythmic" - or - wrong = "rythyms" and right = "rhythms" - or - wrong = "sacrafice" and right = "sacrifice" - or - wrong = "sacreligious" and right = "sacrilegious" - or - wrong = "sacremento" and right = "sacramento" - or - wrong = "sacrifical" and right = "sacrificial" - or - wrong = "saftey" and right = "safety" - or - wrong = "safty" and right = "safety" - or - wrong = "salery" and right = "salary" - or - wrong = "sanctionning" and right = "sanctioning" - or - wrong = "sandwhich" and right = "sandwich" - or - wrong = "sanhedrim" and right = "sanhedrin" - or - wrong = "santioned" and right = "sanctioned" - or - wrong = "sargant" and right = "sergeant" - or - wrong = "sargeant" and right = "sergeant" - or - wrong = "sasy" and right = "sassy" - or - wrong = "sasy" and right = "says" - or - wrong = "satelite" and right = "satellite" - or - wrong = "satelites" and right = "satellites" - or - wrong = "saterday" and right = "saturday" - or - wrong = "saterdays" and right = "saturdays" - or - wrong = "satisfactority" and right = "satisfactorily" - or - wrong = "satric" and right = "satiric" - or - wrong = "satrical" and right = "satirical" - or - wrong = "satrically" and right = "satirically" - or - wrong = "sattelite" and right = "satellite" - or - wrong = "sattelites" and right = "satellites" - or - wrong = "saught" and right = "sought" - or - wrong = "saveing" and right = "saving" - or - wrong = "saxaphone" and right = "saxophone" - or - wrong = "scaleable" and right = "scalable" - or - wrong = "scandanavia" and right = "scandinavia" - or - wrong = "scaricity" and right = "scarcity" - or - wrong = "scavanged" and right = "scavenged" - or - wrong = "schedual" and right = "schedule" - or - wrong = "scholarhip" and right = "scholarship" - or - wrong = "scholarstic" and right = "scholarly" - or - wrong = "scholarstic" and right = "scholastic" - or - wrong = "scientfic" and right = "scientific" - or - wrong = "scientifc" and right = "scientific" - or - wrong = "scientis" and right = "scientist" - or - wrong = "scince" and right = "science" - or - wrong = "scinece" and right = "science" - or - wrong = "scirpt" and right = "script" - or - wrong = "scoll" and right = "scroll" - or - wrong = "screenwrighter" and right = "screenwriter" - or - wrong = "scrutinity" and right = "scrutiny" - or - wrong = "scuptures" and right = "sculptures" - or - wrong = "seach" and right = "search" - or - wrong = "seached" and right = "searched" - or - wrong = "seaches" and right = "searches" - or - wrong = "secceeded" and right = "seceded" - or - wrong = "secceeded" and right = "succeeded" - or - wrong = "seceed" and right = "secede" - or - wrong = "seceed" and right = "succeed" - or - wrong = "seceeded" and right = "seceded" - or - wrong = "seceeded" and right = "succeeded" - or - wrong = "secratary" and right = "secretary" - or - wrong = "secretery" and right = "secretary" - or - wrong = "sedereal" and right = "sidereal" - or - wrong = "seeked" and right = "sought" - or - wrong = "segementation" and right = "segmentation" - or - wrong = "seguoys" and right = "segues" - or - wrong = "seige" and right = "siege" - or - wrong = "seing" and right = "seeing" - or - wrong = "seinor" and right = "senior" - or - wrong = "seldomly" and right = "seldom" - or - wrong = "senarios" and right = "scenarios" - or - wrong = "sence" and right = "sense" - or - wrong = "sence" and right = "since" - or - wrong = "senstive" and right = "sensitive" - or - wrong = "sensure" and right = "censure" - or - wrong = "seperate" and right = "separate" - or - wrong = "seperated" and right = "separated" - or - wrong = "seperately" and right = "separately" - or - wrong = "seperates" and right = "separates" - or - wrong = "seperating" and right = "separating" - or - wrong = "seperation" and right = "separation" - or - wrong = "seperatism" and right = "separatism" - or - wrong = "seperatist" and right = "separatist" - or - wrong = "seperator" and right = "separator" - or - wrong = "sepina" and right = "subpoena" - or - wrong = "sepulchure" and right = "sepulcher" - or - wrong = "sepulchure" and right = "sepulchre" - or - wrong = "sepulcre" and right = "sepulcher" - or - wrong = "sepulcre" and right = "sepulchre" - or - wrong = "sergent" and right = "sergeant" - or - wrong = "settelement" and right = "settlement" - or - wrong = "settlment" and right = "settlement" - or - wrong = "settting" and right = "setting" - or - wrong = "severeal" and right = "several" - or - wrong = "severley" and right = "severely" - or - wrong = "severly" and right = "severely" - or - wrong = "sevice" and right = "service" - or - wrong = "shadasloo" and right = "shadaloo" - or - wrong = "shaddow" and right = "shadow" - or - wrong = "shadoloo" and right = "shadaloo" - or - wrong = "shamen" and right = "shaman" - or - wrong = "shamen" and right = "shamans" - or - wrong = "sheat" and right = "cheat" - or - wrong = "sheat" and right = "sheath" - or - wrong = "sheat" and right = "sheet" - or - wrong = "sheild" and right = "shield" - or - wrong = "sherif" and right = "sheriff" - or - wrong = "shineing" and right = "shining" - or - wrong = "shiped" and right = "shipped" - or - wrong = "shiping" and right = "shipping" - or - wrong = "shopkeeepers" and right = "shopkeepers" - or - wrong = "shorly" and right = "shortly" - or - wrong = "shoudl" and right = "should" - or - wrong = "shoudln" and right = "should" - or - wrong = "shreak" and right = "shriek" - or - wrong = "shrinked" and right = "shrunk" - or - wrong = "sicne" and right = "since" - or - wrong = "sideral" and right = "sidereal" - or - wrong = "sieze" and right = "seize" - or - wrong = "sieze" and right = "size" - or - wrong = "siezed" and right = "seized" - or - wrong = "siezed" and right = "sized" - or - wrong = "siezing" and right = "seizing" - or - wrong = "siezing" and right = "sizing" - or - wrong = "siezure" and right = "seizure" - or - wrong = "siezures" and right = "seizures" - or - wrong = "siginificant" and right = "significant" - or - wrong = "signficant" and right = "significant" - or - wrong = "signficiant" and right = "significant" - or - wrong = "signfies" and right = "signifies" - or - wrong = "signifantly" and right = "significantly" - or - wrong = "significently" and right = "significantly" - or - wrong = "signifigant" and right = "significant" - or - wrong = "signifigantly" and right = "significantly" - or - wrong = "signitories" and right = "signatories" - or - wrong = "signitory" and right = "signatory" - or - wrong = "similarily" and right = "similarly" - or - wrong = "similiar" and right = "similar" - or - wrong = "similiarity" and right = "similarity" - or - wrong = "similiarly" and right = "similarly" - or - wrong = "simmilar" and right = "similar" - or - wrong = "simpley" and right = "simply" - or - wrong = "simplier" and right = "simpler" - or - wrong = "simultanous" and right = "simultaneous" - or - wrong = "simultanously" and right = "simultaneously" - or - wrong = "sincerley" and right = "sincerely" - or - wrong = "singsog" and right = "singsong" - or - wrong = "sinse" and right = "since" - or - wrong = "sinse" and right = "sines" - or - wrong = "sionist" and right = "zionist" - or - wrong = "sionists" and right = "zionists" - or - wrong = "sixtin" and right = "sistine" - or - wrong = "skagerak" and right = "skagerrak" - or - wrong = "skateing" and right = "skating" - or - wrong = "slaugterhouses" and right = "slaughterhouses" - or - wrong = "slighly" and right = "slightly" - or - wrong = "slippy" and right = "slippery" - or - wrong = "slowy" and right = "slowly" - or - wrong = "smae" and right = "same" - or - wrong = "smealting" and right = "smelting" - or - wrong = "smoe" and right = "some" - or - wrong = "sneeks" and right = "sneaks" - or - wrong = "snese" and right = "sneeze" - or - wrong = "socalism" and right = "socialism" - or - wrong = "socities" and right = "societies" - or - wrong = "soem" and right = "some" - or - wrong = "sofware" and right = "software" - or - wrong = "sohw" and right = "show" - or - wrong = "soilders" and right = "soldiers" - or - wrong = "solatary" and right = "solitary" - or - wrong = "soley" and right = "solely" - or - wrong = "soliders" and right = "soldiers" - or - wrong = "soliliquy" and right = "soliloquy" - or - wrong = "soluable" and right = "soluble" - or - wrong = "somene" and right = "someone" - or - wrong = "somtimes" and right = "sometimes" - or - wrong = "somwhere" and right = "somewhere" - or - wrong = "sophicated" and right = "sophisticated" - or - wrong = "sophmore" and right = "sophomore" - or - wrong = "sorceror" and right = "sorcerer" - or - wrong = "sorrounding" and right = "surrounding" - or - wrong = "sotry" and right = "story" - or - wrong = "sotyr" and right = "satyr" - or - wrong = "sotyr" and right = "story" - or - wrong = "soudn" and right = "sound" - or - wrong = "soudns" and right = "sounds" - or - wrong = "sould" and right = "could" - or - wrong = "sould" and right = "should" - or - wrong = "sould" and right = "sold" - or - wrong = "sould" and right = "soul" - or - wrong = "sountrack" and right = "soundtrack" - or - wrong = "sourth" and right = "south" - or - wrong = "sourthern" and right = "southern" - or - wrong = "souvenier" and right = "souvenir" - or - wrong = "souveniers" and right = "souvenirs" - or - wrong = "soveits" and right = "soviets" - or - wrong = "sovereignity" and right = "sovereignty" - or - wrong = "soverign" and right = "sovereign" - or - wrong = "soverignity" and right = "sovereignty" - or - wrong = "soverignty" and right = "sovereignty" - or - wrong = "spainish" and right = "spanish" - or - wrong = "speach" and right = "speech" - or - wrong = "specfic" and right = "specific" - or - wrong = "speciallized" and right = "specialised" - or - wrong = "speciallized" and right = "specialized" - or - wrong = "specif" and right = "specific" - or - wrong = "specif" and right = "specify" - or - wrong = "specifiying" and right = "specifying" - or - wrong = "speciman" and right = "specimen" - or - wrong = "spectauclar" and right = "spectacular" - or - wrong = "spectaulars" and right = "spectaculars" - or - wrong = "spects" and right = "aspects" - or - wrong = "spects" and right = "expects" - or - wrong = "spectum" and right = "spectrum" - or - wrong = "speices" and right = "species" - or - wrong = "spendour" and right = "splendour" - or - wrong = "spermatozoan" and right = "spermatozoon" - or - wrong = "spoace" and right = "space" - or - wrong = "sponser" and right = "sponsor" - or - wrong = "sponsered" and right = "sponsored" - or - wrong = "spontanous" and right = "spontaneous" - or - wrong = "sponzored" and right = "sponsored" - or - wrong = "spoonfulls" and right = "spoonfuls" - or - wrong = "sppeches" and right = "speeches" - or - wrong = "spreaded" and right = "spread" - or - wrong = "sprech" and right = "speech" - or - wrong = "spred" and right = "spread" - or - wrong = "spriritual" and right = "spiritual" - or - wrong = "spritual" and right = "spiritual" - or - wrong = "sqaure" and right = "square" - or - wrong = "sring" and right = "string" - or - wrong = "stablility" and right = "stability" - or - wrong = "stainlees" and right = "stainless" - or - wrong = "staion" and right = "station" - or - wrong = "standars" and right = "standards" - or - wrong = "stange" and right = "strange" - or - wrong = "startegic" and right = "strategic" - or - wrong = "startegies" and right = "strategies" - or - wrong = "startegy" and right = "strategy" - or - wrong = "stateman" and right = "statesman" - or - wrong = "statememts" and right = "statements" - or - wrong = "statment" and right = "statement" - or - wrong = "steriods" and right = "steroids" - or - wrong = "sterotypes" and right = "stereotypes" - or - wrong = "stilus" and right = "stylus" - or - wrong = "stingent" and right = "stringent" - or - wrong = "stiring" and right = "stirring" - or - wrong = "stirrs" and right = "stirs" - or - wrong = "stlye" and right = "style" - or - wrong = "stomache" and right = "stomach" - or - wrong = "stong" and right = "strong" - or - wrong = "stopry" and right = "story" - or - wrong = "storeis" and right = "stories" - or - wrong = "storise" and right = "stories" - or - wrong = "stornegst" and right = "strongest" - or - wrong = "stoyr" and right = "story" - or - wrong = "stpo" and right = "stop" - or - wrong = "stradegies" and right = "strategies" - or - wrong = "stradegy" and right = "strategy" - or - wrong = "strat" and right = "start" - or - wrong = "strat" and right = "strata" - or - wrong = "stratagically" and right = "strategically" - or - wrong = "streemlining" and right = "streamlining" - or - wrong = "stregth" and right = "strength" - or - wrong = "strenghen" and right = "strengthen" - or - wrong = "strenghened" and right = "strengthened" - or - wrong = "strenghening" and right = "strengthening" - or - wrong = "strenght" and right = "strength" - or - wrong = "strenghten" and right = "strengthen" - or - wrong = "strenghtened" and right = "strengthened" - or - wrong = "strenghtening" and right = "strengthening" - or - wrong = "strengtened" and right = "strengthened" - or - wrong = "strenous" and right = "strenuous" - or - wrong = "strictist" and right = "strictest" - or - wrong = "strikely" and right = "strikingly" - or - wrong = "strnad" and right = "strand" - or - wrong = "stroy" and right = "destroy" - or - wrong = "stroy" and right = "story" - or - wrong = "structual" and right = "structural" - or - wrong = "stubborness" and right = "stubbornness" - or - wrong = "stucture" and right = "structure" - or - wrong = "stuctured" and right = "structured" - or - wrong = "studdy" and right = "study" - or - wrong = "studing" and right = "studying" - or - wrong = "stuggling" and right = "struggling" - or - wrong = "sturcture" and right = "structure" - or - wrong = "subcatagories" and right = "subcategories" - or - wrong = "subcatagory" and right = "subcategory" - or - wrong = "subconsiously" and right = "subconsciously" - or - wrong = "subjudgation" and right = "subjugation" - or - wrong = "submachne" and right = "submachine" - or - wrong = "subpecies" and right = "subspecies" - or - wrong = "subsidary" and right = "subsidiary" - or - wrong = "subsiduary" and right = "subsidiary" - or - wrong = "subsquent" and right = "subsequent" - or - wrong = "subsquently" and right = "subsequently" - or - wrong = "substace" and right = "substance" - or - wrong = "substancial" and right = "substantial" - or - wrong = "substatial" and right = "substantial" - or - wrong = "substituded" and right = "substituted" - or - wrong = "substract" and right = "subtract" - or - wrong = "substracted" and right = "subtracted" - or - wrong = "substracting" and right = "subtracting" - or - wrong = "substraction" and right = "subtraction" - or - wrong = "substracts" and right = "subtracts" - or - wrong = "subtances" and right = "substances" - or - wrong = "subterranian" and right = "subterranean" - or - wrong = "suburburban" and right = "suburban" - or - wrong = "succceeded" and right = "succeeded" - or - wrong = "succcesses" and right = "successes" - or - wrong = "succedded" and right = "succeeded" - or - wrong = "succeded" and right = "succeeded" - or - wrong = "succeds" and right = "succeeds" - or - wrong = "succesful" and right = "successful" - or - wrong = "succesfully" and right = "successfully" - or - wrong = "succesfuly" and right = "successfully" - or - wrong = "succesion" and right = "succession" - or - wrong = "succesive" and right = "successive" - or - wrong = "successfull" and right = "successful" - or - wrong = "successully" and right = "successfully" - or - wrong = "succsess" and right = "success" - or - wrong = "succsessfull" and right = "successful" - or - wrong = "suceed" and right = "succeed" - or - wrong = "suceeded" and right = "succeeded" - or - wrong = "suceeding" and right = "succeeding" - or - wrong = "suceeds" and right = "succeeds" - or - wrong = "sucesful" and right = "successful" - or - wrong = "sucesfully" and right = "successfully" - or - wrong = "sucesfuly" and right = "successfully" - or - wrong = "sucesion" and right = "succession" - or - wrong = "sucess" and right = "success" - or - wrong = "sucesses" and right = "successes" - or - wrong = "sucessful" and right = "successful" - or - wrong = "sucessfull" and right = "successful" - or - wrong = "sucessfully" and right = "successfully" - or - wrong = "sucessfuly" and right = "successfully" - or - wrong = "sucession" and right = "succession" - or - wrong = "sucessive" and right = "successive" - or - wrong = "sucessor" and right = "successor" - or - wrong = "sucessot" and right = "successor" - or - wrong = "sucide" and right = "suicide" - or - wrong = "sucidial" and right = "suicidal" - or - wrong = "sudent" and right = "student" - or - wrong = "sudents" and right = "students" - or - wrong = "sufferage" and right = "suffrage" - or - wrong = "sufferred" and right = "suffered" - or - wrong = "sufferring" and right = "suffering" - or - wrong = "sufficent" and right = "sufficient" - or - wrong = "sufficently" and right = "sufficiently" - or - wrong = "sumary" and right = "summary" - or - wrong = "sunglases" and right = "sunglasses" - or - wrong = "suop" and right = "soup" - or - wrong = "superceeded" and right = "superseded" - or - wrong = "superintendant" and right = "superintendent" - or - wrong = "suphisticated" and right = "sophisticated" - or - wrong = "suplimented" and right = "supplemented" - or - wrong = "suported" and right = "supported" - or - wrong = "supose" and right = "suppose" - or - wrong = "suposed" and right = "supposed" - or - wrong = "suposedly" and right = "supposedly" - or - wrong = "suposes" and right = "supposes" - or - wrong = "suposing" and right = "supposing" - or - wrong = "supplamented" and right = "supplemented" - or - wrong = "suppliementing" and right = "supplementing" - or - wrong = "suppoed" and right = "supposed" - or - wrong = "supposingly" and right = "supposedly" - or - wrong = "suppy" and right = "supply" - or - wrong = "suprassing" and right = "surpassing" - or - wrong = "supress" and right = "suppress" - or - wrong = "supressed" and right = "suppressed" - or - wrong = "supresses" and right = "suppresses" - or - wrong = "supressing" and right = "suppressing" - or - wrong = "suprise" and right = "surprise" - or - wrong = "suprised" and right = "surprised" - or - wrong = "suprising" and right = "surprising" - or - wrong = "suprisingly" and right = "surprisingly" - or - wrong = "suprize" and right = "surprise" - or - wrong = "suprized" and right = "surprised" - or - wrong = "suprizing" and right = "surprising" - or - wrong = "suprizingly" and right = "surprisingly" - or - wrong = "surfce" and right = "surface" - or - wrong = "surley" and right = "surely" - or - wrong = "surley" and right = "surly" - or - wrong = "suround" and right = "surround" - or - wrong = "surounded" and right = "surrounded" - or - wrong = "surounding" and right = "surrounding" - or - wrong = "suroundings" and right = "surroundings" - or - wrong = "surounds" and right = "surrounds" - or - wrong = "surplanted" and right = "supplanted" - or - wrong = "surpress" and right = "suppress" - or - wrong = "surpressed" and right = "suppressed" - or - wrong = "surprize" and right = "surprise" - or - wrong = "surprized" and right = "surprised" - or - wrong = "surprizing" and right = "surprising" - or - wrong = "surprizingly" and right = "surprisingly" - or - wrong = "surrended" and right = "surrendered" - or - wrong = "surrended" and right = "surrounded" - or - wrong = "surrepetitious" and right = "surreptitious" - or - wrong = "surrepetitiously" and right = "surreptitiously" - or - wrong = "surreptious" and right = "surreptitious" - or - wrong = "surreptiously" and right = "surreptitiously" - or - wrong = "surronded" and right = "surrounded" - or - wrong = "surrouded" and right = "surrounded" - or - wrong = "surrouding" and right = "surrounding" - or - wrong = "surrundering" and right = "surrendering" - or - wrong = "surveilence" and right = "surveillance" - or - wrong = "surveill" and right = "surveil" - or - wrong = "surveyer" and right = "surveyor" - or - wrong = "surviver" and right = "survivor" - or - wrong = "survivers" and right = "survivors" - or - wrong = "survivied" and right = "survived" - or - wrong = "suseptable" and right = "susceptible" - or - wrong = "suseptible" and right = "susceptible" - or - wrong = "suspention" and right = "suspension" - or - wrong = "swaer" and right = "swear" - or - wrong = "swaers" and right = "swears" - or - wrong = "swepth" and right = "swept" - or - wrong = "swiming" and right = "swimming" - or - wrong = "syas" and right = "says" - or - wrong = "symetrical" and right = "symmetrical" - or - wrong = "symetrically" and right = "symmetrically" - or - wrong = "symetry" and right = "symmetry" - or - wrong = "symettric" and right = "symmetric" - or - wrong = "symmetral" and right = "symmetric" - or - wrong = "symmetricaly" and right = "symmetrically" - or - wrong = "synagouge" and right = "synagogue" - or - wrong = "syncronization" and right = "synchronization" - or - wrong = "synonomous" and right = "synonymous" - or - wrong = "synonymns" and right = "synonyms" - or - wrong = "synphony" and right = "symphony" - or - wrong = "syphyllis" and right = "syphilis" - or - wrong = "sypmtoms" and right = "symptoms" - or - wrong = "syrap" and right = "syrup" - or - wrong = "sysmatically" and right = "systematically" - or - wrong = "sytem" and right = "system" - or - wrong = "sytle" and right = "style" - or - wrong = "tabacco" and right = "tobacco" - or - wrong = "tahn" and right = "than" - or - wrong = "taht" and right = "that" - or - wrong = "talekd" and right = "talked" - or - wrong = "targetted" and right = "targeted" - or - wrong = "targetting" and right = "targeting" - or - wrong = "tast" and right = "taste" - or - wrong = "tath" and right = "that" - or - wrong = "tatoo" and right = "tattoo" - or - wrong = "tattooes" and right = "tattoos" - or - wrong = "taxanomic" and right = "taxonomic" - or - wrong = "taxanomy" and right = "taxonomy" - or - wrong = "teached" and right = "taught" - or - wrong = "techician" and right = "technician" - or - wrong = "techicians" and right = "technicians" - or - wrong = "techiniques" and right = "techniques" - or - wrong = "technitian" and right = "technician" - or - wrong = "technnology" and right = "technology" - or - wrong = "technolgy" and right = "technology" - or - wrong = "teh" and right = "the" - or - wrong = "tehy" and right = "they" - or - wrong = "telelevision" and right = "television" - or - wrong = "televsion" and right = "television" - or - wrong = "telphony" and right = "telephony" - or - wrong = "temerature" and right = "temperature" - or - wrong = "tempalte" and right = "template" - or - wrong = "tempaltes" and right = "templates" - or - wrong = "temparate" and right = "temperate" - or - wrong = "temperarily" and right = "temporarily" - or - wrong = "temperment" and right = "temperament" - or - wrong = "tempertaure" and right = "temperature" - or - wrong = "temperture" and right = "temperature" - or - wrong = "temprary" and right = "temporary" - or - wrong = "tenacle" and right = "tentacle" - or - wrong = "tenacles" and right = "tentacles" - or - wrong = "tendacy" and right = "tendency" - or - wrong = "tendancies" and right = "tendencies" - or - wrong = "tendancy" and right = "tendency" - or - wrong = "tepmorarily" and right = "temporarily" - or - wrong = "terrestial" and right = "terrestrial" - or - wrong = "terriories" and right = "territories" - or - wrong = "terriory" and right = "territory" - or - wrong = "territorist" and right = "terrorist" - or - wrong = "territoy" and right = "territory" - or - wrong = "terroist" and right = "terrorist" - or - wrong = "testiclular" and right = "testicular" - or - wrong = "testomony" and right = "testimony" - or - wrong = "tghe" and right = "the" - or - wrong = "thast" and right = "that" - or - wrong = "theather" and right = "theater" - or - wrong = "theese" and right = "these" - or - wrong = "theif" and right = "thief" - or - wrong = "theives" and right = "thieves" - or - wrong = "themselfs" and right = "themselves" - or - wrong = "themslves" and right = "themselves" - or - wrong = "ther" and right = "the" - or - wrong = "ther" and right = "their" - or - wrong = "ther" and right = "there" - or - wrong = "therafter" and right = "thereafter" - or - wrong = "therby" and right = "thereby" - or - wrong = "theri" and right = "their" - or - wrong = "thgat" and right = "that" - or - wrong = "thge" and right = "the" - or - wrong = "thier" and right = "their" - or - wrong = "thign" and right = "thing" - or - wrong = "thigns" and right = "things" - or - wrong = "thigsn" and right = "things" - or - wrong = "thikn" and right = "think" - or - wrong = "thikning" and right = "thickening" - or - wrong = "thikning" and right = "thinking" - or - wrong = "thikns" and right = "thinks" - or - wrong = "thiunk" and right = "think" - or - wrong = "thn" and right = "then" - or - wrong = "thna" and right = "than" - or - wrong = "thne" and right = "then" - or - wrong = "thnig" and right = "thing" - or - wrong = "thnigs" and right = "things" - or - wrong = "thoughout" and right = "throughout" - or - wrong = "threatend" and right = "threatened" - or - wrong = "threatning" and right = "threatening" - or - wrong = "threee" and right = "three" - or - wrong = "threshhold" and right = "threshold" - or - wrong = "thrid" and right = "third" - or - wrong = "throrough" and right = "thorough" - or - wrong = "throughly" and right = "thoroughly" - or - wrong = "throught" and right = "thought" - or - wrong = "throught" and right = "through" - or - wrong = "throught" and right = "throughout" - or - wrong = "througout" and right = "throughout" - or - wrong = "thru" and right = "through" - or - wrong = "thsi" and right = "this" - or - wrong = "thsoe" and right = "those" - or - wrong = "thta" and right = "that" - or - wrong = "thyat" and right = "that" - or - wrong = "tiem" and right = "tim" - or - wrong = "tiem" and right = "time" - or - wrong = "tihkn" and right = "think" - or - wrong = "tihs" and right = "this" - or - wrong = "timne" and right = "time" - or - wrong = "tiome" and right = "time" - or - wrong = "tiome" and right = "tome" - or - wrong = "tje" and right = "the" - or - wrong = "tjhe" and right = "the" - or - wrong = "tjpanishad" and right = "upanishad" - or - wrong = "tkae" and right = "take" - or - wrong = "tkaes" and right = "takes" - or - wrong = "tkaing" and right = "taking" - or - wrong = "tlaking" and right = "talking" - or - wrong = "tobbaco" and right = "tobacco" - or - wrong = "todya" and right = "today" - or - wrong = "toghether" and right = "together" - or - wrong = "toke" and right = "took" - or - wrong = "tolerence" and right = "tolerance" - or - wrong = "tolkein" and right = "tolkien" - or - wrong = "tomatos" and right = "tomatoes" - or - wrong = "tommorow" and right = "tomorrow" - or - wrong = "tommorrow" and right = "tomorrow" - or - wrong = "tongiht" and right = "tonight" - or - wrong = "toriodal" and right = "toroidal" - or - wrong = "tormenters" and right = "tormentors" - or - wrong = "tornadoe" and right = "tornado" - or - wrong = "torpeados" and right = "torpedoes" - or - wrong = "torpedos" and right = "torpedoes" - or - wrong = "tortise" and right = "tortoise" - or - wrong = "toubles" and right = "troubles" - or - wrong = "tounge" and right = "tongue" - or - wrong = "tourch" and right = "torch" - or - wrong = "tourch" and right = "touch" - or - wrong = "towords" and right = "towards" - or - wrong = "towrad" and right = "toward" - or - wrong = "tradionally" and right = "traditionally" - or - wrong = "traditionaly" and right = "traditionally" - or - wrong = "traditionnal" and right = "traditional" - or - wrong = "traditition" and right = "tradition" - or - wrong = "tradtionally" and right = "traditionally" - or - wrong = "trafficed" and right = "trafficked" - or - wrong = "trafficing" and right = "trafficking" - or - wrong = "trafic" and right = "traffic" - or - wrong = "trancendent" and right = "transcendent" - or - wrong = "trancending" and right = "transcending" - or - wrong = "tranform" and right = "transform" - or - wrong = "tranformed" and right = "transformed" - or - wrong = "transcendance" and right = "transcendence" - or - wrong = "transcendant" and right = "transcendent" - or - wrong = "transcendentational" and right = "transcendental" - or - wrong = "transcripting" and right = "transcribing" - or - wrong = "transcripting" and right = "transcription" - or - wrong = "transending" and right = "transcending" - or - wrong = "transesxuals" and right = "transsexuals" - or - wrong = "transfered" and right = "transferred" - or - wrong = "transfering" and right = "transferring" - or - wrong = "transformaton" and right = "transformation" - or - wrong = "transistion" and right = "transition" - or - wrong = "translater" and right = "translator" - or - wrong = "translaters" and right = "translators" - or - wrong = "transmissable" and right = "transmissible" - or - wrong = "transporation" and right = "transportation" - or - wrong = "tremelo" and right = "tremolo" - or - wrong = "tremelos" and right = "tremolos" - or - wrong = "treshold" and right = "threshold" - or - wrong = "triguered" and right = "triggered" - or - wrong = "triology" and right = "trilogy" - or - wrong = "troling" and right = "trolling" - or - wrong = "troup" and right = "troupe" - or - wrong = "troups" and right = "troops" - or - wrong = "troups" and right = "troupes" - or - wrong = "truely" and right = "truly" - or - wrong = "trustworthyness" and right = "trustworthiness" - or - wrong = "turnk" and right = "trunk" - or - wrong = "turnk" and right = "turnkey" - or - wrong = "tuscon" and right = "tucson" - or - wrong = "tust" and right = "trust" - or - wrong = "twelth" and right = "twelfth" - or - wrong = "twon" and right = "town" - or - wrong = "twpo" and right = "two" - or - wrong = "tyhat" and right = "that" - or - wrong = "tyhe" and right = "they" - or - wrong = "typcial" and right = "typical" - or - wrong = "typicaly" and right = "typically" - or - wrong = "tyranies" and right = "tyrannies" - or - wrong = "tyrany" and right = "tyranny" - or - wrong = "tyrranies" and right = "tyrannies" - or - wrong = "tyrrany" and right = "tyranny" - or - wrong = "ubiquitious" and right = "ubiquitous" - or - wrong = "ublisher" and right = "publisher" - or - wrong = "udpate" and right = "update" - or - wrong = "uise" and right = "use" - or - wrong = "ukranian" and right = "ukrainian" - or - wrong = "ultimely" and right = "ultimately" - or - wrong = "unacompanied" and right = "unaccompanied" - or - wrong = "unahppy" and right = "unhappy" - or - wrong = "unanymous" and right = "unanimous" - or - wrong = "unathorised" and right = "unauthorised" - or - wrong = "unavailible" and right = "unavailable" - or - wrong = "unballance" and right = "unbalance" - or - wrong = "unbeknowst" and right = "unbeknownst" - or - wrong = "unbeleivable" and right = "unbelievable" - or - wrong = "uncertainity" and right = "uncertainty" - or - wrong = "unchallengable" and right = "unchallengeable" - or - wrong = "unchangable" and right = "unchangeable" - or - wrong = "uncompetive" and right = "uncompetitive" - or - wrong = "unconcious" and right = "unconscious" - or - wrong = "unconciousness" and right = "unconsciousness" - or - wrong = "unconfortability" and right = "discomfort" - or - wrong = "uncontitutional" and right = "unconstitutional" - or - wrong = "unconvential" and right = "unconventional" - or - wrong = "undecideable" and right = "undecidable" - or - wrong = "understoon" and right = "understood" - or - wrong = "undesireable" and right = "undesirable" - or - wrong = "undetecable" and right = "undetectable" - or - wrong = "undoubtely" and right = "undoubtedly" - or - wrong = "undreground" and right = "underground" - or - wrong = "uneccesary" and right = "unnecessary" - or - wrong = "unecessary" and right = "unnecessary" - or - wrong = "unequalities" and right = "inequalities" - or - wrong = "unforetunately" and right = "unfortunately" - or - wrong = "unforgetable" and right = "unforgettable" - or - wrong = "unforgiveable" and right = "unforgivable" - or - wrong = "unforseen" and right = "unforeseen" - or - wrong = "unfortunatley" and right = "unfortunately" - or - wrong = "unfortunatly" and right = "unfortunately" - or - wrong = "unfourtunately" and right = "unfortunately" - or - wrong = "unihabited" and right = "uninhabited" - or - wrong = "unilateraly" and right = "unilaterally" - or - wrong = "unilatreal" and right = "unilateral" - or - wrong = "unilatreally" and right = "unilaterally" - or - wrong = "uninterruped" and right = "uninterrupted" - or - wrong = "uninterupted" and right = "uninterrupted" - or - wrong = "unintialized" and right = "uninitialized" - or - wrong = "unitesstates" and right = "unitedstates" - or - wrong = "univeral" and right = "universal" - or - wrong = "univeristies" and right = "universities" - or - wrong = "univeristy" and right = "university" - or - wrong = "univerity" and right = "university" - or - wrong = "universtiy" and right = "university" - or - wrong = "univesities" and right = "universities" - or - wrong = "univesity" and right = "university" - or - wrong = "unkown" and right = "unknown" - or - wrong = "unlikey" and right = "unlikely" - or - wrong = "unmanouverable" and right = "unmaneuverable" - or - wrong = "unmanouverable" and right = "unmanoeuvrable" - or - wrong = "unmistakeably" and right = "unmistakably" - or - wrong = "unneccesarily" and right = "unnecessarily" - or - wrong = "unneccesary" and right = "unnecessary" - or - wrong = "unneccessarily" and right = "unnecessarily" - or - wrong = "unneccessary" and right = "unnecessary" - or - wrong = "unnecesarily" and right = "unnecessarily" - or - wrong = "unnecesary" and right = "unnecessary" - or - wrong = "unoffical" and right = "unofficial" - or - wrong = "unoperational" and right = "nonoperational" - or - wrong = "unoticeable" and right = "unnoticeable" - or - wrong = "unplease" and right = "displease" - or - wrong = "unplesant" and right = "unpleasant" - or - wrong = "unprecendented" and right = "unprecedented" - or - wrong = "unprecidented" and right = "unprecedented" - or - wrong = "unrepentent" and right = "unrepentant" - or - wrong = "unrepetant" and right = "unrepentant" - or - wrong = "unrepetent" and right = "unrepentant" - or - wrong = "unsed" and right = "unsaid" - or - wrong = "unsed" and right = "unused" - or - wrong = "unsed" and right = "used" - or - wrong = "unsubstanciated" and right = "unsubstantiated" - or - wrong = "unsuccesful" and right = "unsuccessful" - or - wrong = "unsuccesfully" and right = "unsuccessfully" - or - wrong = "unsuccessfull" and right = "unsuccessful" - or - wrong = "unsucesful" and right = "unsuccessful" - or - wrong = "unsucesfuly" and right = "unsuccessfully" - or - wrong = "unsucessful" and right = "unsuccessful" - or - wrong = "unsucessfull" and right = "unsuccessful" - or - wrong = "unsucessfully" and right = "unsuccessfully" - or - wrong = "unsuprised" and right = "unsurprised" - or - wrong = "unsuprising" and right = "unsurprising" - or - wrong = "unsuprisingly" and right = "unsurprisingly" - or - wrong = "unsuprized" and right = "unsurprised" - or - wrong = "unsuprizing" and right = "unsurprising" - or - wrong = "unsuprizingly" and right = "unsurprisingly" - or - wrong = "unsurprized" and right = "unsurprised" - or - wrong = "unsurprizing" and right = "unsurprising" - or - wrong = "unsurprizingly" and right = "unsurprisingly" - or - wrong = "untill" and right = "until" - or - wrong = "untranslateable" and right = "untranslatable" - or - wrong = "unuseable" and right = "unusable" - or - wrong = "unusuable" and right = "unusable" - or - wrong = "unviersity" and right = "university" - or - wrong = "unwarrented" and right = "unwarranted" - or - wrong = "unweildly" and right = "unwieldy" - or - wrong = "unwieldly" and right = "unwieldy" - or - wrong = "upcomming" and right = "upcoming" - or - wrong = "upgradded" and right = "upgraded" - or - wrong = "usally" and right = "usually" - or - wrong = "useage" and right = "usage" - or - wrong = "usefull" and right = "useful" - or - wrong = "usefuly" and right = "usefully" - or - wrong = "useing" and right = "using" - or - wrong = "usualy" and right = "usually" - or - wrong = "ususally" and right = "usually" - or - wrong = "vaccum" and right = "vacuum" - or - wrong = "vaccume" and right = "vacuum" - or - wrong = "vacinity" and right = "vicinity" - or - wrong = "vaguaries" and right = "vagaries" - or - wrong = "vaieties" and right = "varieties" - or - wrong = "vailidty" and right = "validity" - or - wrong = "valetta" and right = "valletta" - or - wrong = "valuble" and right = "valuable" - or - wrong = "valueable" and right = "valuable" - or - wrong = "varations" and right = "variations" - or - wrong = "varient" and right = "variant" - or - wrong = "variey" and right = "variety" - or - wrong = "varing" and right = "varying" - or - wrong = "varities" and right = "varieties" - or - wrong = "varity" and right = "variety" - or - wrong = "vasall" and right = "vassal" - or - wrong = "vasalls" and right = "vassals" - or - wrong = "vaule" and right = "value" - or - wrong = "vegatarian" and right = "vegetarian" - or - wrong = "vegitable" and right = "vegetable" - or - wrong = "vegitables" and right = "vegetables" - or - wrong = "vegtable" and right = "vegetable" - or - wrong = "vehicule" and right = "vehicle" - or - wrong = "vell" and right = "well" - or - wrong = "venemous" and right = "venomous" - or - wrong = "vengance" and right = "vengeance" - or - wrong = "vengence" and right = "vengeance" - or - wrong = "verfication" and right = "verification" - or - wrong = "verison" and right = "version" - or - wrong = "verisons" and right = "versions" - or - wrong = "vermillion" and right = "vermilion" - or - wrong = "versitilaty" and right = "versatility" - or - wrong = "versitlity" and right = "versatility" - or - wrong = "vetween" and right = "between" - or - wrong = "veyr" and right = "very" - or - wrong = "vigeur" and right = "vigor" - or - wrong = "vigeur" and right = "vigour" - or - wrong = "vigeur" and right = "vigueur" - or - wrong = "vigilence" and right = "vigilance" - or - wrong = "vigourous" and right = "vigorous" - or - wrong = "villian" and right = "villain" - or - wrong = "villification" and right = "vilification" - or - wrong = "villify" and right = "vilify" - or - wrong = "villin" and right = "villain" - or - wrong = "villin" and right = "villein" - or - wrong = "villin" and right = "villi" - or - wrong = "vincinity" and right = "vicinity" - or - wrong = "violentce" and right = "violence" - or - wrong = "virtualy" and right = "virtually" - or - wrong = "virutal" and right = "virtual" - or - wrong = "virutally" and right = "virtually" - or - wrong = "visable" and right = "visible" - or - wrong = "visably" and right = "visibly" - or - wrong = "visting" and right = "visiting" - or - wrong = "vistors" and right = "visitors" - or - wrong = "vitories" and right = "victories" - or - wrong = "volcanoe" and right = "volcano" - or - wrong = "voleyball" and right = "volleyball" - or - wrong = "volontary" and right = "voluntary" - or - wrong = "volonteer" and right = "volunteer" - or - wrong = "volonteered" and right = "volunteered" - or - wrong = "volonteering" and right = "volunteering" - or - wrong = "volonteers" and right = "volunteers" - or - wrong = "volounteer" and right = "volunteer" - or - wrong = "volounteered" and right = "volunteered" - or - wrong = "volounteering" and right = "volunteering" - or - wrong = "volounteers" and right = "volunteers" - or - wrong = "volumne" and right = "volume" - or - wrong = "vreity" and right = "variety" - or - wrong = "vrey" and right = "very" - or - wrong = "vriety" and right = "variety" - or - wrong = "vulnerablility" and right = "vulnerability" - or - wrong = "vyer" and right = "very" - or - wrong = "vyre" and right = "very" - or - wrong = "waht" and right = "what" - or - wrong = "warantee" and right = "warranty" - or - wrong = "wardobe" and right = "wardrobe" - or - wrong = "warrent" and right = "warrant" - or - wrong = "warrriors" and right = "warriors" - or - wrong = "wass" and right = "was" - or - wrong = "watn" and right = "want" - or - wrong = "wayword" and right = "wayward" - or - wrong = "weaponary" and right = "weaponry" - or - wrong = "weas" and right = "was" - or - wrong = "wehn" and right = "when" - or - wrong = "weild" and right = "wield" - or - wrong = "weild" and right = "wild" - or - wrong = "weilded" and right = "wielded" - or - wrong = "wendsay" and right = "wednesday" - or - wrong = "wensday" and right = "wednesday" - or - wrong = "wereabouts" and right = "whereabouts" - or - wrong = "whant" and right = "want" - or - wrong = "whants" and right = "wants" - or - wrong = "whcih" and right = "which" - or - wrong = "wheras" and right = "whereas" - or - wrong = "wherease" and right = "whereas" - or - wrong = "whereever" and right = "wherever" - or - wrong = "whic" and right = "which" - or - wrong = "whihc" and right = "which" - or - wrong = "whith" and right = "with" - or - wrong = "whlch" and right = "which" - or - wrong = "whn" and right = "when" - or - wrong = "wholey" and right = "wholly" - or - wrong = "wholy" and right = "holy" - or - wrong = "wholy" and right = "wholly" - or - wrong = "whta" and right = "what" - or - wrong = "whther" and right = "whether" - or - wrong = "wich" and right = "which" - or - wrong = "wich" and right = "witch" - or - wrong = "widesread" and right = "widespread" - or - wrong = "wief" and right = "wife" - or - wrong = "wierd" and right = "weird" - or - wrong = "wiew" and right = "view" - or - wrong = "wih" and right = "with" - or - wrong = "wiht" and right = "with" - or - wrong = "wille" and right = "will" - or - wrong = "willingless" and right = "willingness" - or - wrong = "willk" and right = "will" - or - wrong = "wirting" and right = "writing" - or - wrong = "withdrawl" and right = "withdraw" - or - wrong = "withdrawl" and right = "withdrawal" - or - wrong = "witheld" and right = "withheld" - or - wrong = "withh" and right = "with" - or - wrong = "withing" and right = "within" - or - wrong = "withold" and right = "withhold" - or - wrong = "witht" and right = "with" - or - wrong = "witn" and right = "with" - or - wrong = "wiull" and right = "will" - or - wrong = "wnat" and right = "want" - or - wrong = "wnated" and right = "wanted" - or - wrong = "wnats" and right = "wants" - or - wrong = "wohle" and right = "whole" - or - wrong = "wokr" and right = "work" - or - wrong = "wokring" and right = "working" - or - wrong = "wonderfull" and right = "wonderful" - or - wrong = "wordlwide" and right = "worldwide" - or - wrong = "workststion" and right = "workstation" - or - wrong = "worls" and right = "world" - or - wrong = "worstened" and right = "worsened" - or - wrong = "woudl" and right = "would" - or - wrong = "wresters" and right = "wrestlers" - or - wrong = "wriet" and right = "write" - or - wrong = "writen" and right = "written" - or - wrong = "wroet" and right = "wrote" - or - wrong = "wrok" and right = "work" - or - wrong = "wroking" and right = "working" - or - wrong = "wtih" and right = "with" - or - wrong = "wupport" and right = "support" - or - wrong = "xenophoby" and right = "xenophobia" - or - wrong = "yaching" and right = "yachting" - or - wrong = "yaer" and right = "year" - or - wrong = "yaerly" and right = "yearly" - or - wrong = "yaers" and right = "years" - or - wrong = "yatch" and right = "yacht" - or - wrong = "yearm" and right = "year" - or - wrong = "yeasr" and right = "years" - or - wrong = "yeild" and right = "yield" - or - wrong = "yeilding" and right = "yielding" - or - wrong = "yementite" and right = "yemeni" - or - wrong = "yementite" and right = "yemenite" - or - wrong = "yera" and right = "year" - or - wrong = "yeras" and right = "years" - or - wrong = "yersa" and right = "years" - or - wrong = "yotube" and right = "youtube" - or - wrong = "youseff" and right = "yousef" - or - wrong = "youself" and right = "yourself" - or - wrong = "yrea" and right = "year" - or - wrong = "ytou" and right = "you" - or - wrong = "yuo" and right = "you" - or - wrong = "zeebra" and right = "zebra" -} +import codeql.typos.TypoDatabase as DB + +/** DEPRECATED: Use the `codeql/typos` pack instead. */ +deprecated predicate typos = DB::typos/2; diff --git a/ql/ql/src/qlpack.yml b/ql/ql/src/qlpack.yml index 9ae2cb13787..9ee790bdfe5 100644 --- a/ql/ql/src/qlpack.yml +++ b/ql/ql/src/qlpack.yml @@ -5,3 +5,5 @@ dbscheme: ql.dbscheme suites: codeql-suites defaultSuiteFile: codeql-suites/ql-code-scanning.qls extractor: ql +dependencies: + codeql/typos: "*" diff --git a/shared/typos/codeql/typos/TypoDatabase.qll b/shared/typos/codeql/typos/TypoDatabase.qll new file mode 100644 index 00000000000..a41f003a8c0 --- /dev/null +++ b/shared/typos/codeql/typos/TypoDatabase.qll @@ -0,0 +1,9035 @@ +/** + * Holds if `wrong` is a common misspelling of `right`. + * + * This predicate was automatically generated by + * python buildutils-internal/scripts/generate-typos.py + * which uses http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines (with custom additions) on 2018-01-19. + * + * This file is available under the Creative Commons Attribution-ShareAlike License + * (https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License). + */ +predicate typos(string wrong, string right) { + wrong = "abandonned" and right = "abandoned" + or + wrong = "abbout" and right = "about" + or + wrong = "aberation" and right = "aberration" + or + wrong = "abilityes" and right = "abilities" + or + wrong = "abilties" and right = "abilities" + or + wrong = "abilty" and right = "ability" + or + wrong = "abondon" and right = "abandon" + or + wrong = "abondoned" and right = "abandoned" + or + wrong = "abondoning" and right = "abandoning" + or + wrong = "abondons" and right = "abandons" + or + wrong = "aborigene" and right = "aborigine" + or + wrong = "abortificant" and right = "abortifacient" + or + wrong = "abotu" and right = "about" + or + wrong = "abreviate" and right = "abbreviate" + or + wrong = "abreviated" and right = "abbreviated" + or + wrong = "abreviation" and right = "abbreviation" + or + wrong = "abritrary" and right = "arbitrary" + or + wrong = "absail" and right = "abseil" + or + wrong = "absailing" and right = "abseiling" + or + wrong = "abscence" and right = "absence" + or + wrong = "absense" and right = "absence" + or + wrong = "absolutly" and right = "absolutely" + or + wrong = "absorbsion" and right = "absorption" + or + wrong = "absorbtion" and right = "absorption" + or + wrong = "abudance" and right = "abundance" + or + wrong = "abundacies" and right = "abundances" + or + wrong = "abundancies" and right = "abundances" + or + wrong = "abundunt" and right = "abundant" + or + wrong = "abutts" and right = "abuts" + or + wrong = "acadamy" and right = "academy" + or + wrong = "acadmic" and right = "academic" + or + wrong = "accademic" and right = "academic" + or + wrong = "accademy" and right = "academy" + or + wrong = "acccess" and right = "access" + or + wrong = "acccused" and right = "accused" + or + wrong = "accelleration" and right = "acceleration" + or + wrong = "accension" and right = "accession" + or + wrong = "accension" and right = "ascension" + or + wrong = "acceptence" and right = "acceptance" + or + wrong = "acceptible" and right = "acceptable" + or + wrong = "accesories" and right = "accessories" + or + wrong = "accessable" and right = "accessible" + or + wrong = "accidant" and right = "accident" + or + wrong = "accidentaly" and right = "accidentally" + or + wrong = "accidently" and right = "accidentally" + or + wrong = "acclimitization" and right = "acclimatization" + or + wrong = "accomadate" and right = "accommodate" + or + wrong = "accomadated" and right = "accommodated" + or + wrong = "accomadates" and right = "accommodates" + or + wrong = "accomadating" and right = "accommodating" + or + wrong = "accomadation" and right = "accommodation" + or + wrong = "accomadations" and right = "accommodations" + or + wrong = "accomdate" and right = "accommodate" + or + wrong = "accomodate" and right = "accommodate" + or + wrong = "accomodated" and right = "accommodated" + or + wrong = "accomodates" and right = "accommodates" + or + wrong = "accomodating" and right = "accommodating" + or + wrong = "accomodation" and right = "accommodation" + or + wrong = "accomodations" and right = "accommodations" + or + wrong = "accompanyed" and right = "accompanied" + or + wrong = "accordeon" and right = "accordion" + or + wrong = "accordian" and right = "accordion" + or + wrong = "accoring" and right = "according" + or + wrong = "accoustic" and right = "acoustic" + or + wrong = "accquainted" and right = "acquainted" + or + wrong = "accrediation" and right = "accreditation" + or + wrong = "accredidation" and right = "accreditation" + or + wrong = "accross" and right = "across" + or + wrong = "accussed" and right = "accused" + or + wrong = "acedemic" and right = "academic" + or + wrong = "acheive" and right = "achieve" + or + wrong = "acheived" and right = "achieved" + or + wrong = "acheivement" and right = "achievement" + or + wrong = "acheivements" and right = "achievements" + or + wrong = "acheives" and right = "achieves" + or + wrong = "acheiving" and right = "achieving" + or + wrong = "acheivment" and right = "achievement" + or + wrong = "acheivments" and right = "achievements" + or + wrong = "achievment" and right = "achievement" + or + wrong = "achievments" and right = "achievements" + or + wrong = "achive" and right = "achieve" + or + wrong = "achive" and right = "archive" + or + wrong = "achived" and right = "achieved" + or + wrong = "achived" and right = "archived" + or + wrong = "achivement" and right = "achievement" + or + wrong = "achivements" and right = "achievements" + or + wrong = "acident" and right = "accident" + or + wrong = "acknowldeged" and right = "acknowledged" + or + wrong = "acknowledgeing" and right = "acknowledging" + or + wrong = "ackward" and right = "awkward" + or + wrong = "ackward" and right = "backward" + or + wrong = "acommodate" and right = "accommodate" + or + wrong = "acomplish" and right = "accomplish" + or + wrong = "acomplished" and right = "accomplished" + or + wrong = "acomplishment" and right = "accomplishment" + or + wrong = "acomplishments" and right = "accomplishments" + or + wrong = "acording" and right = "according" + or + wrong = "acordingly" and right = "accordingly" + or + wrong = "acquaintence" and right = "acquaintance" + or + wrong = "acquaintences" and right = "acquaintances" + or + wrong = "acquiantence" and right = "acquaintance" + or + wrong = "acquiantences" and right = "acquaintances" + or + wrong = "acquited" and right = "acquitted" + or + wrong = "activites" and right = "activities" + or + wrong = "activly" and right = "actively" + or + wrong = "actualy" and right = "actually" + or + wrong = "acuracy" and right = "accuracy" + or + wrong = "acused" and right = "accused" + or + wrong = "acustom" and right = "accustom" + or + wrong = "acustommed" and right = "accustomed" + or + wrong = "adapater" and right = "adapter" + or + wrong = "adavanced" and right = "advanced" + or + wrong = "adbandon" and right = "abandon" + or + wrong = "addional" and right = "additional" + or + wrong = "addionally" and right = "additionally" + or + wrong = "additinally" and right = "additionally" + or + wrong = "additionaly" and right = "additionally" + or + wrong = "additonal" and right = "additional" + or + wrong = "additonally" and right = "additionally" + or + wrong = "addmission" and right = "admission" + or + wrong = "addopt" and right = "adopt" + or + wrong = "addopted" and right = "adopted" + or + wrong = "addoptive" and right = "adoptive" + or + wrong = "addres" and right = "adders" + or + wrong = "addres" and right = "address" + or + wrong = "addresable" and right = "addressable" + or + wrong = "addresed" and right = "addressed" + or + wrong = "addresing" and right = "addressing" + or + wrong = "addressess" and right = "addresses" + or + wrong = "addtion" and right = "addition" + or + wrong = "addtional" and right = "additional" + or + wrong = "adecuate" and right = "adequate" + or + wrong = "adequit" and right = "adequate" + or + wrong = "adhearing" and right = "adhering" + or + wrong = "adherance" and right = "adherence" + or + wrong = "admendment" and right = "amendment" + or + wrong = "admininistrative" and right = "administrative" + or + wrong = "adminstered" and right = "administered" + or + wrong = "adminstrate" and right = "administrate" + or + wrong = "adminstration" and right = "administration" + or + wrong = "adminstrative" and right = "administrative" + or + wrong = "adminstrator" and right = "administrator" + or + wrong = "admissability" and right = "admissibility" + or + wrong = "admissable" and right = "admissible" + or + wrong = "admited" and right = "admitted" + or + wrong = "admitedly" and right = "admittedly" + or + wrong = "adn" and right = "and" + or + wrong = "adolecent" and right = "adolescent" + or + wrong = "adquire" and right = "acquire" + or + wrong = "adquired" and right = "acquired" + or + wrong = "adquires" and right = "acquires" + or + wrong = "adquiring" and right = "acquiring" + or + wrong = "adres" and right = "address" + or + wrong = "adresable" and right = "addressable" + or + wrong = "adresing" and right = "addressing" + or + wrong = "adress" and right = "address" + or + wrong = "adressable" and right = "addressable" + or + wrong = "adressed" and right = "addressed" + or + wrong = "adressing" and right = "addressing" + or + wrong = "adressing" and right = "dressing" + or + wrong = "adventrous" and right = "adventurous" + or + wrong = "advertisment" and right = "advertisement" + or + wrong = "advertisments" and right = "advertisements" + or + wrong = "advesary" and right = "adversary" + or + wrong = "adviced" and right = "advised" + or + wrong = "aeriel" and right = "aerial" + or + wrong = "aeriels" and right = "aerials" + or + wrong = "afair" and right = "affair" + or + wrong = "afficianados" and right = "aficionados" + or + wrong = "afficionado" and right = "aficionado" + or + wrong = "afficionados" and right = "aficionados" + or + wrong = "affilate" and right = "affiliate" + or + wrong = "affilliate" and right = "affiliate" + or + wrong = "affort" and right = "afford" + or + wrong = "affort" and right = "effort" + or + wrong = "aforememtioned" and right = "aforementioned" + or + wrong = "againnst" and right = "against" + or + wrong = "agains" and right = "against" + or + wrong = "agaisnt" and right = "against" + or + wrong = "aganist" and right = "against" + or + wrong = "aggaravates" and right = "aggravates" + or + wrong = "aggreed" and right = "agreed" + or + wrong = "aggreement" and right = "agreement" + or + wrong = "aggregious" and right = "egregious" + or + wrong = "aggresive" and right = "aggressive" + or + wrong = "agian" and right = "again" + or + wrong = "agianst" and right = "against" + or + wrong = "agin" and right = "again" + or + wrong = "agina" and right = "again" + or + wrong = "agina" and right = "angina" + or + wrong = "aginst" and right = "against" + or + wrong = "agravate" and right = "aggravate" + or + wrong = "agre" and right = "agree" + or + wrong = "agred" and right = "agreed" + or + wrong = "agreeement" and right = "agreement" + or + wrong = "agreemnt" and right = "agreement" + or + wrong = "agregate" and right = "aggregate" + or + wrong = "agregates" and right = "aggregates" + or + wrong = "agreing" and right = "agreeing" + or + wrong = "agression" and right = "aggression" + or + wrong = "agressive" and right = "aggressive" + or + wrong = "agressively" and right = "aggressively" + or + wrong = "agressor" and right = "aggressor" + or + wrong = "agricultue" and right = "agriculture" + or + wrong = "agriculure" and right = "agriculture" + or + wrong = "agricuture" and right = "agriculture" + or + wrong = "agrieved" and right = "aggrieved" + or + wrong = "agrument" and right = "argument" + or + wrong = "agruments" and right = "arguments" + or + wrong = "ahev" and right = "have" + or + wrong = "ahppen" and right = "happen" + or + wrong = "ahve" and right = "have" + or + wrong = "aicraft" and right = "aircraft" + or + wrong = "aiport" and right = "airport" + or + wrong = "airbourne" and right = "airborne" + or + wrong = "aircaft" and right = "aircraft" + or + wrong = "aircrafts" and right = "aircraft" + or + wrong = "airporta" and right = "airports" + or + wrong = "airrcraft" and right = "aircraft" + or + wrong = "aisian" and right = "asian" + or + wrong = "albiet" and right = "albeit" + or + wrong = "alchohol" and right = "alcohol" + or + wrong = "alchoholic" and right = "alcoholic" + or + wrong = "alchol" and right = "alcohol" + or + wrong = "alcholic" and right = "alcoholic" + or + wrong = "alcohal" and right = "alcohol" + or + wrong = "alcoholical" and right = "alcoholic" + or + wrong = "aledge" and right = "allege" + or + wrong = "aledged" and right = "alleged" + or + wrong = "aledges" and right = "alleges" + or + wrong = "alege" and right = "allege" + or + wrong = "aleged" and right = "alleged" + or + wrong = "alegience" and right = "allegiance" + or + wrong = "algebraical" and right = "algebraic" + or + wrong = "algorhitms" and right = "algorithms" + or + wrong = "algoritm" and right = "algorithm" + or + wrong = "algoritms" and right = "algorithms" + or + wrong = "alientating" and right = "alienating" + or + wrong = "alledge" and right = "allege" + or + wrong = "alledged" and right = "alleged" + or + wrong = "alledgedly" and right = "allegedly" + or + wrong = "alledges" and right = "alleges" + or + wrong = "allegedely" and right = "allegedly" + or + wrong = "allegedy" and right = "allegedly" + or + wrong = "allegely" and right = "allegedly" + or + wrong = "allegence" and right = "allegiance" + or + wrong = "allegience" and right = "allegiance" + or + wrong = "allign" and right = "align" + or + wrong = "alligned" and right = "aligned" + or + wrong = "alliviate" and right = "alleviate" + or + wrong = "allopone" and right = "allophone" + or + wrong = "allopones" and right = "allophones" + or + wrong = "allready" and right = "already" + or + wrong = "allthough" and right = "although" + or + wrong = "alltogether" and right = "altogether" + or + wrong = "almsot" and right = "almost" + or + wrong = "alochol" and right = "alcohol" + or + wrong = "alomst" and right = "almost" + or + wrong = "alot" and right = "allot" + or + wrong = "alotted" and right = "allotted" + or + wrong = "alowed" and right = "allowed" + or + wrong = "alowing" and right = "allowing" + or + wrong = "alreayd" and right = "already" + or + wrong = "alse" and right = "else" + or + wrong = "alsot" and right = "also" + or + wrong = "alternitives" and right = "alternatives" + or + wrong = "altho" and right = "although" + or + wrong = "althought" and right = "although" + or + wrong = "altough" and right = "although" + or + wrong = "alusion" and right = "allusion" + or + wrong = "alusion" and right = "illusion" + or + wrong = "alwasy" and right = "always" + or + wrong = "alwyas" and right = "always" + or + wrong = "amalgomated" and right = "amalgamated" + or + wrong = "amatuer" and right = "amateur" + or + wrong = "amature" and right = "amateur" + or + wrong = "amature" and right = "armature" + or + wrong = "amendmant" and right = "amendment" + or + wrong = "amercia" and right = "america" + or + wrong = "amerliorate" and right = "ameliorate" + or + wrong = "amke" and right = "make" + or + wrong = "amking" and right = "making" + or + wrong = "ammend" and right = "amend" + or + wrong = "ammended" and right = "amended" + or + wrong = "ammendment" and right = "amendment" + or + wrong = "ammendments" and right = "amendments" + or + wrong = "ammount" and right = "amount" + or + wrong = "ammused" and right = "amused" + or + wrong = "amoung" and right = "among" + or + wrong = "amoungst" and right = "amongst" + or + wrong = "amung" and right = "among" + or + wrong = "amunition" and right = "ammunition" + or + wrong = "analagous" and right = "analogous" + or + wrong = "analitic" and right = "analytic" + or + wrong = "analogeous" and right = "analogous" + or + wrong = "anarchim" and right = "anarchism" + or + wrong = "anarchistm" and right = "anarchism" + or + wrong = "anbd" and right = "and" + or + wrong = "ancestory" and right = "ancestry" + or + wrong = "ancilliary" and right = "ancillary" + or + wrong = "andd" and right = "and" + or + wrong = "androgenous" and right = "androgynous" + or + wrong = "androgeny" and right = "androgyny" + or + wrong = "anihilation" and right = "annihilation" + or + wrong = "aniversary" and right = "anniversary" + or + wrong = "annoint" and right = "anoint" + or + wrong = "annointed" and right = "anointed" + or + wrong = "annointing" and right = "anointing" + or + wrong = "annoints" and right = "anoints" + or + wrong = "annouced" and right = "announced" + or + wrong = "annualy" and right = "annually" + or + wrong = "annuled" and right = "annulled" + or + wrong = "anohter" and right = "another" + or + wrong = "anomolies" and right = "anomalies" + or + wrong = "anomolous" and right = "anomalous" + or + wrong = "anomoly" and right = "anomaly" + or + wrong = "anonimity" and right = "anonymity" + or + wrong = "anounced" and right = "announced" + or + wrong = "anouncement" and right = "announcement" + or + wrong = "ansalisation" and right = "nasalisation" + or + wrong = "ansalization" and right = "nasalization" + or + wrong = "ansestors" and right = "ancestors" + or + wrong = "antartic" and right = "antarctic" + or + wrong = "anthromorphization" and right = "anthropomorphization" + or + wrong = "anthropolgist" and right = "anthropologist" + or + wrong = "anthropolgy" and right = "anthropology" + or + wrong = "anual" and right = "annual" + or + wrong = "anulled" and right = "annulled" + or + wrong = "anwsered" and right = "answered" + or + wrong = "anyhwere" and right = "anywhere" + or + wrong = "anytying" and right = "anything" + or + wrong = "aparent" and right = "apparent" + or + wrong = "aparment" and right = "apartment" + or + wrong = "apenines" and right = "apennines" + or + wrong = "aplication" and right = "application" + or + wrong = "aplied" and right = "applied" + or + wrong = "apolegetics" and right = "apologetics" + or + wrong = "apon" and right = "apron" + or + wrong = "apon" and right = "upon" + or + wrong = "apparant" and right = "apparent" + or + wrong = "apparantly" and right = "apparently" + or + wrong = "appart" and right = "apart" + or + wrong = "appartment" and right = "apartment" + or + wrong = "appartments" and right = "apartments" + or + wrong = "appealling" and right = "appalling" + or + wrong = "appealling" and right = "appealing" + or + wrong = "appeareance" and right = "appearance" + or + wrong = "appearence" and right = "appearance" + or + wrong = "appearences" and right = "appearances" + or + wrong = "appenines" and right = "apennines" + or + wrong = "apperance" and right = "appearance" + or + wrong = "apperances" and right = "appearances" + or + wrong = "appereance" and right = "appearance" + or + wrong = "appereances" and right = "appearances" + or + wrong = "applicaiton" and right = "application" + or + wrong = "applicaitons" and right = "applications" + or + wrong = "appologies" and right = "apologies" + or + wrong = "appology" and right = "apology" + or + wrong = "apprearance" and right = "appearance" + or + wrong = "apprieciate" and right = "appreciate" + or + wrong = "approachs" and right = "approaches" + or + wrong = "appropiate" and right = "appropriate" + or + wrong = "appropraite" and right = "appropriate" + or + wrong = "appropropiate" and right = "appropriate" + or + wrong = "approproximate" and right = "approximate" + or + wrong = "approxamately" and right = "approximately" + or + wrong = "approxiately" and right = "approximately" + or + wrong = "approximitely" and right = "approximately" + or + wrong = "aprehensive" and right = "apprehensive" + or + wrong = "apropriate" and right = "appropriate" + or + wrong = "aproval" and right = "approval" + or + wrong = "aproximate" and right = "approximate" + or + wrong = "aproximately" and right = "approximately" + or + wrong = "aquaduct" and right = "aqueduct" + or + wrong = "aquaintance" and right = "acquaintance" + or + wrong = "aquainted" and right = "acquainted" + or + wrong = "aquiantance" and right = "acquaintance" + or + wrong = "aquire" and right = "acquire" + or + wrong = "aquired" and right = "acquired" + or + wrong = "aquiring" and right = "acquiring" + or + wrong = "aquisition" and right = "acquisition" + or + wrong = "aquitted" and right = "acquitted" + or + wrong = "aranged" and right = "arranged" + or + wrong = "arangement" and right = "arrangement" + or + wrong = "arbitarily" and right = "arbitrarily" + or + wrong = "arbitary" and right = "arbitrary" + or + wrong = "archaelogical" and right = "archaeological" + or + wrong = "archaelogists" and right = "archaeologists" + or + wrong = "archaelogy" and right = "archaeology" + or + wrong = "archaoelogy" and right = "archaeology" + or + wrong = "archaoelogy" and right = "archeology" + or + wrong = "archaology" and right = "archaeology" + or + wrong = "archaology" and right = "archeology" + or + wrong = "archeaologist" and right = "archaeologist" + or + wrong = "archeaologist" and right = "archeologist" + or + wrong = "archeaologists" and right = "archaeologists" + or + wrong = "archeaologists" and right = "archeologists" + or + wrong = "archetect" and right = "architect" + or + wrong = "archetects" and right = "architects" + or + wrong = "archetectural" and right = "architectural" + or + wrong = "archetecturally" and right = "architecturally" + or + wrong = "archetecture" and right = "architecture" + or + wrong = "archiac" and right = "archaic" + or + wrong = "archictect" and right = "architect" + or + wrong = "archimedian" and right = "archimedean" + or + wrong = "architecht" and right = "architect" + or + wrong = "architechturally" and right = "architecturally" + or + wrong = "architechture" and right = "architecture" + or + wrong = "architechtures" and right = "architectures" + or + wrong = "architectual" and right = "architectural" + or + wrong = "archtype" and right = "archetype" + or + wrong = "archtypes" and right = "archetypes" + or + wrong = "aready" and right = "already" + or + wrong = "areodynamics" and right = "aerodynamics" + or + wrong = "argubly" and right = "arguably" + or + wrong = "arguement" and right = "argument" + or + wrong = "arguements" and right = "arguments" + or + wrong = "arised" and right = "arose" + or + wrong = "arival" and right = "arrival" + or + wrong = "armamant" and right = "armament" + or + wrong = "armistace" and right = "armistice" + or + wrong = "arogant" and right = "arrogant" + or + wrong = "arogent" and right = "arrogant" + or + wrong = "aroud" and right = "around" + or + wrong = "arrangment" and right = "arrangement" + or + wrong = "arrangments" and right = "arrangements" + or + wrong = "arrengement" and right = "arrangement" + or + wrong = "arrengements" and right = "arrangements" + or + wrong = "arround" and right = "around" + or + wrong = "artcile" and right = "article" + or + wrong = "artical" and right = "article" + or + wrong = "artice" and right = "article" + or + wrong = "articel" and right = "article" + or + wrong = "artifical" and right = "artificial" + or + wrong = "artifically" and right = "artificially" + or + wrong = "artillary" and right = "artillery" + or + wrong = "arund" and right = "around" + or + wrong = "asetic" and right = "ascetic" + or + wrong = "asign" and right = "assign" + or + wrong = "aslo" and right = "also" + or + wrong = "asnyc" and right = "async" + or + wrong = "asociated" and right = "associated" + or + wrong = "asorbed" and right = "absorbed" + or + wrong = "asphyxation" and right = "asphyxiation" + or + wrong = "assasin" and right = "assassin" + or + wrong = "assasinate" and right = "assassinate" + or + wrong = "assasinated" and right = "assassinated" + or + wrong = "assasinates" and right = "assassinates" + or + wrong = "assasination" and right = "assassination" + or + wrong = "assasinations" and right = "assassinations" + or + wrong = "assasined" and right = "assassinated" + or + wrong = "assasins" and right = "assassins" + or + wrong = "assassintation" and right = "assassination" + or + wrong = "assemple" and right = "assemble" + or + wrong = "assertation" and right = "assertion" + or + wrong = "asside" and right = "aside" + or + wrong = "assisnate" and right = "assassinate" + or + wrong = "assit" and right = "assist" + or + wrong = "assitant" and right = "assistant" + or + wrong = "assocation" and right = "association" + or + wrong = "assoicate" and right = "associate" + or + wrong = "assoicated" and right = "associated" + or + wrong = "assoicates" and right = "associates" + or + wrong = "assosication" and right = "assassination" + or + wrong = "asssassans" and right = "assassins" + or + wrong = "assualt" and right = "assault" + or + wrong = "assualted" and right = "assaulted" + or + wrong = "assymetric" and right = "asymmetric" + or + wrong = "assymetrical" and right = "asymmetrical" + or + wrong = "asteriod" and right = "asteroid" + or + wrong = "asthetic" and right = "aesthetic" + or + wrong = "asthetical" and right = "aesthetical" + or + wrong = "asthetically" and right = "aesthetically" + or + wrong = "asume" and right = "assume" + or + wrong = "atain" and right = "attain" + or + wrong = "atempting" and right = "attempting" + or + wrong = "atheistical" and right = "atheistic" + or + wrong = "athenean" and right = "athenian" + or + wrong = "atheneans" and right = "athenians" + or + wrong = "athiesm" and right = "atheism" + or + wrong = "athiest" and right = "atheist" + or + wrong = "atorney" and right = "attorney" + or + wrong = "atribute" and right = "attribute" + or + wrong = "atributed" and right = "attributed" + or + wrong = "atributes" and right = "attributes" + or + wrong = "attaindre" and right = "attainder" + or + wrong = "attaindre" and right = "attained" + or + wrong = "attemp" and right = "attempt" + or + wrong = "attemped" and right = "attempted" + or + wrong = "attemt" and right = "attempt" + or + wrong = "attemted" and right = "attempted" + or + wrong = "attemting" and right = "attempting" + or + wrong = "attemts" and right = "attempts" + or + wrong = "attendence" and right = "attendance" + or + wrong = "attendent" and right = "attendant" + or + wrong = "attendents" and right = "attendants" + or + wrong = "attened" and right = "attended" + or + wrong = "attension" and right = "attention" + or + wrong = "attitide" and right = "attitude" + or + wrong = "attributred" and right = "attributed" + or + wrong = "attrocities" and right = "atrocities" + or + wrong = "audeince" and right = "audience" + or + wrong = "auromated" and right = "automated" + or + wrong = "austrailia" and right = "australia" + or + wrong = "austrailian" and right = "australian" + or + wrong = "auther" and right = "author" + or + wrong = "authobiographic" and right = "autobiographic" + or + wrong = "authobiography" and right = "autobiography" + or + wrong = "authorative" and right = "authoritative" + or + wrong = "authorites" and right = "authorities" + or + wrong = "authorithy" and right = "authority" + or + wrong = "authoritiers" and right = "authorities" + or + wrong = "authoritive" and right = "authoritative" + or + wrong = "authrorities" and right = "authorities" + or + wrong = "autochtonous" and right = "autochthonous" + or + wrong = "autoctonous" and right = "autochthonous" + or + wrong = "automaticly" and right = "automatically" + or + wrong = "automibile" and right = "automobile" + or + wrong = "automonomous" and right = "autonomous" + or + wrong = "autor" and right = "author" + or + wrong = "autority" and right = "authority" + or + wrong = "auxilary" and right = "auxiliary" + or + wrong = "auxillaries" and right = "auxiliaries" + or + wrong = "auxillary" and right = "auxiliary" + or + wrong = "auxilliaries" and right = "auxiliaries" + or + wrong = "auxilliary" and right = "auxiliary" + or + wrong = "availabe" and right = "available" + or + wrong = "availablity" and right = "availability" + or + wrong = "availaible" and right = "available" + or + wrong = "availble" and right = "available" + or + wrong = "availiable" and right = "available" + or + wrong = "availible" and right = "available" + or + wrong = "avalable" and right = "available" + or + wrong = "avalance" and right = "avalanche" + or + wrong = "avaliable" and right = "available" + or + wrong = "avation" and right = "aviation" + or + wrong = "averageed" and right = "averaged" + or + wrong = "avilable" and right = "available" + or + wrong = "awared" and right = "awarded" + or + wrong = "awya" and right = "away" + or + wrong = "baceause" and right = "because" + or + wrong = "backgorund" and right = "background" + or + wrong = "backrounds" and right = "backgrounds" + or + wrong = "bakc" and right = "back" + or + wrong = "banannas" and right = "bananas" + or + wrong = "bandwith" and right = "bandwidth" + or + wrong = "bankrupcy" and right = "bankruptcy" + or + wrong = "banruptcy" and right = "bankruptcy" + or + wrong = "baout" and right = "about" + or + wrong = "baout" and right = "bout" + or + wrong = "basicaly" and right = "basically" + or + wrong = "basicly" and right = "basically" + or + wrong = "bcak" and right = "back" + or + wrong = "beachead" and right = "beachhead" + or + wrong = "beacuse" and right = "because" + or + wrong = "beastiality" and right = "bestiality" + or + wrong = "beatiful" and right = "beautiful" + or + wrong = "beaurocracy" and right = "bureaucracy" + or + wrong = "beaurocratic" and right = "bureaucratic" + or + wrong = "beautyfull" and right = "beautiful" + or + wrong = "becamae" and right = "became" + or + wrong = "becames" and right = "became" + or + wrong = "becames" and right = "becomes" + or + wrong = "becasue" and right = "because" + or + wrong = "beccause" and right = "because" + or + wrong = "becomeing" and right = "becoming" + or + wrong = "becomming" and right = "becoming" + or + wrong = "becouse" and right = "because" + or + wrong = "becuase" and right = "because" + or + wrong = "bedore" and right = "before" + or + wrong = "beeing" and right = "being" + or + wrong = "befoer" and right = "before" + or + wrong = "beggin" and right = "begging" + or + wrong = "beggin" and right = "begin" + or + wrong = "begginer" and right = "beginner" + or + wrong = "begginers" and right = "beginners" + or + wrong = "beggining" and right = "beginning" + or + wrong = "begginings" and right = "beginnings" + or + wrong = "beggins" and right = "begins" + or + wrong = "begining" and right = "beginning" + or + wrong = "beginnig" and right = "beginning" + or + wrong = "behavour" and right = "behavior" + or + wrong = "behavour" and right = "behaviour" + or + wrong = "beleagured" and right = "beleaguered" + or + wrong = "beleif" and right = "belief" + or + wrong = "beleive" and right = "believe" + or + wrong = "beleived" and right = "believed" + or + wrong = "beleives" and right = "believes" + or + wrong = "beleiving" and right = "believing" + or + wrong = "beligum" and right = "belgium" + or + wrong = "belive" and right = "believe" + or + wrong = "belived" and right = "believed" + or + wrong = "belived" and right = "beloved" + or + wrong = "belives" and right = "beliefs" + or + wrong = "belives" and right = "believes" + or + wrong = "belligerant" and right = "belligerent" + or + wrong = "bellweather" and right = "bellwether" + or + wrong = "bemusemnt" and right = "bemusement" + or + wrong = "beneficary" and right = "beneficiary" + or + wrong = "beng" and right = "being" + or + wrong = "benificial" and right = "beneficial" + or + wrong = "benifit" and right = "benefit" + or + wrong = "benifits" and right = "benefits" + or + wrong = "bergamont" and right = "bergamot" + or + wrong = "bernouilli" and right = "bernoulli" + or + wrong = "beseige" and right = "besiege" + or + wrong = "beseiged" and right = "besieged" + or + wrong = "beseiging" and right = "besieging" + or + wrong = "beteen" and right = "between" + or + wrong = "betwen" and right = "between" + or + wrong = "beween" and right = "between" + or + wrong = "bewteen" and right = "between" + or + wrong = "bigining" and right = "beginning" + or + wrong = "biginning" and right = "beginning" + or + wrong = "bilateraly" and right = "bilaterally" + or + wrong = "billingualism" and right = "bilingualism" + or + wrong = "binominal" and right = "binomial" + or + wrong = "bizzare" and right = "bizarre" + or + wrong = "blaim" and right = "blame" + or + wrong = "blaimed" and right = "blamed" + or + wrong = "blessure" and right = "blessing" + or + wrong = "blitzkreig" and right = "blitzkrieg" + or + wrong = "boaut" and right = "about" + or + wrong = "boaut" and right = "boat" + or + wrong = "boaut" and right = "bout" + or + wrong = "bodydbuilder" and right = "bodybuilder" + or + wrong = "bolean" and right = "boolean" + or + wrong = "bombardement" and right = "bombardment" + or + wrong = "bombarment" and right = "bombardment" + or + wrong = "bondary" and right = "boundary" + or + wrong = "bonnano" and right = "bonanno" + or + wrong = "boook" and right = "book" + or + wrong = "borke" and right = "broke" + or + wrong = "boundry" and right = "boundary" + or + wrong = "bouyancy" and right = "buoyancy" + or + wrong = "bouyant" and right = "buoyant" + or + wrong = "boyant" and right = "buoyant" + or + wrong = "bradcast" and right = "broadcast" + or + wrong = "brasillian" and right = "brazilian" + or + wrong = "breakthough" and right = "breakthrough" + or + wrong = "breakthroughts" and right = "breakthroughs" + or + wrong = "breif" and right = "brief" + or + wrong = "breifly" and right = "briefly" + or + wrong = "brethen" and right = "brethren" + or + wrong = "bretheren" and right = "brethren" + or + wrong = "briliant" and right = "brilliant" + or + wrong = "brillant" and right = "brilliant" + or + wrong = "brimestone" and right = "brimstone" + or + wrong = "britian" and right = "britain" + or + wrong = "brittish" and right = "british" + or + wrong = "broacasted" and right = "broadcast" + or + wrong = "broadacasting" and right = "broadcasting" + or + wrong = "broady" and right = "broadly" + or + wrong = "buddah" and right = "buddha" + or + wrong = "buddist" and right = "buddhist" + or + wrong = "buisness" and right = "business" + or + wrong = "buisnessman" and right = "businessman" + or + wrong = "buoancy" and right = "buoyancy" + or + wrong = "buring" and right = "burin" + or + wrong = "buring" and right = "burning" + or + wrong = "buring" and right = "burying" + or + wrong = "buring" and right = "during" + or + wrong = "burried" and right = "buried" + or + wrong = "busines" and right = "business" + or + wrong = "busineses" and right = "business" + or + wrong = "busineses" and right = "businesses" + or + wrong = "busness" and right = "business" + or + wrong = "bussiness" and right = "business" + or + wrong = "caculater" and right = "calculator" + or + wrong = "cacuses" and right = "caucuses" + or + wrong = "cahracters" and right = "characters" + or + wrong = "calaber" and right = "caliber" + or + wrong = "calander" and right = "calendar" + or + wrong = "calander" and right = "calender" + or + wrong = "calander" and right = "colander" + or + wrong = "calculater" and right = "calculator" + or + wrong = "calculs" and right = "calculus" + or + wrong = "calender" and right = "calendar" + or + wrong = "calenders" and right = "calendars" + or + wrong = "caligraphy" and right = "calligraphy" + or + wrong = "caluclate" and right = "calculate" + or + wrong = "caluclated" and right = "calculated" + or + wrong = "caluculate" and right = "calculate" + or + wrong = "caluculated" and right = "calculated" + or + wrong = "calulate" and right = "calculate" + or + wrong = "calulated" and right = "calculated" + or + wrong = "calulater" and right = "calculator" + or + wrong = "cambrige" and right = "cambridge" + or + wrong = "camoflage" and right = "camouflage" + or + wrong = "campagin" and right = "campaign" + or + wrong = "campain" and right = "campaign" + or + wrong = "campains" and right = "campaigns" + or + wrong = "candadate" and right = "candidate" + or + wrong = "candiate" and right = "candidate" + or + wrong = "candidiate" and right = "candidate" + or + wrong = "cannister" and right = "canister" + or + wrong = "cannisters" and right = "canisters" + or + wrong = "cannnot" and right = "cannot" + or + wrong = "cannonical" and right = "canonical" + or + wrong = "cannotation" and right = "connotation" + or + wrong = "cannotations" and right = "connotations" + or + wrong = "caost" and right = "coast" + or + wrong = "caperbility" and right = "capability" + or + wrong = "capible" and right = "capable" + or + wrong = "captial" and right = "capital" + or + wrong = "captued" and right = "captured" + or + wrong = "capturd" and right = "captured" + or + wrong = "carachter" and right = "character" + or + wrong = "caracterized" and right = "characterized" + or + wrong = "carcas" and right = "caracas" + or + wrong = "carcas" and right = "carcass" + or + wrong = "carefull" and right = "careful" + or + wrong = "careing" and right = "caring" + or + wrong = "carismatic" and right = "charismatic" + or + wrong = "carmalite" and right = "carmelite" + or + wrong = "carnagie" and right = "carnegie" + or + wrong = "carnege" and right = "carnage" + or + wrong = "carnege" and right = "carnegie" + or + wrong = "carnige" and right = "carnage" + or + wrong = "carnige" and right = "carnegie" + or + wrong = "carnigie" and right = "carnegie" + or + wrong = "carreer" and right = "career" + or + wrong = "carrers" and right = "careers" + or + wrong = "carribbean" and right = "caribbean" + or + wrong = "carribean" and right = "caribbean" + or + wrong = "carryng" and right = "carrying" + or + wrong = "cartdridge" and right = "cartridge" + or + wrong = "carthagian" and right = "carthaginian" + or + wrong = "carthographer" and right = "cartographer" + or + wrong = "cartilege" and right = "cartilage" + or + wrong = "cartilidge" and right = "cartilage" + or + wrong = "cartrige" and right = "cartridge" + or + wrong = "casette" and right = "cassette" + or + wrong = "casion" and right = "caisson" + or + wrong = "cassawory" and right = "cassowary" + or + wrong = "cassowarry" and right = "cassowary" + or + wrong = "casue" and right = "cause" + or + wrong = "casued" and right = "caused" + or + wrong = "casues" and right = "causes" + or + wrong = "casuing" and right = "causing" + or + wrong = "casulaties" and right = "casualties" + or + wrong = "casulaty" and right = "casualty" + or + wrong = "catagories" and right = "categories" + or + wrong = "catagorized" and right = "categorized" + or + wrong = "catagory" and right = "category" + or + wrong = "cataline" and right = "catalina" + or + wrong = "cataline" and right = "catiline" + or + wrong = "catapillar" and right = "caterpillar" + or + wrong = "catapillars" and right = "caterpillars" + or + wrong = "catapiller" and right = "caterpillar" + or + wrong = "catapillers" and right = "caterpillars" + or + wrong = "catepillar" and right = "caterpillar" + or + wrong = "catepillars" and right = "caterpillars" + or + wrong = "catergorize" and right = "categorize" + or + wrong = "catergorized" and right = "categorized" + or + wrong = "caterpilar" and right = "caterpillar" + or + wrong = "caterpilars" and right = "caterpillars" + or + wrong = "caterpiller" and right = "caterpillar" + or + wrong = "caterpillers" and right = "caterpillars" + or + wrong = "cathlic" and right = "catholic" + or + wrong = "catholocism" and right = "catholicism" + or + wrong = "catterpilar" and right = "caterpillar" + or + wrong = "catterpilars" and right = "caterpillars" + or + wrong = "catterpillar" and right = "caterpillar" + or + wrong = "catterpillars" and right = "caterpillars" + or + wrong = "cattleship" and right = "battleship" + or + wrong = "causalities" and right = "casualties" + or + wrong = "ceasar" and right = "caesar" + or + wrong = "celcius" and right = "celsius" + or + wrong = "cellpading" and right = "cellpadding" + or + wrong = "cementary" and right = "cemetery" + or + wrong = "cemetarey" and right = "cemetery" + or + wrong = "cemetaries" and right = "cemeteries" + or + wrong = "cemetary" and right = "cemetery" + or + wrong = "cencus" and right = "census" + or + wrong = "censur" and right = "censor" + or + wrong = "censur" and right = "censure" + or + wrong = "cententenial" and right = "centennial" + or + wrong = "centruies" and right = "centuries" + or + wrong = "centruy" and right = "century" + or + wrong = "centuties" and right = "centuries" + or + wrong = "centuty" and right = "century" + or + wrong = "ceratin" and right = "certain" + or + wrong = "ceratin" and right = "keratin" + or + wrong = "cerimonial" and right = "ceremonial" + or + wrong = "cerimonies" and right = "ceremonies" + or + wrong = "cerimonious" and right = "ceremonious" + or + wrong = "cerimony" and right = "ceremony" + or + wrong = "ceromony" and right = "ceremony" + or + wrong = "certainity" and right = "certainty" + or + wrong = "certian" and right = "certain" + or + wrong = "cervial" and right = "cervical" + or + wrong = "cervial" and right = "serval" + or + wrong = "cervial" and right = "servile" + or + wrong = "chalenging" and right = "challenging" + or + wrong = "challange" and right = "challenge" + or + wrong = "challanged" and right = "challenged" + or + wrong = "challege" and right = "challenge" + or + wrong = "champange" and right = "champagne" + or + wrong = "changable" and right = "changeable" + or + wrong = "charachter" and right = "character" + or + wrong = "charachters" and right = "characters" + or + wrong = "charactersistic" and right = "characteristic" + or + wrong = "charactor" and right = "character" + or + wrong = "charactors" and right = "characters" + or + wrong = "charasmatic" and right = "charismatic" + or + wrong = "charaterized" and right = "characterized" + or + wrong = "chariman" and right = "chairman" + or + wrong = "charistics" and right = "characteristics" + or + wrong = "chasr" and right = "chase" + or + wrong = "chasr" and right = "chaser" + or + wrong = "cheif" and right = "chief" + or + wrong = "cheifs" and right = "chiefs" + or + wrong = "chemcial" and right = "chemical" + or + wrong = "chemcially" and right = "chemically" + or + wrong = "chemestry" and right = "chemistry" + or + wrong = "chemicaly" and right = "chemically" + or + wrong = "childbird" and right = "childbirth" + or + wrong = "childen" and right = "children" + or + wrong = "choclate" and right = "chocolate" + or + wrong = "choosen" and right = "chosen" + or + wrong = "chracter" and right = "character" + or + wrong = "chuch" and right = "church" + or + wrong = "churchs" and right = "churches" + or + wrong = "cincinatti" and right = "cincinnati" + or + wrong = "cincinnatti" and right = "cincinnati" + or + wrong = "circulaton" and right = "circulation" + or + wrong = "circumsicion" and right = "circumcision" + or + wrong = "circut" and right = "circuit" + or + wrong = "ciricuit" and right = "circuit" + or + wrong = "ciriculum" and right = "curriculum" + or + wrong = "civillian" and right = "civilian" + or + wrong = "claer" and right = "clear" + or + wrong = "claerer" and right = "clearer" + or + wrong = "claerly" and right = "clearly" + or + wrong = "claimes" and right = "claims" + or + wrong = "clas" and right = "class" + or + wrong = "clasic" and right = "classic" + or + wrong = "clasical" and right = "classical" + or + wrong = "clasically" and right = "classically" + or + wrong = "cleareance" and right = "clearance" + or + wrong = "clera" and right = "clear" + or + wrong = "clera" and right = "sclera" + or + wrong = "clincial" and right = "clinical" + or + wrong = "clinicaly" and right = "clinically" + or + wrong = "cmo" and right = "com" + or + wrong = "cmoputer" and right = "computer" + or + wrong = "coctail" and right = "cocktail" + or + wrong = "coform" and right = "conform" + or + wrong = "cognizent" and right = "cognizant" + or + wrong = "coincedentally" and right = "coincidentally" + or + wrong = "colaborations" and right = "collaborations" + or + wrong = "colateral" and right = "collateral" + or + wrong = "colelctive" and right = "collective" + or + wrong = "collaberative" and right = "collaborative" + or + wrong = "collecton" and right = "collection" + or + wrong = "collegue" and right = "colleague" + or + wrong = "collegues" and right = "colleagues" + or + wrong = "collonade" and right = "colonnade" + or + wrong = "collonies" and right = "colonies" + or + wrong = "collony" and right = "colony" + or + wrong = "collosal" and right = "colossal" + or + wrong = "colonizators" and right = "colonizers" + or + wrong = "comander" and right = "commandeer" + or + wrong = "comander" and right = "commander" + or + wrong = "comando" and right = "commando" + or + wrong = "comandos" and right = "commandos" + or + wrong = "comany" and right = "company" + or + wrong = "comapany" and right = "company" + or + wrong = "comback" and right = "comeback" + or + wrong = "combanations" and right = "combinations" + or + wrong = "combinatins" and right = "combinations" + or + wrong = "combusion" and right = "combustion" + or + wrong = "comdemnation" and right = "condemnation" + or + wrong = "comemmorates" and right = "commemorates" + or + wrong = "comemoretion" and right = "commemoration" + or + wrong = "comision" and right = "commission" + or + wrong = "comisioned" and right = "commissioned" + or + wrong = "comisioner" and right = "commissioner" + or + wrong = "comisioning" and right = "commissioning" + or + wrong = "comisions" and right = "commissions" + or + wrong = "comission" and right = "commission" + or + wrong = "comissioned" and right = "commissioned" + or + wrong = "comissioner" and right = "commissioner" + or + wrong = "comissioning" and right = "commissioning" + or + wrong = "comissions" and right = "commissions" + or + wrong = "comited" and right = "committed" + or + wrong = "comiting" and right = "committing" + or + wrong = "comitted" and right = "committed" + or + wrong = "comittee" and right = "committee" + or + wrong = "comitting" and right = "committing" + or + wrong = "commandoes" and right = "commandos" + or + wrong = "commedic" and right = "comedic" + or + wrong = "commemerative" and right = "commemorative" + or + wrong = "commemmorate" and right = "commemorate" + or + wrong = "commemmorating" and right = "commemorating" + or + wrong = "commerical" and right = "commercial" + or + wrong = "commerically" and right = "commercially" + or + wrong = "commericial" and right = "commercial" + or + wrong = "commericially" and right = "commercially" + or + wrong = "commerorative" and right = "commemorative" + or + wrong = "comming" and right = "coming" + or + wrong = "comminication" and right = "communication" + or + wrong = "commision" and right = "commission" + or + wrong = "commisioned" and right = "commissioned" + or + wrong = "commisioner" and right = "commissioner" + or + wrong = "commisioning" and right = "commissioning" + or + wrong = "commisions" and right = "commissions" + or + wrong = "commited" and right = "committed" + or + wrong = "commitee" and right = "committee" + or + wrong = "commiting" and right = "committing" + or + wrong = "committe" and right = "committee" + or + wrong = "committment" and right = "commitment" + or + wrong = "committments" and right = "commitments" + or + wrong = "commmemorated" and right = "commemorated" + or + wrong = "commongly" and right = "commonly" + or + wrong = "commonweath" and right = "commonwealth" + or + wrong = "commuications" and right = "communications" + or + wrong = "commuinications" and right = "communications" + or + wrong = "communciation" and right = "communication" + or + wrong = "communiation" and right = "communication" + or + wrong = "communites" and right = "communities" + or + wrong = "compability" and right = "compatibility" + or + wrong = "comparision" and right = "comparison" + or + wrong = "comparisions" and right = "comparisons" + or + wrong = "comparitive" and right = "comparative" + or + wrong = "comparitively" and right = "comparatively" + or + wrong = "compatabilities" and right = "compatibilities" + or + wrong = "compatability" and right = "compatibility" + or + wrong = "compatable" and right = "compatible" + or + wrong = "compatablities" and right = "compatibilities" + or + wrong = "compatablity" and right = "compatibility" + or + wrong = "compatiable" and right = "compatible" + or + wrong = "compatiblities" and right = "compatibilities" + or + wrong = "compatiblity" and right = "compatibility" + or + wrong = "compeitions" and right = "competitions" + or + wrong = "compensantion" and right = "compensation" + or + wrong = "competance" and right = "competence" + or + wrong = "competant" and right = "competent" + or + wrong = "competative" and right = "competitive" + or + wrong = "competion" and right = "competition" + or + wrong = "competion" and right = "completion" + or + wrong = "competitiion" and right = "competition" + or + wrong = "competive" and right = "competitive" + or + wrong = "competiveness" and right = "competitiveness" + or + wrong = "comphrehensive" and right = "comprehensive" + or + wrong = "compitent" and right = "competent" + or + wrong = "completelyl" and right = "completely" + or + wrong = "completetion" and right = "completion" + or + wrong = "complier" and right = "compiler" + or + wrong = "componant" and right = "component" + or + wrong = "comprable" and right = "comparable" + or + wrong = "comprimise" and right = "compromise" + or + wrong = "compulsary" and right = "compulsory" + or + wrong = "compulsery" and right = "compulsory" + or + wrong = "computarized" and right = "computerized" + or + wrong = "concensus" and right = "consensus" + or + wrong = "concider" and right = "consider" + or + wrong = "concidered" and right = "considered" + or + wrong = "concidering" and right = "considering" + or + wrong = "conciders" and right = "considers" + or + wrong = "concieted" and right = "conceited" + or + wrong = "concieved" and right = "conceived" + or + wrong = "concious" and right = "conscious" + or + wrong = "conciously" and right = "consciously" + or + wrong = "conciousness" and right = "consciousness" + or + wrong = "condamned" and right = "condemned" + or + wrong = "condemmed" and right = "condemned" + or + wrong = "condidtion" and right = "condition" + or + wrong = "condidtions" and right = "conditions" + or + wrong = "conected" and right = "connected" + or + wrong = "conection" and right = "connection" + or + wrong = "conesencus" and right = "consensus" + or + wrong = "confidental" and right = "confidential" + or + wrong = "confidentally" and right = "confidentially" + or + wrong = "confids" and right = "confides" + or + wrong = "configureable" and right = "configurable" + or + wrong = "confortable" and right = "comfortable" + or + wrong = "congradulations" and right = "congratulations" + or + wrong = "congresional" and right = "congressional" + or + wrong = "conived" and right = "connived" + or + wrong = "conjecutre" and right = "conjecture" + or + wrong = "conjuction" and right = "conjunction" + or + wrong = "connectinos" and right = "connections" + or + wrong = "conneticut" and right = "connecticut" + or + wrong = "conotations" and right = "connotations" + or + wrong = "conquerd" and right = "conquered" + or + wrong = "conquerer" and right = "conqueror" + or + wrong = "conquerers" and right = "conquerors" + or + wrong = "conqured" and right = "conquered" + or + wrong = "conscent" and right = "consent" + or + wrong = "consciouness" and right = "consciousness" + or + wrong = "consdider" and right = "consider" + or + wrong = "consdidered" and right = "considered" + or + wrong = "consdiered" and right = "considered" + or + wrong = "consectutive" and right = "consecutive" + or + wrong = "consenquently" and right = "consequently" + or + wrong = "consentrate" and right = "concentrate" + or + wrong = "consentrated" and right = "concentrated" + or + wrong = "consentrates" and right = "concentrates" + or + wrong = "consept" and right = "concept" + or + wrong = "consequentually" and right = "consequently" + or + wrong = "consequeseces" and right = "consequences" + or + wrong = "consern" and right = "concern" + or + wrong = "conserned" and right = "concerned" + or + wrong = "conserning" and right = "concerning" + or + wrong = "conservitive" and right = "conservative" + or + wrong = "consiciousness" and right = "consciousness" + or + wrong = "consicousness" and right = "consciousness" + or + wrong = "considerd" and right = "considered" + or + wrong = "consideres" and right = "considered" + or + wrong = "consious" and right = "conscious" + or + wrong = "consistant" and right = "consistent" + or + wrong = "consistantly" and right = "consistently" + or + wrong = "consituencies" and right = "constituencies" + or + wrong = "consituency" and right = "constituency" + or + wrong = "consituted" and right = "constituted" + or + wrong = "consitution" and right = "constitution" + or + wrong = "consitutional" and right = "constitutional" + or + wrong = "consolodate" and right = "consolidate" + or + wrong = "consolodated" and right = "consolidated" + or + wrong = "consonent" and right = "consonant" + or + wrong = "consonents" and right = "consonants" + or + wrong = "consorcium" and right = "consortium" + or + wrong = "conspiracys" and right = "conspiracies" + or + wrong = "conspiriator" and right = "conspirator" + or + wrong = "consructor" and right = "constructor" + or + wrong = "constaints" and right = "constraints" + or + wrong = "constanly" and right = "constantly" + or + wrong = "constarnation" and right = "consternation" + or + wrong = "constatn" and right = "constant" + or + wrong = "constinually" and right = "continually" + or + wrong = "constituant" and right = "constituent" + or + wrong = "constituants" and right = "constituents" + or + wrong = "constituion" and right = "constitution" + or + wrong = "constituional" and right = "constitutional" + or + wrong = "consttruction" and right = "construction" + or + wrong = "constuction" and right = "construction" + or + wrong = "consulant" and right = "consultant" + or + wrong = "consumate" and right = "consummate" + or + wrong = "consumated" and right = "consummated" + or + wrong = "contaiminate" and right = "contaminate" + or + wrong = "containes" and right = "contains" + or + wrong = "contamporaries" and right = "contemporaries" + or + wrong = "contamporary" and right = "contemporary" + or + wrong = "contempoary" and right = "contemporary" + or + wrong = "contemporaneus" and right = "contemporaneous" + or + wrong = "contempory" and right = "contemporary" + or + wrong = "contendor" and right = "contender" + or + wrong = "contian" and right = "contain" + or + wrong = "contians" and right = "contains" + or + wrong = "contibute" and right = "contribute" + or + wrong = "contibuted" and right = "contributed" + or + wrong = "contibutes" and right = "contributes" + or + wrong = "contigent" and right = "contingent" + or + wrong = "contined" and right = "continued" + or + wrong = "continential" and right = "continental" + or + wrong = "continous" and right = "continuous" + or + wrong = "continously" and right = "continuously" + or + wrong = "continueing" and right = "continuing" + or + wrong = "contravercial" and right = "controversial" + or + wrong = "contraversy" and right = "controversy" + or + wrong = "contributer" and right = "contributor" + or + wrong = "contributers" and right = "contributors" + or + wrong = "contritutions" and right = "contributions" + or + wrong = "controled" and right = "controlled" + or + wrong = "controling" and right = "controlling" + or + wrong = "controll" and right = "control" + or + wrong = "controlls" and right = "controls" + or + wrong = "controvercial" and right = "controversial" + or + wrong = "controvercy" and right = "controversy" + or + wrong = "controveries" and right = "controversies" + or + wrong = "controversal" and right = "controversial" + or + wrong = "controversey" and right = "controversy" + or + wrong = "controvertial" and right = "controversial" + or + wrong = "controvery" and right = "controversy" + or + wrong = "contruction" and right = "construction" + or + wrong = "contructor" and right = "constructor" + or + wrong = "contstruction" and right = "construction" + or + wrong = "conveinent" and right = "convenient" + or + wrong = "convenant" and right = "covenant" + or + wrong = "convential" and right = "conventional" + or + wrong = "convertables" and right = "convertibles" + or + wrong = "convertion" and right = "conversion" + or + wrong = "conviced" and right = "convinced" + or + wrong = "convienient" and right = "convenient" + or + wrong = "coordiantion" and right = "coordination" + or + wrong = "coorperation" and right = "cooperation" + or + wrong = "coorperation" and right = "corporation" + or + wrong = "coorperations" and right = "corporations" + or + wrong = "copmetitors" and right = "competitors" + or + wrong = "coputer" and right = "computer" + or + wrong = "copywrite" and right = "copyright" + or + wrong = "coridal" and right = "cordial" + or + wrong = "cornmitted" and right = "committed" + or + wrong = "corosion" and right = "corrosion" + or + wrong = "corparate" and right = "corporate" + or + wrong = "corperations" and right = "corporations" + or + wrong = "correcters" and right = "correctors" + or + wrong = "correponding" and right = "corresponding" + or + wrong = "correposding" and right = "corresponding" + or + wrong = "correspondant" and right = "correspondent" + or + wrong = "correspondants" and right = "correspondents" + or + wrong = "corridoors" and right = "corridors" + or + wrong = "corrispond" and right = "correspond" + or + wrong = "corrispondant" and right = "correspondent" + or + wrong = "corrispondants" and right = "correspondents" + or + wrong = "corrisponded" and right = "corresponded" + or + wrong = "corrisponding" and right = "corresponding" + or + wrong = "corrisponds" and right = "corresponds" + or + wrong = "costitution" and right = "constitution" + or + wrong = "coucil" and right = "council" + or + wrong = "coudl" and right = "cloud" + or + wrong = "coudl" and right = "could" + or + wrong = "councellor" and right = "councillor" + or + wrong = "councellor" and right = "councilor" + or + wrong = "councellor" and right = "counselor" + or + wrong = "councellors" and right = "councillors" + or + wrong = "councellors" and right = "councilors" + or + wrong = "councellors" and right = "counselors" + or + wrong = "counries" and right = "countries" + or + wrong = "countains" and right = "contains" + or + wrong = "countires" and right = "countries" + or + wrong = "coururier" and right = "courier" + or + wrong = "coururier" and right = "couturier" + or + wrong = "coverted" and right = "converted" + or + wrong = "coverted" and right = "covered" + or + wrong = "coverted" and right = "coveted" + or + wrong = "cpoy" and right = "copy" + or + wrong = "cpoy" and right = "coy" + or + wrong = "creaeted" and right = "created" + or + wrong = "creedence" and right = "credence" + or + wrong = "critereon" and right = "criterion" + or + wrong = "criterias" and right = "criteria" + or + wrong = "criticists" and right = "critics" + or + wrong = "critising" and right = "criticising" + or + wrong = "critising" and right = "criticizing" + or + wrong = "critisising" and right = "criticising" + or + wrong = "critisism" and right = "criticism" + or + wrong = "critisisms" and right = "criticisms" + or + wrong = "critisize" and right = "criticise" + or + wrong = "critisize" and right = "criticize" + or + wrong = "critisized" and right = "criticised" + or + wrong = "critisized" and right = "criticized" + or + wrong = "critisizes" and right = "criticises" + or + wrong = "critisizes" and right = "criticizes" + or + wrong = "critisizing" and right = "criticising" + or + wrong = "critisizing" and right = "criticizing" + or + wrong = "critized" and right = "criticized" + or + wrong = "critizing" and right = "criticizing" + or + wrong = "crockodiles" and right = "crocodiles" + or + wrong = "crowm" and right = "crown" + or + wrong = "crtical" and right = "critical" + or + wrong = "crticised" and right = "criticised" + or + wrong = "crucifiction" and right = "crucifixion" + or + wrong = "crusies" and right = "cruises" + or + wrong = "crutial" and right = "crucial" + or + wrong = "crystalisation" and right = "crystallisation" + or + wrong = "culiminating" and right = "culminating" + or + wrong = "cumulatative" and right = "cumulative" + or + wrong = "curch" and right = "church" + or + wrong = "curcuit" and right = "circuit" + or + wrong = "currenly" and right = "currently" + or + wrong = "curriculem" and right = "curriculum" + or + wrong = "cxan" and right = "cyan" + or + wrong = "cyclinder" and right = "cylinder" + or + wrong = "dacquiri" and right = "daiquiri" + or + wrong = "daed" and right = "dead" + or + wrong = "dael" and right = "dahl" + or + wrong = "dael" and right = "deal" + or + wrong = "dael" and right = "dial" + or + wrong = "dalmation" and right = "dalmatian" + or + wrong = "damenor" and right = "demeanor" + or + wrong = "dammage" and right = "damage" + or + wrong = "dardenelles" and right = "dardanelles" + or + wrong = "daugher" and right = "daughter" + or + wrong = "deafult" and right = "default" + or + wrong = "debateable" and right = "debatable" + or + wrong = "decendant" and right = "descendant" + or + wrong = "decendants" and right = "descendants" + or + wrong = "decendent" and right = "descendant" + or + wrong = "decendents" and right = "descendants" + or + wrong = "decideable" and right = "decidable" + or + wrong = "decidely" and right = "decidedly" + or + wrong = "decieved" and right = "deceived" + or + wrong = "decison" and right = "decision" + or + wrong = "decomissioned" and right = "decommissioned" + or + wrong = "decomposit" and right = "decompose" + or + wrong = "decomposited" and right = "decomposed" + or + wrong = "decompositing" and right = "decomposing" + or + wrong = "decomposits" and right = "decomposes" + or + wrong = "decress" and right = "decrees" + or + wrong = "decribe" and right = "describe" + or + wrong = "decribed" and right = "described" + or + wrong = "decribes" and right = "describes" + or + wrong = "decribing" and right = "describing" + or + wrong = "dectect" and right = "detect" + or + wrong = "defendent" and right = "defendant" + or + wrong = "defendents" and right = "defendants" + or + wrong = "deffensively" and right = "defensively" + or + wrong = "deffine" and right = "define" + or + wrong = "deffined" and right = "defined" + or + wrong = "definance" and right = "defiance" + or + wrong = "definate" and right = "definite" + or + wrong = "definately" and right = "definitely" + or + wrong = "definatly" and right = "definitely" + or + wrong = "definetly" and right = "definitely" + or + wrong = "definining" and right = "defining" + or + wrong = "definit" and right = "definite" + or + wrong = "definitly" and right = "definitely" + or + wrong = "definiton" and right = "definition" + or + wrong = "defintion" and right = "definition" + or + wrong = "defualt" and right = "default" + or + wrong = "defult" and right = "default" + or + wrong = "degrate" and right = "degrade" + or + wrong = "delagates" and right = "delegates" + or + wrong = "delapidated" and right = "dilapidated" + or + wrong = "delerious" and right = "delirious" + or + wrong = "delevopment" and right = "development" + or + wrong = "deliberatly" and right = "deliberately" + or + wrong = "delusionally" and right = "delusively" + or + wrong = "demenor" and right = "demeanor" + or + wrong = "demographical" and right = "demographic" + or + wrong = "demolision" and right = "demolition" + or + wrong = "demorcracy" and right = "democracy" + or + wrong = "demostration" and right = "demonstration" + or + wrong = "denegrating" and right = "denigrating" + or + wrong = "densly" and right = "densely" + or + wrong = "deparment" and right = "department" + or + wrong = "deparmental" and right = "departmental" + or + wrong = "deparments" and right = "departments" + or + wrong = "dependance" and right = "dependence" + or + wrong = "dependancy" and right = "dependency" + or + wrong = "deram" and right = "dram" + or + wrong = "deram" and right = "dream" + or + wrong = "deriviated" and right = "derived" + or + wrong = "derivitive" and right = "derivative" + or + wrong = "derogitory" and right = "derogatory" + or + wrong = "descendands" and right = "descendants" + or + wrong = "descibed" and right = "described" + or + wrong = "desciptors" and right = "descriptors" + or + wrong = "descision" and right = "decision" + or + wrong = "descisions" and right = "decisions" + or + wrong = "descriibes" and right = "describes" + or + wrong = "descripters" and right = "descriptors" + or + wrong = "descripton" and right = "description" + or + wrong = "desctruction" and right = "destruction" + or + wrong = "descuss" and right = "discuss" + or + wrong = "desgined" and right = "designed" + or + wrong = "deside" and right = "decide" + or + wrong = "desigining" and right = "designing" + or + wrong = "desinations" and right = "destinations" + or + wrong = "desintegrated" and right = "disintegrated" + or + wrong = "desintegration" and right = "disintegration" + or + wrong = "desireable" and right = "desirable" + or + wrong = "desitned" and right = "destined" + or + wrong = "desktiop" and right = "desktop" + or + wrong = "desorder" and right = "disorder" + or + wrong = "desoriented" and right = "disoriented" + or + wrong = "desparate" and right = "desperate" + or + wrong = "desparate" and right = "disparate" + or + wrong = "despict" and right = "depict" + or + wrong = "despiration" and right = "desperation" + or + wrong = "dessicated" and right = "desiccated" + or + wrong = "dessigned" and right = "designed" + or + wrong = "destablized" and right = "destabilized" + or + wrong = "destory" and right = "destroy" + or + wrong = "desugered" and right = "desugared" + or + wrong = "detailled" and right = "detailed" + or + wrong = "detatched" and right = "detached" + or + wrong = "deteoriated" and right = "deteriorated" + or + wrong = "deteriate" and right = "deteriorate" + or + wrong = "deterioriating" and right = "deteriorating" + or + wrong = "determinining" and right = "determining" + or + wrong = "detremental" and right = "detrimental" + or + wrong = "devasted" and right = "devastated" + or + wrong = "develope" and right = "develop" + or + wrong = "developement" and right = "development" + or + wrong = "developped" and right = "developed" + or + wrong = "develpment" and right = "development" + or + wrong = "devels" and right = "delves" + or + wrong = "devestated" and right = "devastated" + or + wrong = "devestating" and right = "devastating" + or + wrong = "devide" and right = "divide" + or + wrong = "devided" and right = "divided" + or + wrong = "devistating" and right = "devastating" + or + wrong = "devolopement" and right = "development" + or + wrong = "diablical" and right = "diabolical" + or + wrong = "diamons" and right = "diamonds" + or + wrong = "diaster" and right = "disaster" + or + wrong = "dichtomy" and right = "dichotomy" + or + wrong = "diconnects" and right = "disconnects" + or + wrong = "dicover" and right = "discover" + or + wrong = "dicovered" and right = "discovered" + or + wrong = "dicovering" and right = "discovering" + or + wrong = "dicovers" and right = "discovers" + or + wrong = "dicovery" and right = "discovery" + or + wrong = "dictionarys" and right = "dictionaries" + or + wrong = "dicussed" and right = "discussed" + or + wrong = "diea" and right = "die" + or + wrong = "diea" and right = "idea" + or + wrong = "dieing" and right = "dyeing" + or + wrong = "dieing" and right = "dying" + or + wrong = "dieties" and right = "deities" + or + wrong = "diety" and right = "deity" + or + wrong = "diferent" and right = "different" + or + wrong = "diferrent" and right = "different" + or + wrong = "differentiatiations" and right = "differentiations" + or + wrong = "differnt" and right = "different" + or + wrong = "difficulity" and right = "difficulty" + or + wrong = "diffrent" and right = "different" + or + wrong = "dificulties" and right = "difficulties" + or + wrong = "dificulty" and right = "difficulty" + or + wrong = "dimenions" and right = "dimensions" + or + wrong = "dimention" and right = "dimension" + or + wrong = "dimentional" and right = "dimensional" + or + wrong = "dimentions" and right = "dimensions" + or + wrong = "dimesnional" and right = "dimensional" + or + wrong = "diminuitive" and right = "diminutive" + or + wrong = "dimunitive" and right = "diminutive" + or + wrong = "diosese" and right = "diocese" + or + wrong = "diphtong" and right = "diphthong" + or + wrong = "diphtongs" and right = "diphthongs" + or + wrong = "diplomancy" and right = "diplomacy" + or + wrong = "dipthong" and right = "diphthong" + or + wrong = "dipthongs" and right = "diphthongs" + or + wrong = "directoty" and right = "directory" + or + wrong = "dirived" and right = "derived" + or + wrong = "disagreeed" and right = "disagreed" + or + wrong = "disapeared" and right = "disappeared" + or + wrong = "disapointing" and right = "disappointing" + or + wrong = "disappearred" and right = "disappeared" + or + wrong = "disaproval" and right = "disapproval" + or + wrong = "disasterous" and right = "disastrous" + or + wrong = "disatisfaction" and right = "dissatisfaction" + or + wrong = "disatisfied" and right = "dissatisfied" + or + wrong = "disatrous" and right = "disastrous" + or + wrong = "discontentment" and right = "discontent" + or + wrong = "discribe" and right = "describe" + or + wrong = "discribed" and right = "described" + or + wrong = "discribes" and right = "describes" + or + wrong = "discribing" and right = "describing" + or + wrong = "disctinction" and right = "distinction" + or + wrong = "disctinctive" and right = "distinctive" + or + wrong = "disemination" and right = "dissemination" + or + wrong = "disenchanged" and right = "disenchanted" + or + wrong = "disiplined" and right = "disciplined" + or + wrong = "disobediance" and right = "disobedience" + or + wrong = "disobediant" and right = "disobedient" + or + wrong = "disolved" and right = "dissolved" + or + wrong = "disover" and right = "discover" + or + wrong = "dispair" and right = "despair" + or + wrong = "disparingly" and right = "disparagingly" + or + wrong = "dispence" and right = "dispense" + or + wrong = "dispenced" and right = "dispensed" + or + wrong = "dispencing" and right = "dispensing" + or + wrong = "dispicable" and right = "despicable" + or + wrong = "dispite" and right = "despite" + or + wrong = "dispostion" and right = "disposition" + or + wrong = "disproportiate" and right = "disproportionate" + or + wrong = "disputandem" and right = "disputandum" + or + wrong = "disricts" and right = "districts" + or + wrong = "dissagreement" and right = "disagreement" + or + wrong = "dissapear" and right = "disappear" + or + wrong = "dissapearance" and right = "disappearance" + or + wrong = "dissapeared" and right = "disappeared" + or + wrong = "dissapearing" and right = "disappearing" + or + wrong = "dissapears" and right = "disappears" + or + wrong = "dissappear" and right = "disappear" + or + wrong = "dissappears" and right = "disappears" + or + wrong = "dissappointed" and right = "disappointed" + or + wrong = "dissarray" and right = "disarray" + or + wrong = "dissobediance" and right = "disobedience" + or + wrong = "dissobediant" and right = "disobedient" + or + wrong = "dissobedience" and right = "disobedience" + or + wrong = "dissobedient" and right = "disobedient" + or + wrong = "distiction" and right = "distinction" + or + wrong = "distingish" and right = "distinguish" + or + wrong = "distingished" and right = "distinguished" + or + wrong = "distingishes" and right = "distinguishes" + or + wrong = "distingishing" and right = "distinguishing" + or + wrong = "distingquished" and right = "distinguished" + or + wrong = "distrubution" and right = "distribution" + or + wrong = "distruction" and right = "destruction" + or + wrong = "distructive" and right = "destructive" + or + wrong = "ditributed" and right = "distributed" + or + wrong = "diversed" and right = "diverged" + or + wrong = "diversed" and right = "diverse" + or + wrong = "divice" and right = "device" + or + wrong = "divinition" and right = "divination" + or + wrong = "divison" and right = "division" + or + wrong = "divisons" and right = "divisions" + or + wrong = "doccument" and right = "document" + or + wrong = "doccumented" and right = "documented" + or + wrong = "doccuments" and right = "documents" + or + wrong = "docrines" and right = "doctrines" + or + wrong = "doctines" and right = "doctrines" + or + wrong = "documenatry" and right = "documentary" + or + wrong = "doens" and right = "does" + or + wrong = "doign" and right = "doing" + or + wrong = "dominaton" and right = "domination" + or + wrong = "dominent" and right = "dominant" + or + wrong = "dominiant" and right = "dominant" + or + wrong = "donig" and right = "doing" + or + wrong = "doub" and right = "daub" + or + wrong = "doub" and right = "doubt" + or + wrong = "doulbe" and right = "double" + or + wrong = "dowloads" and right = "downloads" + or + wrong = "dramtic" and right = "dramatic" + or + wrong = "draughtman" and right = "draughtsman" + or + wrong = "dravadian" and right = "dravidian" + or + wrong = "dreasm" and right = "dreams" + or + wrong = "driectly" and right = "directly" + or + wrong = "drnik" and right = "drink" + or + wrong = "druming" and right = "drumming" + or + wrong = "drummless" and right = "drumless" + or + wrong = "dum" and right = "dumb" + or + wrong = "dupicate" and right = "duplicate" + or + wrong = "durig" and right = "during" + or + wrong = "durring" and right = "during" + or + wrong = "duting" and right = "during" + or + wrong = "dyas" and right = "dryas" + or + wrong = "eahc" and right = "each" + or + wrong = "ealier" and right = "earlier" + or + wrong = "earlies" and right = "earliest" + or + wrong = "earnt" and right = "earned" + or + wrong = "ecclectic" and right = "eclectic" + or + wrong = "eceonomy" and right = "economy" + or + wrong = "ecidious" and right = "deciduous" + or + wrong = "eclispe" and right = "eclipse" + or + wrong = "ecomonic" and right = "economic" + or + wrong = "ect" and right = "etc" + or + wrong = "editting" and right = "editing" + or + wrong = "eearly" and right = "early" + or + wrong = "efel" and right = "evil" + or + wrong = "effeciency" and right = "efficiency" + or + wrong = "effecient" and right = "efficient" + or + wrong = "effeciently" and right = "efficiently" + or + wrong = "efficency" and right = "efficiency" + or + wrong = "efficent" and right = "efficient" + or + wrong = "efficently" and right = "efficiently" + or + wrong = "efford" and right = "afford" + or + wrong = "efford" and right = "effort" + or + wrong = "effords" and right = "affords" + or + wrong = "effords" and right = "efforts" + or + wrong = "effulence" and right = "effluence" + or + wrong = "eigth" and right = "eight" + or + wrong = "eigth" and right = "eighth" + or + wrong = "eiter" and right = "either" + or + wrong = "elction" and right = "election" + or + wrong = "electic" and right = "eclectic" + or + wrong = "electic" and right = "electric" + or + wrong = "electon" and right = "election" + or + wrong = "electon" and right = "electron" + or + wrong = "electrial" and right = "electrical" + or + wrong = "electricly" and right = "electrically" + or + wrong = "electricty" and right = "electricity" + or + wrong = "elementay" and right = "elementary" + or + wrong = "eleminated" and right = "eliminated" + or + wrong = "eleminating" and right = "eliminating" + or + wrong = "eles" and right = "eels" + or + wrong = "eletricity" and right = "electricity" + or + wrong = "elicided" and right = "elicited" + or + wrong = "eligable" and right = "eligible" + or + wrong = "elimentary" and right = "elementary" + or + wrong = "ellected" and right = "elected" + or + wrong = "elphant" and right = "elephant" + or + wrong = "embarass" and right = "embarrass" + or + wrong = "embarassed" and right = "embarrassed" + or + wrong = "embarassing" and right = "embarrassing" + or + wrong = "embarassment" and right = "embarrassment" + or + wrong = "embargos" and right = "embargoes" + or + wrong = "embarras" and right = "embarrass" + or + wrong = "embarrased" and right = "embarrassed" + or + wrong = "embarrasing" and right = "embarrassing" + or + wrong = "embarrasment" and right = "embarrassment" + or + wrong = "embezelled" and right = "embezzled" + or + wrong = "emblamatic" and right = "emblematic" + or + wrong = "eminate" and right = "emanate" + or + wrong = "eminated" and right = "emanated" + or + wrong = "emision" and right = "emission" + or + wrong = "emited" and right = "emitted" + or + wrong = "emiting" and right = "emitting" + or + wrong = "emition" and right = "emission" + or + wrong = "emition" and right = "emotion" + or + wrong = "emmediately" and right = "immediately" + or + wrong = "emmigrated" and right = "emigrated" + or + wrong = "emmigrated" and right = "immigrated" + or + wrong = "emminent" and right = "eminent" + or + wrong = "emminent" and right = "imminent" + or + wrong = "emminently" and right = "eminently" + or + wrong = "emmisaries" and right = "emissaries" + or + wrong = "emmisarries" and right = "emissaries" + or + wrong = "emmisarry" and right = "emissary" + or + wrong = "emmisary" and right = "emissary" + or + wrong = "emmision" and right = "emission" + or + wrong = "emmisions" and right = "emissions" + or + wrong = "emmited" and right = "emitted" + or + wrong = "emmiting" and right = "emitting" + or + wrong = "emmitted" and right = "emitted" + or + wrong = "emmitting" and right = "emitting" + or + wrong = "emnity" and right = "enmity" + or + wrong = "emperical" and right = "empirical" + or + wrong = "emphaised" and right = "emphasised" + or + wrong = "emphsis" and right = "emphasis" + or + wrong = "emphysyma" and right = "emphysema" + or + wrong = "empirial" and right = "empirical" + or + wrong = "empirial" and right = "imperial" + or + wrong = "emporer" and right = "emperor" + or + wrong = "emprisoned" and right = "imprisoned" + or + wrong = "enameld" and right = "enameled" + or + wrong = "enchancement" and right = "enhancement" + or + wrong = "encouraing" and right = "encouraging" + or + wrong = "encryptiion" and right = "encryption" + or + wrong = "encylopedia" and right = "encyclopedia" + or + wrong = "endevors" and right = "endeavors" + or + wrong = "endevour" and right = "endeavour" + or + wrong = "endig" and right = "ending" + or + wrong = "endolithes" and right = "endoliths" + or + wrong = "enduce" and right = "induce" + or + wrong = "ened" and right = "need" + or + wrong = "enforceing" and right = "enforcing" + or + wrong = "engagment" and right = "engagement" + or + wrong = "engeneer" and right = "engineer" + or + wrong = "engeneering" and right = "engineering" + or + wrong = "engieneer" and right = "engineer" + or + wrong = "engieneers" and right = "engineers" + or + wrong = "enlargment" and right = "enlargement" + or + wrong = "enlargments" and right = "enlargements" + or + wrong = "enlish" and right = "english" + or + wrong = "enlish" and right = "enlist" + or + wrong = "enourmous" and right = "enormous" + or + wrong = "enourmously" and right = "enormously" + or + wrong = "ensconsed" and right = "ensconced" + or + wrong = "entaglements" and right = "entanglements" + or + wrong = "enteratinment" and right = "entertainment" + or + wrong = "enthusiatic" and right = "enthusiastic" + or + wrong = "entitity" and right = "entity" + or + wrong = "entitlied" and right = "entitled" + or + wrong = "entrepeneur" and right = "entrepreneur" + or + wrong = "entrepeneurs" and right = "entrepreneurs" + or + wrong = "enviorment" and right = "environment" + or + wrong = "enviormental" and right = "environmental" + or + wrong = "enviormentally" and right = "environmentally" + or + wrong = "enviorments" and right = "environments" + or + wrong = "enviornment" and right = "environment" + or + wrong = "enviornmental" and right = "environmental" + or + wrong = "enviornmentalist" and right = "environmentalist" + or + wrong = "enviornmentally" and right = "environmentally" + or + wrong = "enviornments" and right = "environments" + or + wrong = "enviroment" and right = "environment" + or + wrong = "enviromental" and right = "environmental" + or + wrong = "enviromentalist" and right = "environmentalist" + or + wrong = "enviromentally" and right = "environmentally" + or + wrong = "enviroments" and right = "environments" + or + wrong = "environemnt" and right = "environment" + or + wrong = "envolutionary" and right = "evolutionary" + or + wrong = "envrionments" and right = "environments" + or + wrong = "enxt" and right = "next" + or + wrong = "epidsodes" and right = "episodes" + or + wrong = "epsiode" and right = "episode" + or + wrong = "equialent" and right = "equivalent" + or + wrong = "equilibium" and right = "equilibrium" + or + wrong = "equilibrum" and right = "equilibrium" + or + wrong = "equiped" and right = "equipped" + or + wrong = "equippment" and right = "equipment" + or + wrong = "equitorial" and right = "equatorial" + or + wrong = "equivelant" and right = "equivalent" + or + wrong = "equivelent" and right = "equivalent" + or + wrong = "equivilant" and right = "equivalent" + or + wrong = "equivilent" and right = "equivalent" + or + wrong = "equivlalent" and right = "equivalent" + or + wrong = "erally" and right = "orally" + or + wrong = "erally" and right = "really" + or + wrong = "eratic" and right = "erratic" + or + wrong = "eratically" and right = "erratically" + or + wrong = "eraticly" and right = "erratically" + or + wrong = "erested" and right = "arrested" + or + wrong = "erested" and right = "erected" + or + wrong = "errupted" and right = "erupted" + or + wrong = "esential" and right = "essential" + or + wrong = "esitmated" and right = "estimated" + or + wrong = "esle" and right = "else" + or + wrong = "especialy" and right = "especially" + or + wrong = "essencial" and right = "essential" + or + wrong = "essense" and right = "essence" + or + wrong = "essentail" and right = "essential" + or + wrong = "essentialy" and right = "essentially" + or + wrong = "essentual" and right = "essential" + or + wrong = "essesital" and right = "essential" + or + wrong = "estabishes" and right = "establishes" + or + wrong = "establising" and right = "establishing" + or + wrong = "ethnocentricm" and right = "ethnocentrism" + or + wrong = "ethose" and right = "ethos" + or + wrong = "ethose" and right = "those" + or + wrong = "europian" and right = "european" + or + wrong = "europians" and right = "europeans" + or + wrong = "eurpean" and right = "european" + or + wrong = "eurpoean" and right = "european" + or + wrong = "evenhtually" and right = "eventually" + or + wrong = "eventally" and right = "eventually" + or + wrong = "eventially" and right = "eventually" + or + wrong = "eventualy" and right = "eventually" + or + wrong = "everthing" and right = "everything" + or + wrong = "everyting" and right = "everything" + or + wrong = "eveyr" and right = "every" + or + wrong = "evidentally" and right = "evidently" + or + wrong = "exagerate" and right = "exaggerate" + or + wrong = "exagerated" and right = "exaggerated" + or + wrong = "exagerates" and right = "exaggerates" + or + wrong = "exagerating" and right = "exaggerating" + or + wrong = "exagerrate" and right = "exaggerate" + or + wrong = "exagerrated" and right = "exaggerated" + or + wrong = "exagerrates" and right = "exaggerates" + or + wrong = "exagerrating" and right = "exaggerating" + or + wrong = "examinated" and right = "examined" + or + wrong = "exampt" and right = "exempt" + or + wrong = "exapansion" and right = "expansion" + or + wrong = "excact" and right = "exact" + or + wrong = "excange" and right = "exchange" + or + wrong = "excecute" and right = "execute" + or + wrong = "excecuted" and right = "executed" + or + wrong = "excecutes" and right = "executes" + or + wrong = "excecuting" and right = "executing" + or + wrong = "excecution" and right = "execution" + or + wrong = "excedded" and right = "exceeded" + or + wrong = "excelent" and right = "excellent" + or + wrong = "excell" and right = "excel" + or + wrong = "excellance" and right = "excellence" + or + wrong = "excellant" and right = "excellent" + or + wrong = "excells" and right = "excels" + or + wrong = "excercise" and right = "exercise" + or + wrong = "exchanching" and right = "exchanging" + or + wrong = "excisted" and right = "existed" + or + wrong = "exculsivly" and right = "exclusively" + or + wrong = "execising" and right = "exercising" + or + wrong = "exection" and right = "execution" + or + wrong = "exectued" and right = "executed" + or + wrong = "exeedingly" and right = "exceedingly" + or + wrong = "exelent" and right = "excellent" + or + wrong = "exellent" and right = "excellent" + or + wrong = "exemple" and right = "example" + or + wrong = "exept" and right = "except" + or + wrong = "exeptional" and right = "exceptional" + or + wrong = "exerbate" and right = "exacerbate" + or + wrong = "exerbated" and right = "exacerbated" + or + wrong = "exerciese" and right = "exercises" + or + wrong = "exerpt" and right = "excerpt" + or + wrong = "exerpts" and right = "excerpts" + or + wrong = "exersize" and right = "exercise" + or + wrong = "exerternal" and right = "external" + or + wrong = "exhalted" and right = "exalted" + or + wrong = "exhibtion" and right = "exhibition" + or + wrong = "exibition" and right = "exhibition" + or + wrong = "exibitions" and right = "exhibitions" + or + wrong = "exicting" and right = "exciting" + or + wrong = "exinct" and right = "extinct" + or + wrong = "existance" and right = "existence" + or + wrong = "existant" and right = "existent" + or + wrong = "existince" and right = "existence" + or + wrong = "exliled" and right = "exiled" + or + wrong = "exludes" and right = "excludes" + or + wrong = "exmaple" and right = "example" + or + wrong = "exonorate" and right = "exonerate" + or + wrong = "exoskelaton" and right = "exoskeleton" + or + wrong = "expalin" and right = "explain" + or + wrong = "expatriot" and right = "expatriate" + or + wrong = "expeced" and right = "expected" + or + wrong = "expecially" and right = "especially" + or + wrong = "expeditonary" and right = "expeditionary" + or + wrong = "expeiments" and right = "experiments" + or + wrong = "expell" and right = "expel" + or + wrong = "expells" and right = "expels" + or + wrong = "experiance" and right = "experience" + or + wrong = "experianced" and right = "experienced" + or + wrong = "expession" and right = "expression" + or + wrong = "expessions" and right = "expressions" + or + wrong = "expiditions" and right = "expeditions" + or + wrong = "expierence" and right = "experience" + or + wrong = "explaination" and right = "explanation" + or + wrong = "explaning" and right = "explaining" + or + wrong = "explictly" and right = "explicitly" + or + wrong = "exploititive" and right = "exploitative" + or + wrong = "explotation" and right = "exploitation" + or + wrong = "expropiated" and right = "expropriated" + or + wrong = "expropiation" and right = "expropriation" + or + wrong = "exressed" and right = "expressed" + or + wrong = "extemely" and right = "extremely" + or + wrong = "extened" and right = "extended" + or + wrong = "extention" and right = "extension" + or + wrong = "extentions" and right = "extensions" + or + wrong = "extered" and right = "exerted" + or + wrong = "extermist" and right = "extremist" + or + wrong = "extint" and right = "extant" + or + wrong = "extint" and right = "extinct" + or + wrong = "extracter" and right = "extractor" + or + wrong = "extradiction" and right = "extradition" + or + wrong = "extraterrestial" and right = "extraterrestrial" + or + wrong = "extraterrestials" and right = "extraterrestrials" + or + wrong = "extravagent" and right = "extravagant" + or + wrong = "extrememly" and right = "extremely" + or + wrong = "extremeophile" and right = "extremophile" + or + wrong = "extremly" and right = "extremely" + or + wrong = "extrordinarily" and right = "extraordinarily" + or + wrong = "extrordinary" and right = "extraordinary" + or + wrong = "eyar" and right = "eyas" + or + wrong = "eyar" and right = "year" + or + wrong = "eyars" and right = "eyas" + or + wrong = "eyars" and right = "years" + or + wrong = "eyasr" and right = "eyas" + or + wrong = "eyasr" and right = "years" + or + wrong = "faciliate" and right = "facilitate" + or + wrong = "faciliated" and right = "facilitated" + or + wrong = "faciliates" and right = "facilitates" + or + wrong = "facilites" and right = "facilities" + or + wrong = "facillitate" and right = "facilitate" + or + wrong = "facinated" and right = "fascinated" + or + wrong = "facist" and right = "fascist" + or + wrong = "familes" and right = "families" + or + wrong = "familliar" and right = "familiar" + or + wrong = "famoust" and right = "famous" + or + wrong = "fanatism" and right = "fanaticism" + or + wrong = "farenheit" and right = "fahrenheit" + or + wrong = "fatc" and right = "fact" + or + wrong = "faught" and right = "fought" + or + wrong = "favoutrable" and right = "favourable" + or + wrong = "feasable" and right = "feasible" + or + wrong = "febuary" and right = "february" + or + wrong = "feburary" and right = "february" + or + wrong = "fedreally" and right = "federally" + or + wrong = "femminist" and right = "feminist" + or + wrong = "feromone" and right = "pheromone" + or + wrong = "fertily" and right = "fertility" + or + wrong = "fianite" and right = "finite" + or + wrong = "fianlly" and right = "finally" + or + wrong = "ficticious" and right = "fictitious" + or + wrong = "fictious" and right = "fictitious" + or + wrong = "fidn" and right = "find" + or + wrong = "fiel" and right = "feel" + or + wrong = "fiel" and right = "field" + or + wrong = "fiel" and right = "file" + or + wrong = "fiel" and right = "phial" + or + wrong = "fiels" and right = "feels" + or + wrong = "fiels" and right = "fields" + or + wrong = "fiels" and right = "files" + or + wrong = "fiels" and right = "phials" + or + wrong = "fiercly" and right = "fiercely" + or + wrong = "fightings" and right = "fighting" + or + wrong = "filiament" and right = "filament" + or + wrong = "fimilies" and right = "families" + or + wrong = "finacial" and right = "financial" + or + wrong = "finaly" and right = "finally" + or + wrong = "financialy" and right = "financially" + or + wrong = "firends" and right = "friends" + or + wrong = "firts" and right = "first" + or + wrong = "firts" and right = "flirts" + or + wrong = "fisionable" and right = "fissionable" + or + wrong = "flamable" and right = "flammable" + or + wrong = "flawess" and right = "flawless" + or + wrong = "fleed" and right = "fled" + or + wrong = "fleed" and right = "freed" + or + wrong = "flemmish" and right = "flemish" + or + wrong = "florescent" and right = "fluorescent" + or + wrong = "flourescent" and right = "fluorescent" + or + wrong = "flourine" and right = "fluorine" + or + wrong = "flourishment" and right = "flourishing" + or + wrong = "fluorish" and right = "flourish" + or + wrong = "follwoing" and right = "following" + or + wrong = "folowing" and right = "following" + or + wrong = "fomed" and right = "formed" + or + wrong = "fomr" and right = "form" + or + wrong = "fomr" and right = "from" + or + wrong = "fonetic" and right = "phonetic" + or + wrong = "fontrier" and right = "fontier" + or + wrong = "foootball" and right = "football" + or + wrong = "forbad" and right = "forbade" + or + wrong = "forbiden" and right = "forbidden" + or + wrong = "foreward" and right = "foreword" + or + wrong = "forfiet" and right = "forfeit" + or + wrong = "forhead" and right = "forehead" + or + wrong = "foriegn" and right = "foreign" + or + wrong = "formalhaut" and right = "fomalhaut" + or + wrong = "formallize" and right = "formalize" + or + wrong = "formallized" and right = "formalized" + or + wrong = "formaly" and right = "formally" + or + wrong = "formaly" and right = "formerly" + or + wrong = "formelly" and right = "formerly" + or + wrong = "formidible" and right = "formidable" + or + wrong = "formost" and right = "foremost" + or + wrong = "forsaw" and right = "foresaw" + or + wrong = "forseeable" and right = "foreseeable" + or + wrong = "fortelling" and right = "foretelling" + or + wrong = "forunner" and right = "forerunner" + or + wrong = "foucs" and right = "focus" + or + wrong = "foudn" and right = "found" + or + wrong = "fougth" and right = "fought" + or + wrong = "foundaries" and right = "foundries" + or + wrong = "foundary" and right = "foundry" + or + wrong = "foundland" and right = "newfoundland" + or + wrong = "fourties" and right = "forties" + or + wrong = "fourty" and right = "forty" + or + wrong = "fouth" and right = "fourth" + or + wrong = "foward" and right = "forward" + or + wrong = "framwork" and right = "framework" + or + wrong = "fransiscan" and right = "franciscan" + or + wrong = "fransiscans" and right = "franciscans" + or + wrong = "freind" and right = "friend" + or + wrong = "freindly" and right = "friendly" + or + wrong = "frequentily" and right = "frequently" + or + wrong = "frome" and right = "from" + or + wrong = "fromed" and right = "formed" + or + wrong = "froniter" and right = "frontier" + or + wrong = "fucntion" and right = "function" + or + wrong = "fucntioning" and right = "functioning" + or + wrong = "fufill" and right = "fulfill" + or + wrong = "fufilled" and right = "fulfilled" + or + wrong = "fulfiled" and right = "fulfilled" + or + wrong = "fullfill" and right = "fulfill" + or + wrong = "fullfilled" and right = "fulfilled" + or + wrong = "funcion" and right = "function" + or + wrong = "fundametal" and right = "fundamental" + or + wrong = "fundametals" and right = "fundamentals" + or + wrong = "funguses" and right = "fungi" + or + wrong = "funtion" and right = "function" + or + wrong = "funtions" and right = "functions" + or + wrong = "furuther" and right = "further" + or + wrong = "futher" and right = "further" + or + wrong = "futhermore" and right = "furthermore" + or + wrong = "futhroc" and right = "futhark" + or + wrong = "futhroc" and right = "futhorc" + or + wrong = "gae" and right = "gael" + or + wrong = "gae" and right = "gale" + or + wrong = "gae" and right = "game" + or + wrong = "galatic" and right = "galactic" + or + wrong = "galations" and right = "galatians" + or + wrong = "gallaxies" and right = "galaxies" + or + wrong = "galvinized" and right = "galvanized" + or + wrong = "ganerate" and right = "generate" + or + wrong = "ganes" and right = "games" + or + wrong = "ganster" and right = "gangster" + or + wrong = "garantee" and right = "guarantee" + or + wrong = "garanteed" and right = "guaranteed" + or + wrong = "garantees" and right = "guarantees" + or + wrong = "garnison" and right = "garrison" + or + wrong = "gaurantee" and right = "guarantee" + or + wrong = "gauranteed" and right = "guaranteed" + or + wrong = "gaurantees" and right = "guarantees" + or + wrong = "gaurd" and right = "gourd" + or + wrong = "gaurd" and right = "guard" + or + wrong = "gaurentee" and right = "guarantee" + or + wrong = "gaurenteed" and right = "guaranteed" + or + wrong = "gaurentees" and right = "guarantees" + or + wrong = "geneological" and right = "genealogical" + or + wrong = "geneologies" and right = "genealogies" + or + wrong = "geneology" and right = "genealogy" + or + wrong = "generaly" and right = "generally" + or + wrong = "generatting" and right = "generating" + or + wrong = "genialia" and right = "genitalia" + or + wrong = "geographicial" and right = "geographical" + or + wrong = "geometrician" and right = "geometer" + or + wrong = "geometricians" and right = "geometers" + or + wrong = "gerat" and right = "great" + or + wrong = "ghandi" and right = "gandhi" + or + wrong = "glamourous" and right = "glamorous" + or + wrong = "glight" and right = "flight" + or + wrong = "gnawwed" and right = "gnawed" + or + wrong = "godess" and right = "goddess" + or + wrong = "godesses" and right = "goddesses" + or + wrong = "godounov" and right = "godunov" + or + wrong = "gogin" and right = "gauguin" + or + wrong = "gogin" and right = "going" + or + wrong = "goign" and right = "going" + or + wrong = "gonig" and right = "going" + or + wrong = "gothenberg" and right = "gothenburg" + or + wrong = "gottleib" and right = "gottlieb" + or + wrong = "gouvener" and right = "governor" + or + wrong = "govement" and right = "government" + or + wrong = "govenment" and right = "government" + or + wrong = "govenrment" and right = "government" + or + wrong = "goverance" and right = "governance" + or + wrong = "goverment" and right = "government" + or + wrong = "govermental" and right = "governmental" + or + wrong = "governer" and right = "governor" + or + wrong = "governmnet" and right = "government" + or + wrong = "govorment" and right = "government" + or + wrong = "govormental" and right = "governmental" + or + wrong = "govornment" and right = "government" + or + wrong = "gracefull" and right = "graceful" + or + wrong = "graet" and right = "great" + or + wrong = "grafitti" and right = "graffiti" + or + wrong = "gramatically" and right = "grammatically" + or + wrong = "grammaticaly" and right = "grammatically" + or + wrong = "grammer" and right = "grammar" + or + wrong = "grat" and right = "great" + or + wrong = "gratuitious" and right = "gratuitous" + or + wrong = "greatful" and right = "grateful" + or + wrong = "greatfully" and right = "gratefully" + or + wrong = "greif" and right = "grief" + or + wrong = "gridles" and right = "griddles" + or + wrong = "gropu" and right = "group" + or + wrong = "grwo" and right = "grow" + or + wrong = "guaduloupe" and right = "guadalupe" + or + wrong = "guaduloupe" and right = "guadeloupe" + or + wrong = "guadulupe" and right = "guadalupe" + or + wrong = "guadulupe" and right = "guadeloupe" + or + wrong = "guage" and right = "gauge" + or + wrong = "guarentee" and right = "guarantee" + or + wrong = "guarenteed" and right = "guaranteed" + or + wrong = "guarentees" and right = "guarantees" + or + wrong = "guatamala" and right = "guatemala" + or + wrong = "guatamalan" and right = "guatemalan" + or + wrong = "guerrila" and right = "guerrilla" + or + wrong = "guerrilas" and right = "guerrillas" + or + wrong = "guidence" and right = "guidance" + or + wrong = "guilia" and right = "giulia" + or + wrong = "guilio" and right = "giulio" + or + wrong = "guiness" and right = "guinness" + or + wrong = "guiseppe" and right = "giuseppe" + or + wrong = "gunanine" and right = "guanine" + or + wrong = "gurantee" and right = "guarantee" + or + wrong = "guranteed" and right = "guaranteed" + or + wrong = "gurantees" and right = "guarantees" + or + wrong = "guttaral" and right = "guttural" + or + wrong = "gutteral" and right = "guttural" + or + wrong = "habaeus" and right = "habeas" + or + wrong = "habeus" and right = "habeas" + or + wrong = "habsbourg" and right = "habsburg" + or + wrong = "haemorrage" and right = "haemorrhage" + or + wrong = "haev" and right = "have" + or + wrong = "haev" and right = "heave" + or + wrong = "halarious" and right = "hilarious" + or + wrong = "hallowean" and right = "halloween" + or + wrong = "halp" and right = "help" + or + wrong = "hander" and right = "handler" + or + wrong = "hapen" and right = "happen" + or + wrong = "hapened" and right = "happened" + or + wrong = "hapening" and right = "happening" + or + wrong = "happend" and right = "happened" + or + wrong = "happended" and right = "happened" + or + wrong = "happenned" and right = "happened" + or + wrong = "harased" and right = "harassed" + or + wrong = "harases" and right = "harasses" + or + wrong = "harasment" and right = "harassment" + or + wrong = "harasments" and right = "harassments" + or + wrong = "harassement" and right = "harassment" + or + wrong = "harras" and right = "harass" + or + wrong = "harrased" and right = "harassed" + or + wrong = "harrases" and right = "harasses" + or + wrong = "harrasing" and right = "harassing" + or + wrong = "harrasment" and right = "harassment" + or + wrong = "harrasments" and right = "harassments" + or + wrong = "harrassed" and right = "harassed" + or + wrong = "harrasses" and right = "harassed" + or + wrong = "harrassing" and right = "harassing" + or + wrong = "harrassment" and right = "harassment" + or + wrong = "harrassments" and right = "harassments" + or + wrong = "hatian" and right = "haitian" + or + wrong = "haviest" and right = "heaviest" + or + wrong = "headquarer" and right = "headquarter" + or + wrong = "headquater" and right = "headquarter" + or + wrong = "headquatered" and right = "headquartered" + or + wrong = "headquaters" and right = "headquarters" + or + wrong = "healthercare" and right = "healthcare" + or + wrong = "heared" and right = "heard" + or + wrong = "heathy" and right = "healthy" + or + wrong = "heidelburg" and right = "heidelberg" + or + wrong = "heigher" and right = "higher" + or + wrong = "heirarchy" and right = "hierarchy" + or + wrong = "heiroglyphics" and right = "hieroglyphics" + or + wrong = "helment" and right = "helmet" + or + wrong = "helpfull" and right = "helpful" + or + wrong = "helpped" and right = "helped" + or + wrong = "hemmorhage" and right = "hemorrhage" + or + wrong = "herad" and right = "heard" + or + wrong = "herad" and right = "hera" + or + wrong = "heridity" and right = "heredity" + or + wrong = "heroe" and right = "hero" + or + wrong = "heros" and right = "heroes" + or + wrong = "hertiage" and right = "heritage" + or + wrong = "hertzs" and right = "hertz" + or + wrong = "hesistant" and right = "hesitant" + or + wrong = "heterogenous" and right = "heterogeneous" + or + wrong = "hieght" and right = "height" + or + wrong = "hierachical" and right = "hierarchical" + or + wrong = "hierachies" and right = "hierarchies" + or + wrong = "hierachy" and right = "hierarchy" + or + wrong = "hierarcical" and right = "hierarchical" + or + wrong = "hierarcy" and right = "hierarchy" + or + wrong = "hieroglph" and right = "hieroglyph" + or + wrong = "hieroglphs" and right = "hieroglyphs" + or + wrong = "higer" and right = "higher" + or + wrong = "higest" and right = "highest" + or + wrong = "higway" and right = "highway" + or + wrong = "hillarious" and right = "hilarious" + or + wrong = "himselv" and right = "himself" + or + wrong = "hinderance" and right = "hindrance" + or + wrong = "hinderence" and right = "hindrance" + or + wrong = "hindrence" and right = "hindrance" + or + wrong = "hipopotamus" and right = "hippopotamus" + or + wrong = "hismelf" and right = "himself" + or + wrong = "histocompatability" and right = "histocompatibility" + or + wrong = "historicians" and right = "historians" + or + wrong = "holf" and right = "hold" + or + wrong = "holliday" and right = "holiday" + or + wrong = "homogeneize" and right = "homogenize" + or + wrong = "homogeneized" and right = "homogenized" + or + wrong = "honory" and right = "honorary" + or + wrong = "horrifing" and right = "horrifying" + or + wrong = "hosited" and right = "hoisted" + or + wrong = "hospitible" and right = "hospitable" + or + wrong = "hounour" and right = "honour" + or + wrong = "housr" and right = "hours" + or + wrong = "housr" and right = "house" + or + wrong = "howver" and right = "however" + or + wrong = "hsitorians" and right = "historians" + or + wrong = "hstory" and right = "history" + or + wrong = "hten" and right = "hen" + or + wrong = "hten" and right = "the" + or + wrong = "hten" and right = "then" + or + wrong = "htere" and right = "here" + or + wrong = "htere" and right = "there" + or + wrong = "htey" and right = "they" + or + wrong = "htikn" and right = "think" + or + wrong = "hting" and right = "thing" + or + wrong = "htink" and right = "think" + or + wrong = "htis" and right = "this" + or + wrong = "humer" and right = "humor" + or + wrong = "humer" and right = "humour" + or + wrong = "humerous" and right = "humerus" + or + wrong = "humerous" and right = "humorous" + or + wrong = "huminoid" and right = "humanoid" + or + wrong = "humoural" and right = "humoral" + or + wrong = "humurous" and right = "humorous" + or + wrong = "husban" and right = "husband" + or + wrong = "hvae" and right = "have" + or + wrong = "hvaing" and right = "having" + or + wrong = "hvea" and right = "have" + or + wrong = "hvea" and right = "heave" + or + wrong = "hwihc" and right = "which" + or + wrong = "hwile" and right = "while" + or + wrong = "hwole" and right = "whole" + or + wrong = "hydogen" and right = "hydrogen" + or + wrong = "hydropile" and right = "hydrophile" + or + wrong = "hydropilic" and right = "hydrophilic" + or + wrong = "hydropobe" and right = "hydrophobe" + or + wrong = "hydropobic" and right = "hydrophobic" + or + wrong = "hygeine" and right = "hygiene" + or + wrong = "hyjack" and right = "hijack" + or + wrong = "hyjacking" and right = "hijacking" + or + wrong = "hypocracy" and right = "hypocrisy" + or + wrong = "hypocrasy" and right = "hypocrisy" + or + wrong = "hypocricy" and right = "hypocrisy" + or + wrong = "hypocrit" and right = "hypocrite" + or + wrong = "hypocrits" and right = "hypocrites" + or + wrong = "iconclastic" and right = "iconoclastic" + or + wrong = "idaeidae" and right = "idea" + or + wrong = "idaes" and right = "ideas" + or + wrong = "idealogies" and right = "ideologies" + or + wrong = "idealogy" and right = "ideology" + or + wrong = "identicial" and right = "identical" + or + wrong = "identifers" and right = "identifiers" + or + wrong = "ideosyncratic" and right = "idiosyncratic" + or + wrong = "idesa" and right = "ideas" + or + wrong = "idesa" and right = "ides" + or + wrong = "idiosyncracy" and right = "idiosyncrasy" + or + wrong = "ihaca" and right = "ithaca" + or + wrong = "illegimacy" and right = "illegitimacy" + or + wrong = "illegitmate" and right = "illegitimate" + or + wrong = "illess" and right = "illness" + or + wrong = "illiegal" and right = "illegal" + or + wrong = "illution" and right = "illusion" + or + wrong = "ilness" and right = "illness" + or + wrong = "ilogical" and right = "illogical" + or + wrong = "imagenary" and right = "imaginary" + or + wrong = "imagin" and right = "imagine" + or + wrong = "imaginery" and right = "imagery" + or + wrong = "imaginery" and right = "imaginary" + or + wrong = "imanent" and right = "eminent" + or + wrong = "imanent" and right = "imminent" + or + wrong = "imcomplete" and right = "incomplete" + or + wrong = "imediately" and right = "immediately" + or + wrong = "imense" and right = "immense" + or + wrong = "imigrant" and right = "emigrant" + or + wrong = "imigrant" and right = "immigrant" + or + wrong = "imigrated" and right = "emigrated" + or + wrong = "imigrated" and right = "immigrated" + or + wrong = "imigration" and right = "emigration" + or + wrong = "imigration" and right = "immigration" + or + wrong = "iminent" and right = "eminent" + or + wrong = "iminent" and right = "immanent" + or + wrong = "iminent" and right = "imminent" + or + wrong = "immediatley" and right = "immediately" + or + wrong = "immediatly" and right = "immediately" + or + wrong = "immidately" and right = "immediately" + or + wrong = "immidiately" and right = "immediately" + or + wrong = "immitate" and right = "imitate" + or + wrong = "immitated" and right = "imitated" + or + wrong = "immitating" and right = "imitating" + or + wrong = "immitator" and right = "imitator" + or + wrong = "immunosupressant" and right = "immunosuppressant" + or + wrong = "impecabbly" and right = "impeccably" + or + wrong = "impedence" and right = "impedance" + or + wrong = "implamenting" and right = "implementing" + or + wrong = "impliment" and right = "implement" + or + wrong = "implimented" and right = "implemented" + or + wrong = "imploys" and right = "employs" + or + wrong = "importamt" and right = "important" + or + wrong = "impressario" and right = "impresario" + or + wrong = "imprioned" and right = "imprisoned" + or + wrong = "imprisonned" and right = "imprisoned" + or + wrong = "improvision" and right = "improvisation" + or + wrong = "improvments" and right = "improvements" + or + wrong = "inablility" and right = "inability" + or + wrong = "inaccessable" and right = "inaccessible" + or + wrong = "inadiquate" and right = "inadequate" + or + wrong = "inadquate" and right = "inadequate" + or + wrong = "inadvertant" and right = "inadvertent" + or + wrong = "inadvertantly" and right = "inadvertently" + or + wrong = "inagurated" and right = "inaugurated" + or + wrong = "inaguration" and right = "inauguration" + or + wrong = "inappropiate" and right = "inappropriate" + or + wrong = "inaugures" and right = "inaugurates" + or + wrong = "inbalance" and right = "imbalance" + or + wrong = "inbalanced" and right = "imbalanced" + or + wrong = "inbetween" and right = "between" + or + wrong = "incarcirated" and right = "incarcerated" + or + wrong = "incidentially" and right = "incidentally" + or + wrong = "incidently" and right = "incidentally" + or + wrong = "inclreased" and right = "increased" + or + wrong = "includ" and right = "include" + or + wrong = "includng" and right = "including" + or + wrong = "incompatabilities" and right = "incompatibilities" + or + wrong = "incompatability" and right = "incompatibility" + or + wrong = "incompatable" and right = "incompatible" + or + wrong = "incompatablities" and right = "incompatibilities" + or + wrong = "incompatablity" and right = "incompatibility" + or + wrong = "incompatiblities" and right = "incompatibilities" + or + wrong = "incompatiblity" and right = "incompatibility" + or + wrong = "incompetance" and right = "incompetence" + or + wrong = "incompetant" and right = "incompetent" + or + wrong = "incomptable" and right = "incompatible" + or + wrong = "incomptetent" and right = "incompetent" + or + wrong = "inconsistant" and right = "inconsistent" + or + wrong = "incoroporated" and right = "incorporated" + or + wrong = "incorperation" and right = "incorporation" + or + wrong = "incorportaed" and right = "incorporated" + or + wrong = "incorprates" and right = "incorporates" + or + wrong = "incorruptable" and right = "incorruptible" + or + wrong = "incramentally" and right = "incrementally" + or + wrong = "increadible" and right = "incredible" + or + wrong = "incredable" and right = "incredible" + or + wrong = "inctroduce" and right = "introduce" + or + wrong = "inctroduced" and right = "introduced" + or + wrong = "incuding" and right = "including" + or + wrong = "incunabla" and right = "incunabula" + or + wrong = "indefinately" and right = "indefinitely" + or + wrong = "indefineable" and right = "undefinable" + or + wrong = "indefinitly" and right = "indefinitely" + or + wrong = "indentical" and right = "identical" + or + wrong = "indepedantly" and right = "independently" + or + wrong = "indepedence" and right = "independence" + or + wrong = "independance" and right = "independence" + or + wrong = "independant" and right = "independent" + or + wrong = "independantly" and right = "independently" + or + wrong = "independece" and right = "independence" + or + wrong = "independendet" and right = "independent" + or + wrong = "indespensable" and right = "indispensable" + or + wrong = "indespensible" and right = "indispensable" + or + wrong = "indictement" and right = "indictment" + or + wrong = "indigineous" and right = "indigenous" + or + wrong = "indipendence" and right = "independence" + or + wrong = "indipendent" and right = "independent" + or + wrong = "indipendently" and right = "independently" + or + wrong = "indispensible" and right = "indispensable" + or + wrong = "indisputible" and right = "indisputable" + or + wrong = "indisputibly" and right = "indisputably" + or + wrong = "indite" and right = "indict" + or + wrong = "individualy" and right = "individually" + or + wrong = "indpendent" and right = "independent" + or + wrong = "indpendently" and right = "independently" + or + wrong = "indulgue" and right = "indulge" + or + wrong = "indutrial" and right = "industrial" + or + wrong = "indviduals" and right = "individuals" + or + wrong = "inefficienty" and right = "inefficiently" + or + wrong = "inevatible" and right = "inevitable" + or + wrong = "inevitible" and right = "inevitable" + or + wrong = "inevititably" and right = "inevitably" + or + wrong = "infalability" and right = "infallibility" + or + wrong = "infallable" and right = "infallible" + or + wrong = "infectuous" and right = "infectious" + or + wrong = "infered" and right = "inferred" + or + wrong = "infilitrate" and right = "infiltrate" + or + wrong = "infilitrated" and right = "infiltrated" + or + wrong = "infilitration" and right = "infiltration" + or + wrong = "infinit" and right = "infinite" + or + wrong = "inflamation" and right = "inflammation" + or + wrong = "influencial" and right = "influential" + or + wrong = "influented" and right = "influenced" + or + wrong = "infomation" and right = "information" + or + wrong = "informtion" and right = "information" + or + wrong = "infrantryman" and right = "infantryman" + or + wrong = "infrigement" and right = "infringement" + or + wrong = "ingenius" and right = "ingenious" + or + wrong = "ingreediants" and right = "ingredients" + or + wrong = "inhabitans" and right = "inhabitants" + or + wrong = "inherantly" and right = "inherently" + or + wrong = "inheritage" and right = "heritage" + or + wrong = "inheritage" and right = "inheritance" + or + wrong = "inheritence" and right = "inheritance" + or + wrong = "inital" and right = "initial" + or + wrong = "initalize" and right = "initialize" + or + wrong = "initally" and right = "initially" + or + wrong = "initation" and right = "initiation" + or + wrong = "initiaitive" and right = "initiative" + or + wrong = "inlcuding" and right = "including" + or + wrong = "inmigrant" and right = "immigrant" + or + wrong = "inmigrants" and right = "immigrants" + or + wrong = "innoculated" and right = "inoculated" + or + wrong = "inocence" and right = "innocence" + or + wrong = "inofficial" and right = "unofficial" + or + wrong = "inot" and right = "into" + or + wrong = "inpeach" and right = "impeach" + or + wrong = "inpending" and right = "impending" + or + wrong = "inpenetrable" and right = "impenetrable" + or + wrong = "inpolite" and right = "impolite" + or + wrong = "inprisonment" and right = "imprisonment" + or + wrong = "inproving" and right = "improving" + or + wrong = "insectiverous" and right = "insectivorous" + or + wrong = "insensative" and right = "insensitive" + or + wrong = "inseperable" and right = "inseparable" + or + wrong = "insistance" and right = "insistence" + or + wrong = "insitution" and right = "institution" + or + wrong = "insitutions" and right = "institutions" + or + wrong = "inspite" and right = "inspire" + or + wrong = "instade" and right = "instead" + or + wrong = "instatance" and right = "instance" + or + wrong = "institue" and right = "institute" + or + wrong = "instuction" and right = "instruction" + or + wrong = "instuments" and right = "instruments" + or + wrong = "instutionalized" and right = "institutionalized" + or + wrong = "instutions" and right = "intuitions" + or + wrong = "insurence" and right = "insurance" + or + wrong = "intelectual" and right = "intellectual" + or + wrong = "inteligence" and right = "intelligence" + or + wrong = "inteligent" and right = "intelligent" + or + wrong = "intenational" and right = "international" + or + wrong = "intented" and right = "indented" + or + wrong = "intented" and right = "intended" + or + wrong = "intepretation" and right = "interpretation" + or + wrong = "intepretator" and right = "interpretor" + or + wrong = "interational" and right = "international" + or + wrong = "interbread" and right = "interbred" + or + wrong = "interbread" and right = "interbreed" + or + wrong = "interchangable" and right = "interchangeable" + or + wrong = "interchangably" and right = "interchangeably" + or + wrong = "intercontinential" and right = "intercontinental" + or + wrong = "intercontinetal" and right = "intercontinental" + or + wrong = "intered" and right = "interned" + or + wrong = "intered" and right = "interred" + or + wrong = "interelated" and right = "interrelated" + or + wrong = "interferance" and right = "interference" + or + wrong = "interfereing" and right = "interfering" + or + wrong = "intergrated" and right = "integrated" + or + wrong = "intergration" and right = "integration" + or + wrong = "interm" and right = "interim" + or + wrong = "internation" and right = "international" + or + wrong = "interpet" and right = "interpret" + or + wrong = "interrim" and right = "interim" + or + wrong = "interrugum" and right = "interregnum" + or + wrong = "intertaining" and right = "entertaining" + or + wrong = "interupt" and right = "interrupt" + or + wrong = "intervines" and right = "intervenes" + or + wrong = "intevene" and right = "intervene" + or + wrong = "intial" and right = "initial" + or + wrong = "intialize" and right = "initialize" + or + wrong = "intialized" and right = "initialized" + or + wrong = "intially" and right = "initially" + or + wrong = "intrduced" and right = "introduced" + or + wrong = "intrest" and right = "interest" + or + wrong = "introdued" and right = "introduced" + or + wrong = "intruduced" and right = "introduced" + or + wrong = "intrument" and right = "instrument" + or + wrong = "intrumental" and right = "instrumental" + or + wrong = "intruments" and right = "instruments" + or + wrong = "intrusted" and right = "entrusted" + or + wrong = "intutive" and right = "intuitive" + or + wrong = "intutively" and right = "intuitively" + or + wrong = "inudstry" and right = "industry" + or + wrong = "inumerable" and right = "enumerable" + or + wrong = "inumerable" and right = "innumerable" + or + wrong = "inventer" and right = "inventor" + or + wrong = "invertibrates" and right = "invertebrates" + or + wrong = "investingate" and right = "investigate" + or + wrong = "involvment" and right = "involvement" + or + wrong = "irelevent" and right = "irrelevant" + or + wrong = "iresistable" and right = "irresistible" + or + wrong = "iresistably" and right = "irresistibly" + or + wrong = "iresistible" and right = "irresistible" + or + wrong = "iresistibly" and right = "irresistibly" + or + wrong = "iritable" and right = "irritable" + or + wrong = "iritated" and right = "irritated" + or + wrong = "ironicly" and right = "ironically" + or + wrong = "irregardless" and right = "regardless" + or + wrong = "irrelevent" and right = "irrelevant" + or + wrong = "irreplacable" and right = "irreplaceable" + or + wrong = "irresistable" and right = "irresistible" + or + wrong = "irresistably" and right = "irresistibly" + or + wrong = "israelies" and right = "israelis" + or + wrong = "issueing" and right = "issuing" + or + wrong = "itnroduced" and right = "introduced" + or + wrong = "iunior" and right = "junior" + or + wrong = "iwll" and right = "will" + or + wrong = "iwth" and right = "with" + or + wrong = "janurary" and right = "january" + or + wrong = "januray" and right = "january" + or + wrong = "japanes" and right = "japanese" + or + wrong = "jaques" and right = "jacques" + or + wrong = "jeapardy" and right = "jeopardy" + or + wrong = "jewllery" and right = "jewellery" + or + wrong = "johanine" and right = "johannine" + or + wrong = "jorunal" and right = "journal" + or + wrong = "jospeh" and right = "joseph" + or + wrong = "jouney" and right = "journey" + or + wrong = "journied" and right = "journeyed" + or + wrong = "journies" and right = "journeys" + or + wrong = "jstu" and right = "just" + or + wrong = "jsut" and right = "just" + or + wrong = "juadaism" and right = "judaism" + or + wrong = "juadism" and right = "judaism" + or + wrong = "judical" and right = "judicial" + or + wrong = "judisuary" and right = "judiciary" + or + wrong = "juducial" and right = "judicial" + or + wrong = "juristiction" and right = "jurisdiction" + or + wrong = "juristictions" and right = "jurisdictions" + or + wrong = "kindergarden" and right = "kindergarten" + or + wrong = "klenex" and right = "kleenex" + or + wrong = "knifes" and right = "knives" + or + wrong = "knive" and right = "knife" + or + wrong = "knowlege" and right = "knowledge" + or + wrong = "knowlegeable" and right = "knowledgeable" + or + wrong = "knwo" and right = "know" + or + wrong = "knwos" and right = "knows" + or + wrong = "konw" and right = "know" + or + wrong = "konws" and right = "knows" + or + wrong = "kwno" and right = "know" + or + wrong = "labatory" and right = "laboratory" + or + wrong = "labatory" and right = "lavatory" + or + wrong = "labled" and right = "labeled" + or + wrong = "labled" and right = "labelled" + or + wrong = "labratory" and right = "laboratory" + or + wrong = "laguage" and right = "language" + or + wrong = "laguages" and right = "languages" + or + wrong = "langage" and right = "language" + or + wrong = "langauge" and right = "language" + or + wrong = "larg" and right = "large" + or + wrong = "largst" and right = "largest" + or + wrong = "larrry" and right = "larry" + or + wrong = "lastr" and right = "last" + or + wrong = "lattitude" and right = "latitude" + or + wrong = "launchs" and right = "launch" + or + wrong = "launchs" and right = "launches" + or + wrong = "launhed" and right = "launched" + or + wrong = "lavae" and right = "larvae" + or + wrong = "layed" and right = "laid" + or + wrong = "lazyness" and right = "laziness" + or + wrong = "leage" and right = "league" + or + wrong = "leanr" and right = "lean" + or + wrong = "leanr" and right = "leaner" + or + wrong = "leanr" and right = "learn" + or + wrong = "leathal" and right = "lethal" + or + wrong = "lefted" and right = "left" + or + wrong = "legitamate" and right = "legitimate" + or + wrong = "legitmate" and right = "legitimate" + or + wrong = "leibnitz" and right = "leibniz" + or + wrong = "lengh" and right = "length" + or + wrong = "lenght" and right = "length" + or + wrong = "lengt" and right = "length" + or + wrong = "lenth" and right = "length" + or + wrong = "leran" and right = "learn" + or + wrong = "lerans" and right = "learns" + or + wrong = "leutenant" and right = "lieutenant" + or + wrong = "levetate" and right = "levitate" + or + wrong = "levetated" and right = "levitated" + or + wrong = "levetates" and right = "levitates" + or + wrong = "levetating" and right = "levitating" + or + wrong = "levle" and right = "level" + or + wrong = "liasion" and right = "liaison" + or + wrong = "liason" and right = "liaison" + or + wrong = "liasons" and right = "liaisons" + or + wrong = "libaries" and right = "libraries" + or + wrong = "libary" and right = "library" + or + wrong = "libell" and right = "libel" + or + wrong = "libguistic" and right = "linguistic" + or + wrong = "libguistics" and right = "linguistics" + or + wrong = "libitarianisn" and right = "libertarianism" + or + wrong = "lible" and right = "liable" + or + wrong = "lible" and right = "libel" + or + wrong = "lieing" and right = "lying" + or + wrong = "liek" and right = "like" + or + wrong = "liekd" and right = "liked" + or + wrong = "liesure" and right = "leisure" + or + wrong = "lieuenant" and right = "lieutenant" + or + wrong = "lieved" and right = "lived" + or + wrong = "liftime" and right = "lifetime" + or + wrong = "likelyhood" and right = "likelihood" + or + wrong = "linnaena" and right = "linnaean" + or + wrong = "lippizaner" and right = "lipizzaner" + or + wrong = "liquify" and right = "liquefy" + or + wrong = "liscense" and right = "licence" + or + wrong = "liscense" and right = "license" + or + wrong = "lisence" and right = "licence" + or + wrong = "lisence" and right = "license" + or + wrong = "lisense" and right = "licence" + or + wrong = "lisense" and right = "license" + or + wrong = "listners" and right = "listeners" + or + wrong = "litature" and right = "literature" + or + wrong = "literaly" and right = "literally" + or + wrong = "literture" and right = "literature" + or + wrong = "littel" and right = "little" + or + wrong = "litterally" and right = "literally" + or + wrong = "liuke" and right = "like" + or + wrong = "livley" and right = "lively" + or + wrong = "lmits" and right = "limits" + or + wrong = "loev" and right = "love" + or + wrong = "lonelyness" and right = "loneliness" + or + wrong = "longitudonal" and right = "longitudinal" + or + wrong = "lonley" and right = "lonely" + or + wrong = "lonly" and right = "lonely" + or + wrong = "lonly" and right = "only" + or + wrong = "loosing" and right = "losing" + or + wrong = "lotharingen" and right = "lothringen" + or + wrong = "lsat" and right = "last" + or + wrong = "lukid" and right = "likud" + or + wrong = "lveo" and right = "love" + or + wrong = "lvoe" and right = "love" + or + wrong = "lybia" and right = "libya" + or + wrong = "maching" and right = "machine" + or + wrong = "maching" and right = "marching" + or + wrong = "maching" and right = "matching" + or + wrong = "mackeral" and right = "mackerel" + or + wrong = "magasine" and right = "magazine" + or + wrong = "magincian" and right = "magician" + or + wrong = "magisine" and right = "magazine" + or + wrong = "magizine" and right = "magazine" + or + wrong = "magnificient" and right = "magnificent" + or + wrong = "magolia" and right = "magnolia" + or + wrong = "mailny" and right = "mainly" + or + wrong = "maintainance" and right = "maintenance" + or + wrong = "maintainence" and right = "maintenance" + or + wrong = "maintance" and right = "maintenance" + or + wrong = "maintenence" and right = "maintenance" + or + wrong = "maintinaing" and right = "maintaining" + or + wrong = "maintioned" and right = "mentioned" + or + wrong = "majoroty" and right = "majority" + or + wrong = "maked" and right = "made" + or + wrong = "maked" and right = "marked" + or + wrong = "makse" and right = "makes" + or + wrong = "malcom" and right = "malcolm" + or + wrong = "maltesian" and right = "maltese" + or + wrong = "mamal" and right = "mammal" + or + wrong = "mamalian" and right = "mammalian" + or + wrong = "managable" and right = "manageable" + or + wrong = "managable" and right = "manageably" + or + wrong = "managment" and right = "management" + or + wrong = "maneouvre" and right = "manoeuvre" + or + wrong = "maneouvred" and right = "manoeuvred" + or + wrong = "maneouvres" and right = "manoeuvres" + or + wrong = "maneouvring" and right = "manoeuvring" + or + wrong = "manisfestations" and right = "manifestations" + or + wrong = "manoeuverability" and right = "maneuverability" + or + wrong = "manouver" and right = "maneuver" + or + wrong = "manouver" and right = "manoeuvre" + or + wrong = "manouverability" and right = "maneuverability" + or + wrong = "manouverability" and right = "manoeuverability" + or + wrong = "manouverability" and right = "manoeuvrability" + or + wrong = "manouverable" and right = "maneuverable" + or + wrong = "manouverable" and right = "manoeuvrable" + or + wrong = "manouvers" and right = "maneuvers" + or + wrong = "manouvers" and right = "manoeuvres" + or + wrong = "mantained" and right = "maintained" + or + wrong = "manuever" and right = "maneuver" + or + wrong = "manuever" and right = "manoeuvre" + or + wrong = "manuevers" and right = "maneuvers" + or + wrong = "manuevers" and right = "manoeuvres" + or + wrong = "manufacturedd" and right = "manufactured" + or + wrong = "manufature" and right = "manufacture" + or + wrong = "manufatured" and right = "manufactured" + or + wrong = "manufaturing" and right = "manufacturing" + or + wrong = "manuver" and right = "maneuver" + or + wrong = "mariage" and right = "marriage" + or + wrong = "marjority" and right = "majority" + or + wrong = "markes" and right = "marks" + or + wrong = "marketting" and right = "marketing" + or + wrong = "marmelade" and right = "marmalade" + or + wrong = "marrage" and right = "marriage" + or + wrong = "marraige" and right = "marriage" + or + wrong = "marrtyred" and right = "martyred" + or + wrong = "marryied" and right = "married" + or + wrong = "massachussets" and right = "massachusetts" + or + wrong = "massachussetts" and right = "massachusetts" + or + wrong = "masterbation" and right = "masturbation" + or + wrong = "mataphysical" and right = "metaphysical" + or + wrong = "materalists" and right = "materialist" + or + wrong = "mathamatics" and right = "mathematics" + or + wrong = "mathematican" and right = "mathematician" + or + wrong = "mathematicas" and right = "mathematics" + or + wrong = "matheticians" and right = "mathematicians" + or + wrong = "mathmatically" and right = "mathematically" + or + wrong = "mathmatician" and right = "mathematician" + or + wrong = "mathmaticians" and right = "mathematicians" + or + wrong = "mccarthyst" and right = "mccarthyist" + or + wrong = "mchanics" and right = "mechanics" + or + wrong = "meaninng" and right = "meaning" + or + wrong = "mear" and right = "mare" + or + wrong = "mear" and right = "mere" + or + wrong = "mear" and right = "wear" + or + wrong = "mechandise" and right = "merchandise" + or + wrong = "medacine" and right = "medicine" + or + wrong = "medeival" and right = "medieval" + or + wrong = "medevial" and right = "medieval" + or + wrong = "mediciney" and right = "mediciny" + or + wrong = "medievel" and right = "medieval" + or + wrong = "mediterainnean" and right = "mediterranean" + or + wrong = "mediteranean" and right = "mediterranean" + or + wrong = "meerkrat" and right = "meerkat" + or + wrong = "melieux" and right = "milieux" + or + wrong = "membranaphone" and right = "membranophone" + or + wrong = "memeber" and right = "member" + or + wrong = "menally" and right = "mentally" + or + wrong = "meranda" and right = "miranda" + or + wrong = "meranda" and right = "veranda" + or + wrong = "mercentile" and right = "mercantile" + or + wrong = "mesage" and right = "message" + or + wrong = "messanger" and right = "messenger" + or + wrong = "messenging" and right = "messaging" + or + wrong = "messsage" and right = "message" + or + wrong = "metalic" and right = "metallic" + or + wrong = "metalurgic" and right = "metallurgic" + or + wrong = "metalurgical" and right = "metallurgical" + or + wrong = "metalurgy" and right = "metallurgy" + or + wrong = "metamorphysis" and right = "metamorphosis" + or + wrong = "metaphoricial" and right = "metaphorical" + or + wrong = "meterologist" and right = "meteorologist" + or + wrong = "meterology" and right = "meteorology" + or + wrong = "methaphor" and right = "metaphor" + or + wrong = "methaphors" and right = "metaphors" + or + wrong = "michagan" and right = "michigan" + or + wrong = "micoscopy" and right = "microscopy" + or + wrong = "midwifes" and right = "midwives" + or + wrong = "mileau" and right = "milieu" + or + wrong = "milennia" and right = "millennia" + or + wrong = "milennium" and right = "millennium" + or + wrong = "mileu" and right = "milieu" + or + wrong = "miliary" and right = "military" + or + wrong = "miligram" and right = "milligram" + or + wrong = "milion" and right = "million" + or + wrong = "miliraty" and right = "military" + or + wrong = "millenia" and right = "millennia" + or + wrong = "millenial" and right = "millennial" + or + wrong = "millenialism" and right = "millennialism" + or + wrong = "millenium" and right = "millennium" + or + wrong = "millepede" and right = "millipede" + or + wrong = "millioniare" and right = "millionaire" + or + wrong = "millitant" and right = "militant" + or + wrong = "millitary" and right = "military" + or + wrong = "millon" and right = "million" + or + wrong = "miltary" and right = "military" + or + wrong = "minature" and right = "miniature" + or + wrong = "minerial" and right = "mineral" + or + wrong = "ministery" and right = "ministry" + or + wrong = "minsitry" and right = "ministry" + or + wrong = "minstries" and right = "ministries" + or + wrong = "minstry" and right = "ministry" + or + wrong = "minumum" and right = "minimum" + or + wrong = "mirrorred" and right = "mirrored" + or + wrong = "miscelaneous" and right = "miscellaneous" + or + wrong = "miscellanious" and right = "miscellaneous" + or + wrong = "miscellanous" and right = "miscellaneous" + or + wrong = "mischeivous" and right = "mischievous" + or + wrong = "mischevious" and right = "mischievous" + or + wrong = "mischievious" and right = "mischievous" + or + wrong = "misdameanor" and right = "misdemeanor" + or + wrong = "misdameanors" and right = "misdemeanors" + or + wrong = "misdemenor" and right = "misdemeanor" + or + wrong = "misdemenors" and right = "misdemeanors" + or + wrong = "misfourtunes" and right = "misfortunes" + or + wrong = "misile" and right = "missile" + or + wrong = "misouri" and right = "missouri" + or + wrong = "mispell" and right = "misspell" + or + wrong = "mispelled" and right = "misspelled" + or + wrong = "mispelling" and right = "misspelling" + or + wrong = "missen" and right = "mizzen" + or + wrong = "missisipi" and right = "mississippi" + or + wrong = "missisippi" and right = "mississippi" + or + wrong = "missle" and right = "missile" + or + wrong = "missonary" and right = "missionary" + or + wrong = "misterious" and right = "mysterious" + or + wrong = "mistery" and right = "mystery" + or + wrong = "misteryous" and right = "mysterious" + or + wrong = "mkae" and right = "make" + or + wrong = "mkaes" and right = "makes" + or + wrong = "mkaing" and right = "making" + or + wrong = "mkea" and right = "make" + or + wrong = "moderm" and right = "modem" + or + wrong = "modle" and right = "model" + or + wrong = "moent" and right = "moment" + or + wrong = "moeny" and right = "money" + or + wrong = "mohammedans" and right = "muslims" + or + wrong = "moil" and right = "mohel" + or + wrong = "moil" and right = "soil" + or + wrong = "moleclues" and right = "molecules" + or + wrong = "momento" and right = "memento" + or + wrong = "monestaries" and right = "monasteries" + or + wrong = "monestary" and right = "monastery" + or + wrong = "monestary" and right = "monetary" + or + wrong = "monickers" and right = "monikers" + or + wrong = "monolite" and right = "monolithic" + or + wrong = "monserrat" and right = "montserrat" + or + wrong = "montains" and right = "mountains" + or + wrong = "montanous" and right = "mountainous" + or + wrong = "montnana" and right = "montana" + or + wrong = "monts" and right = "months" + or + wrong = "montypic" and right = "monotypic" + or + wrong = "moreso" and right = "more" + or + wrong = "morgage" and right = "mortgage" + or + wrong = "morisette" and right = "morissette" + or + wrong = "morrisette" and right = "morissette" + or + wrong = "morroccan" and right = "moroccan" + or + wrong = "morrocco" and right = "morocco" + or + wrong = "morroco" and right = "morocco" + or + wrong = "mortage" and right = "mortgage" + or + wrong = "mosture" and right = "moisture" + or + wrong = "motiviated" and right = "motivated" + or + wrong = "mounth" and right = "month" + or + wrong = "movei" and right = "movie" + or + wrong = "movment" and right = "movement" + or + wrong = "mroe" and right = "more" + or + wrong = "mucuous" and right = "mucous" + or + wrong = "muder" and right = "murder" + or + wrong = "mudering" and right = "murdering" + or + wrong = "muhammadan" and right = "muslim" + or + wrong = "multicultralism" and right = "multiculturalism" + or + wrong = "multipled" and right = "multiplied" + or + wrong = "multiplers" and right = "multipliers" + or + wrong = "munbers" and right = "numbers" + or + wrong = "muncipalities" and right = "municipalities" + or + wrong = "muncipality" and right = "municipality" + or + wrong = "munnicipality" and right = "municipality" + or + wrong = "muscels" and right = "muscles" + or + wrong = "muscels" and right = "mussels" + or + wrong = "muscial" and right = "musical" + or + wrong = "muscician" and right = "musician" + or + wrong = "muscicians" and right = "musicians" + or + wrong = "mutiliated" and right = "mutilated" + or + wrong = "mutiple" and right = "multiple" + or + wrong = "myraid" and right = "myriad" + or + wrong = "mysef" and right = "myself" + or + wrong = "mysogynist" and right = "misogynist" + or + wrong = "mysogyny" and right = "misogyny" + or + wrong = "mysterous" and right = "mysterious" + or + wrong = "mythraic" and right = "mithraic" + or + wrong = "naieve" and right = "naive" + or + wrong = "naploeon" and right = "napoleon" + or + wrong = "napolean" and right = "napoleon" + or + wrong = "napoleonian" and right = "napoleonic" + or + wrong = "naturaly" and right = "naturally" + or + wrong = "naturely" and right = "naturally" + or + wrong = "naturual" and right = "natural" + or + wrong = "naturually" and right = "naturally" + or + wrong = "nazereth" and right = "nazareth" + or + wrong = "neccesarily" and right = "necessarily" + or + wrong = "neccesary" and right = "necessary" + or + wrong = "neccessarily" and right = "necessarily" + or + wrong = "neccessary" and right = "necessary" + or + wrong = "neccessities" and right = "necessities" + or + wrong = "necesarily" and right = "necessarily" + or + wrong = "necesary" and right = "necessary" + or + wrong = "necessiate" and right = "necessitate" + or + wrong = "neglible" and right = "negligible" + or + wrong = "negligable" and right = "negligible" + or + wrong = "negociate" and right = "negotiate" + or + wrong = "negociation" and right = "negotiation" + or + wrong = "negociations" and right = "negotiations" + or + wrong = "negotation" and right = "negotiation" + or + wrong = "neice" and right = "nice" + or + wrong = "neice" and right = "niece" + or + wrong = "neigborhood" and right = "neighborhood" + or + wrong = "neigbour" and right = "neighbor" + or + wrong = "neigbour" and right = "neighbour" + or + wrong = "neigbourhood" and right = "neighbourhood" + or + wrong = "neigbouring" and right = "neighboring" + or + wrong = "neigbouring" and right = "neighbouring" + or + wrong = "neigbours" and right = "neighbors" + or + wrong = "neigbours" and right = "neighbours" + or + wrong = "neolitic" and right = "neolithic" + or + wrong = "nessasarily" and right = "necessarily" + or + wrong = "nessecary" and right = "necessary" + or + wrong = "nestin" and right = "nesting" + or + wrong = "neverthless" and right = "nevertheless" + or + wrong = "newletters" and right = "newsletters" + or + wrong = "nickle" and right = "nickel" + or + wrong = "nightime" and right = "nighttime" + or + wrong = "nineth" and right = "ninth" + or + wrong = "ninteenth" and right = "nineteenth" + or + wrong = "ninty" and right = "ninety" + or + wrong = "nkow" and right = "know" + or + wrong = "nkwo" and right = "know" + or + wrong = "nmae" and right = "name" + or + wrong = "noncombatents" and right = "noncombatants" + or + wrong = "nonsence" and right = "nonsense" + or + wrong = "nontheless" and right = "nonetheless" + or + wrong = "norhern" and right = "northern" + or + wrong = "northen" and right = "northern" + or + wrong = "northereastern" and right = "northeastern" + or + wrong = "notabley" and right = "notably" + or + wrong = "noteable" and right = "notable" + or + wrong = "noteably" and right = "notably" + or + wrong = "noteriety" and right = "notoriety" + or + wrong = "noth" and right = "north" + or + wrong = "nothern" and right = "northern" + or + wrong = "noticable" and right = "noticeable" + or + wrong = "noticably" and right = "noticeably" + or + wrong = "notications" and right = "notifications" + or + wrong = "noticeing" and right = "noticing" + or + wrong = "noticible" and right = "noticeable" + or + wrong = "notwhithstanding" and right = "notwithstanding" + or + wrong = "noveau" and right = "nouveau" + or + wrong = "novermber" and right = "november" + or + wrong = "nowdays" and right = "nowadays" + or + wrong = "nowe" and right = "now" + or + wrong = "nto" and right = "not" + or + wrong = "nubmer" and right = "number" + or + wrong = "nucular" and right = "nuclear" + or + wrong = "nuculear" and right = "nuclear" + or + wrong = "nuisanse" and right = "nuisance" + or + wrong = "nullabour" and right = "nullarbor" + or + wrong = "numberous" and right = "numerous" + or + wrong = "nuremburg" and right = "nuremberg" + or + wrong = "nusance" and right = "nuisance" + or + wrong = "nutritent" and right = "nutrient" + or + wrong = "nutritents" and right = "nutrients" + or + wrong = "nuturing" and right = "nurturing" + or + wrong = "obect" and right = "object" + or + wrong = "obediance" and right = "obedience" + or + wrong = "obediant" and right = "obedient" + or + wrong = "obejct" and right = "object" + or + wrong = "obession" and right = "obsession" + or + wrong = "obssessed" and right = "obsessed" + or + wrong = "obstacal" and right = "obstacle" + or + wrong = "obstancles" and right = "obstacles" + or + wrong = "obstruced" and right = "obstructed" + or + wrong = "ocasion" and right = "occasion" + or + wrong = "ocasional" and right = "occasional" + or + wrong = "ocasionally" and right = "occasionally" + or + wrong = "ocasionaly" and right = "occasionally" + or + wrong = "ocasioned" and right = "occasioned" + or + wrong = "ocasions" and right = "occasions" + or + wrong = "ocassion" and right = "occasion" + or + wrong = "ocassional" and right = "occasional" + or + wrong = "ocassionally" and right = "occasionally" + or + wrong = "ocassionaly" and right = "occasionally" + or + wrong = "ocassioned" and right = "occasioned" + or + wrong = "ocassions" and right = "occasions" + or + wrong = "occaison" and right = "occasion" + or + wrong = "occassion" and right = "occasion" + or + wrong = "occassional" and right = "occasional" + or + wrong = "occassionally" and right = "occasionally" + or + wrong = "occassionaly" and right = "occasionally" + or + wrong = "occassioned" and right = "occasioned" + or + wrong = "occassions" and right = "occasions" + or + wrong = "occationally" and right = "occasionally" + or + wrong = "occour" and right = "occur" + or + wrong = "occurance" and right = "occurrence" + or + wrong = "occurances" and right = "occurrences" + or + wrong = "occured" and right = "occurred" + or + wrong = "occurence" and right = "occurrence" + or + wrong = "occurences" and right = "occurrences" + or + wrong = "occuring" and right = "occurring" + or + wrong = "occurr" and right = "occur" + or + wrong = "occurrance" and right = "occurrence" + or + wrong = "occurrances" and right = "occurrences" + or + wrong = "octohedra" and right = "octahedra" + or + wrong = "octohedral" and right = "octahedral" + or + wrong = "octohedron" and right = "octahedron" + or + wrong = "ocuntries" and right = "countries" + or + wrong = "ocuntry" and right = "country" + or + wrong = "ocurr" and right = "occur" + or + wrong = "ocurrance" and right = "occurrence" + or + wrong = "ocurred" and right = "occurred" + or + wrong = "ocurrence" and right = "occurrence" + or + wrong = "offcers" and right = "officers" + or + wrong = "offcially" and right = "officially" + or + wrong = "offereings" and right = "offerings" + or + wrong = "offical" and right = "official" + or + wrong = "offically" and right = "officially" + or + wrong = "officals" and right = "officials" + or + wrong = "officaly" and right = "officially" + or + wrong = "officialy" and right = "officially" + or + wrong = "offred" and right = "offered" + or + wrong = "oftenly" and right = "often" + or + wrong = "oging" and right = "going" + or + wrong = "oging" and right = "ogling" + or + wrong = "oject" and right = "object" + or + wrong = "omision" and right = "omission" + or + wrong = "omited" and right = "omitted" + or + wrong = "omiting" and right = "omitting" + or + wrong = "omlette" and right = "omelette" + or + wrong = "ommision" and right = "omission" + or + wrong = "ommited" and right = "omitted" + or + wrong = "ommiting" and right = "omitting" + or + wrong = "ommitted" and right = "omitted" + or + wrong = "ommitting" and right = "omitting" + or + wrong = "omniverous" and right = "omnivorous" + or + wrong = "omniverously" and right = "omnivorously" + or + wrong = "omre" and right = "more" + or + wrong = "onot" and right = "not" + or + wrong = "onot" and right = "note" + or + wrong = "onyl" and right = "only" + or + wrong = "openess" and right = "openness" + or + wrong = "oponent" and right = "opponent" + or + wrong = "oportunity" and right = "opportunity" + or + wrong = "opose" and right = "oppose" + or + wrong = "oposite" and right = "opposite" + or + wrong = "oposition" and right = "opposition" + or + wrong = "oppenly" and right = "openly" + or + wrong = "oppinion" and right = "opinion" + or + wrong = "opponant" and right = "opponent" + or + wrong = "oppononent" and right = "opponent" + or + wrong = "oppositition" and right = "opposition" + or + wrong = "oppossed" and right = "opposed" + or + wrong = "opprotunity" and right = "opportunity" + or + wrong = "opression" and right = "oppression" + or + wrong = "opressive" and right = "oppressive" + or + wrong = "opthalmic" and right = "ophthalmic" + or + wrong = "opthalmologist" and right = "ophthalmologist" + or + wrong = "opthalmology" and right = "ophthalmology" + or + wrong = "opthamologist" and right = "ophthalmologist" + or + wrong = "optmizations" and right = "optimizations" + or + wrong = "optomism" and right = "optimism" + or + wrong = "orded" and right = "ordered" + or + wrong = "organim" and right = "organism" + or + wrong = "organistion" and right = "organisation" + or + wrong = "organiztion" and right = "organization" + or + wrong = "orgin" and right = "organ" + or + wrong = "orgin" and right = "origin" + or + wrong = "orginal" and right = "original" + or + wrong = "orginally" and right = "originally" + or + wrong = "orginize" and right = "organise" + or + wrong = "oridinarily" and right = "ordinarily" + or + wrong = "origanaly" and right = "originally" + or + wrong = "originall" and right = "original" + or + wrong = "originall" and right = "originally" + or + wrong = "originaly" and right = "originally" + or + wrong = "originially" and right = "originally" + or + wrong = "originnally" and right = "originally" + or + wrong = "origional" and right = "original" + or + wrong = "orignally" and right = "originally" + or + wrong = "orignially" and right = "originally" + or + wrong = "otehr" and right = "other" + or + wrong = "oublisher" and right = "publisher" + or + wrong = "ouevre" and right = "oeuvre" + or + wrong = "ouput" and right = "output" + or + wrong = "oustanding" and right = "outstanding" + or + wrong = "overriden" and right = "overridden" + or + wrong = "overshaddowed" and right = "overshadowed" + or + wrong = "overwelming" and right = "overwhelming" + or + wrong = "overwheliming" and right = "overwhelming" + or + wrong = "owrk" and right = "work" + or + wrong = "owudl" and right = "would" + or + wrong = "oxigen" and right = "oxygen" + or + wrong = "oximoron" and right = "oxymoron" + or + wrong = "p0enis" and right = "penis" + or + wrong = "paide" and right = "paid" + or + wrong = "paitience" and right = "patience" + or + wrong = "palce" and right = "palace" + or + wrong = "palce" and right = "place" + or + wrong = "paleolitic" and right = "paleolithic" + or + wrong = "paliamentarian" and right = "parliamentarian" + or + wrong = "palistian" and right = "palestinian" + or + wrong = "palistinian" and right = "palestinian" + or + wrong = "palistinians" and right = "palestinians" + or + wrong = "pallete" and right = "palette" + or + wrong = "pamflet" and right = "pamphlet" + or + wrong = "pamplet" and right = "pamphlet" + or + wrong = "pantomine" and right = "pantomime" + or + wrong = "papanicalou" and right = "papanicolaou" + or + wrong = "paralel" and right = "parallel" + or + wrong = "paralell" and right = "parallel" + or + wrong = "paralelly" and right = "parallelly" + or + wrong = "paralely" and right = "parallelly" + or + wrong = "parallely" and right = "parallelly" + or + wrong = "paramater" and right = "parameter" + or + wrong = "paramters" and right = "parameters" + or + wrong = "parametarized" and right = "parameterized" + or + wrong = "paranthesis" and right = "parenthesis" + or + wrong = "paraphenalia" and right = "paraphernalia" + or + wrong = "parellels" and right = "parallels" + or + wrong = "parisitic" and right = "parasitic" + or + wrong = "parituclar" and right = "particular" + or + wrong = "parliment" and right = "parliament" + or + wrong = "parrakeets" and right = "parakeets" + or + wrong = "parralel" and right = "parallel" + or + wrong = "parrallel" and right = "parallel" + or + wrong = "parrallell" and right = "parallel" + or + wrong = "parrallelly" and right = "parallelly" + or + wrong = "parrallely" and right = "parallelly" + or + wrong = "partialy" and right = "partially" + or + wrong = "particually" and right = "particularly" + or + wrong = "particualr" and right = "particular" + or + wrong = "particuarly" and right = "particularly" + or + wrong = "particularily" and right = "particularly" + or + wrong = "particulary" and right = "particularly" + or + wrong = "pary" and right = "party" + or + wrong = "pased" and right = "passed" + or + wrong = "pasengers" and right = "passengers" + or + wrong = "passerbys" and right = "passersby" + or + wrong = "pasttime" and right = "pastime" + or + wrong = "pastural" and right = "pastoral" + or + wrong = "paticular" and right = "particular" + or + wrong = "pattented" and right = "patented" + or + wrong = "pavillion" and right = "pavilion" + or + wrong = "payed" and right = "paid" + or + wrong = "pblisher" and right = "publisher" + or + wrong = "pbulisher" and right = "publisher" + or + wrong = "peageant" and right = "pageant" + or + wrong = "peaple" and right = "people" + or + wrong = "peaples" and right = "peoples" + or + wrong = "peculure" and right = "peculiar" + or + wrong = "pedestrain" and right = "pedestrian" + or + wrong = "peformed" and right = "performed" + or + wrong = "peice" and right = "piece" + or + wrong = "peloponnes" and right = "peloponnesus" + or + wrong = "penatly" and right = "penalty" + or + wrong = "penerator" and right = "penetrator" + or + wrong = "penisula" and right = "peninsula" + or + wrong = "penisular" and right = "peninsular" + or + wrong = "penninsula" and right = "peninsula" + or + wrong = "penninsular" and right = "peninsular" + or + wrong = "pennisula" and right = "peninsula" + or + wrong = "pennyslvania" and right = "pennsylvania" + or + wrong = "pensinula" and right = "peninsula" + or + wrong = "pensle" and right = "pencil" + or + wrong = "peom" and right = "poem" + or + wrong = "peoms" and right = "poems" + or + wrong = "peopel" and right = "people" + or + wrong = "peopels" and right = "peoples" + or + wrong = "peotry" and right = "poetry" + or + wrong = "perade" and right = "parade" + or + wrong = "percepted" and right = "perceived" + or + wrong = "percieve" and right = "perceive" + or + wrong = "percieved" and right = "perceived" + or + wrong = "perenially" and right = "perennially" + or + wrong = "peretrator" and right = "perpetrator" + or + wrong = "perfomance" and right = "performance" + or + wrong = "perfomers" and right = "performers" + or + wrong = "performence" and right = "performance" + or + wrong = "performes" and right = "performed" + or + wrong = "performes" and right = "performs" + or + wrong = "perhasp" and right = "perhaps" + or + wrong = "perheaps" and right = "perhaps" + or + wrong = "perhpas" and right = "perhaps" + or + wrong = "peripathetic" and right = "peripatetic" + or + wrong = "peristent" and right = "persistent" + or + wrong = "perjery" and right = "perjury" + or + wrong = "perjorative" and right = "pejorative" + or + wrong = "permanant" and right = "permanent" + or + wrong = "permenant" and right = "permanent" + or + wrong = "permenantly" and right = "permanently" + or + wrong = "permissable" and right = "permissible" + or + wrong = "perogative" and right = "prerogative" + or + wrong = "peronal" and right = "personal" + or + wrong = "perosnality" and right = "personality" + or + wrong = "perpertrated" and right = "perpetrated" + or + wrong = "perphas" and right = "perhaps" + or + wrong = "perpindicular" and right = "perpendicular" + or + wrong = "persan" and right = "person" + or + wrong = "perseverence" and right = "perseverance" + or + wrong = "persistance" and right = "persistence" + or + wrong = "persistant" and right = "persistent" + or + wrong = "personel" and right = "personal" + or + wrong = "personel" and right = "personnel" + or + wrong = "personell" and right = "personnel" + or + wrong = "personnell" and right = "personnel" + or + wrong = "persuded" and right = "persuaded" + or + wrong = "persue" and right = "pursue" + or + wrong = "persued" and right = "pursued" + or + wrong = "persuing" and right = "pursuing" + or + wrong = "persuit" and right = "pursuit" + or + wrong = "persuits" and right = "pursuits" + or + wrong = "pertubation" and right = "perturbation" + or + wrong = "pertubations" and right = "perturbations" + or + wrong = "pessiary" and right = "pessary" + or + wrong = "petetion" and right = "petition" + or + wrong = "pharoah" and right = "pharaoh" + or + wrong = "phenomenom" and right = "phenomenon" + or + wrong = "phenomenonal" and right = "phenomenal" + or + wrong = "phenomenonly" and right = "phenomenally" + or + wrong = "phenomonenon" and right = "phenomenon" + or + wrong = "phenomonon" and right = "phenomenon" + or + wrong = "phenonmena" and right = "phenomena" + or + wrong = "philipines" and right = "philippines" + or + wrong = "philisopher" and right = "philosopher" + or + wrong = "philisophical" and right = "philosophical" + or + wrong = "philisophy" and right = "philosophy" + or + wrong = "phillipine" and right = "philippine" + or + wrong = "phillipines" and right = "philippines" + or + wrong = "phillippines" and right = "philippines" + or + wrong = "phillosophically" and right = "philosophically" + or + wrong = "philospher" and right = "philosopher" + or + wrong = "philosphies" and right = "philosophies" + or + wrong = "philosphy" and right = "philosophy" + or + wrong = "phonecian" and right = "phoenecian" + or + wrong = "phongraph" and right = "phonograph" + or + wrong = "phylosophical" and right = "philosophical" + or + wrong = "physicaly" and right = "physically" + or + wrong = "piblisher" and right = "publisher" + or + wrong = "pich" and right = "pitch" + or + wrong = "pilgrimmage" and right = "pilgrimage" + or + wrong = "pilgrimmages" and right = "pilgrimages" + or + wrong = "pinapple" and right = "pineapple" + or + wrong = "pinnaple" and right = "pineapple" + or + wrong = "pinoneered" and right = "pioneered" + or + wrong = "plagarism" and right = "plagiarism" + or + wrong = "planation" and right = "plantation" + or + wrong = "planed" and right = "planned" + or + wrong = "plantiff" and right = "plaintiff" + or + wrong = "plateu" and right = "plateau" + or + wrong = "plausable" and right = "plausible" + or + wrong = "playright" and right = "playwright" + or + wrong = "playwrite" and right = "playwright" + or + wrong = "playwrites" and right = "playwrights" + or + wrong = "pleasent" and right = "pleasant" + or + wrong = "plebicite" and right = "plebiscite" + or + wrong = "plesant" and right = "pleasant" + or + wrong = "poenis" and right = "penis" + or + wrong = "poeoples" and right = "peoples" + or + wrong = "poety" and right = "poetry" + or + wrong = "poisin" and right = "poison" + or + wrong = "polical" and right = "political" + or + wrong = "polinator" and right = "pollinator" + or + wrong = "polinators" and right = "pollinators" + or + wrong = "politican" and right = "politician" + or + wrong = "politicans" and right = "politicians" + or + wrong = "poltical" and right = "political" + or + wrong = "polute" and right = "pollute" + or + wrong = "poluted" and right = "polluted" + or + wrong = "polutes" and right = "pollutes" + or + wrong = "poluting" and right = "polluting" + or + wrong = "polution" and right = "pollution" + or + wrong = "polyphonyic" and right = "polyphonic" + or + wrong = "polysaccaride" and right = "polysaccharide" + or + wrong = "polysaccharid" and right = "polysaccharide" + or + wrong = "pomegranite" and right = "pomegranate" + or + wrong = "pomotion" and right = "promotion" + or + wrong = "poportional" and right = "proportional" + or + wrong = "popoulation" and right = "population" + or + wrong = "popularaty" and right = "popularity" + or + wrong = "populare" and right = "popular" + or + wrong = "populer" and right = "popular" + or + wrong = "porshan" and right = "portion" + or + wrong = "porshon" and right = "portion" + or + wrong = "portait" and right = "portrait" + or + wrong = "portayed" and right = "portrayed" + or + wrong = "portraing" and right = "portraying" + or + wrong = "portugese" and right = "portuguese" + or + wrong = "portuguease" and right = "portuguese" + or + wrong = "portugues" and right = "portuguese" + or + wrong = "posess" and right = "possess" + or + wrong = "posessed" and right = "possessed" + or + wrong = "posesses" and right = "possesses" + or + wrong = "posessing" and right = "possessing" + or + wrong = "posession" and right = "possession" + or + wrong = "posessions" and right = "possessions" + or + wrong = "posion" and right = "poison" + or + wrong = "positon" and right = "position" + or + wrong = "positon" and right = "positron" + or + wrong = "possable" and right = "possible" + or + wrong = "possably" and right = "possibly" + or + wrong = "posseses" and right = "possesses" + or + wrong = "possesing" and right = "possessing" + or + wrong = "possesion" and right = "possession" + or + wrong = "possessess" and right = "possesses" + or + wrong = "possibile" and right = "possible" + or + wrong = "possibilty" and right = "possibility" + or + wrong = "possiblility" and right = "possibility" + or + wrong = "possiblilty" and right = "possibility" + or + wrong = "possiblities" and right = "possibilities" + or + wrong = "possiblity" and right = "possibility" + or + wrong = "possition" and right = "position" + or + wrong = "postdam" and right = "potsdam" + or + wrong = "posthomous" and right = "posthumous" + or + wrong = "postion" and right = "position" + or + wrong = "postive" and right = "positive" + or + wrong = "potatos" and right = "potatoes" + or + wrong = "potrait" and right = "portrait" + or + wrong = "potrayed" and right = "portrayed" + or + wrong = "poulations" and right = "populations" + or + wrong = "poverful" and right = "powerful" + or + wrong = "poweful" and right = "powerful" + or + wrong = "powerfull" and right = "powerful" + or + wrong = "ppublisher" and right = "publisher" + or + wrong = "practial" and right = "practical" + or + wrong = "practially" and right = "practically" + or + wrong = "practicaly" and right = "practically" + or + wrong = "practicioner" and right = "practitioner" + or + wrong = "practicioners" and right = "practitioners" + or + wrong = "practicly" and right = "practically" + or + wrong = "practioner" and right = "practitioner" + or + wrong = "practioners" and right = "practitioners" + or + wrong = "prairy" and right = "prairie" + or + wrong = "prarie" and right = "prairie" + or + wrong = "praries" and right = "prairies" + or + wrong = "pratice" and right = "practice" + or + wrong = "preample" and right = "preamble" + or + wrong = "precedessor" and right = "predecessor" + or + wrong = "preceed" and right = "precede" + or + wrong = "preceeded" and right = "preceded" + or + wrong = "preceeding" and right = "preceding" + or + wrong = "preceeds" and right = "precedes" + or + wrong = "precendence" and right = "precedence" + or + wrong = "precentage" and right = "percentage" + or + wrong = "precice" and right = "precise" + or + wrong = "precisly" and right = "precisely" + or + wrong = "precurser" and right = "precursor" + or + wrong = "predecesors" and right = "predecessors" + or + wrong = "predicatble" and right = "predictable" + or + wrong = "predicitons" and right = "predictions" + or + wrong = "predomiantly" and right = "predominately" + or + wrong = "prefered" and right = "preferred" + or + wrong = "prefering" and right = "preferring" + or + wrong = "preferrably" and right = "preferably" + or + wrong = "pregancies" and right = "pregnancies" + or + wrong = "preiod" and right = "period" + or + wrong = "preliferation" and right = "proliferation" + or + wrong = "premeire" and right = "premiere" + or + wrong = "premeired" and right = "premiered" + or + wrong = "premillenial" and right = "premillennial" + or + wrong = "preminence" and right = "preeminence" + or + wrong = "premission" and right = "permission" + or + wrong = "premonasterians" and right = "premonstratensians" + or + wrong = "preocupation" and right = "preoccupation" + or + wrong = "prepair" and right = "prepare" + or + wrong = "prepartion" and right = "preparation" + or + wrong = "prepatory" and right = "preparatory" + or + wrong = "preperation" and right = "preparation" + or + wrong = "preperations" and right = "preparations" + or + wrong = "preriod" and right = "period" + or + wrong = "presedential" and right = "presidential" + or + wrong = "presense" and right = "presence" + or + wrong = "presidenital" and right = "presidential" + or + wrong = "presidental" and right = "presidential" + or + wrong = "presitgious" and right = "prestigious" + or + wrong = "prespective" and right = "perspective" + or + wrong = "prestigeous" and right = "prestigious" + or + wrong = "prestigous" and right = "prestigious" + or + wrong = "presumabely" and right = "presumably" + or + wrong = "presumibly" and right = "presumably" + or + wrong = "pretection" and right = "protection" + or + wrong = "prevelant" and right = "prevalent" + or + wrong = "preverse" and right = "perverse" + or + wrong = "previvous" and right = "previous" + or + wrong = "pricipal" and right = "principal" + or + wrong = "priciple" and right = "principle" + or + wrong = "priestood" and right = "priesthood" + or + wrong = "primarly" and right = "primarily" + or + wrong = "primative" and right = "primitive" + or + wrong = "primatively" and right = "primitively" + or + wrong = "primatives" and right = "primitives" + or + wrong = "primordal" and right = "primordial" + or + wrong = "principaly" and right = "principality" + or + wrong = "principial" and right = "principal" + or + wrong = "principlaity" and right = "principality" + or + wrong = "principly" and right = "principally" + or + wrong = "prinicipal" and right = "principal" + or + wrong = "privalege" and right = "privilege" + or + wrong = "privaleges" and right = "privileges" + or + wrong = "priveledges" and right = "privileges" + or + wrong = "privelege" and right = "privilege" + or + wrong = "priveleged" and right = "privileged" + or + wrong = "priveleges" and right = "privileges" + or + wrong = "privelige" and right = "privilege" + or + wrong = "priveliged" and right = "privileged" + or + wrong = "priveliges" and right = "privileges" + or + wrong = "privelleges" and right = "privileges" + or + wrong = "privilage" and right = "privilege" + or + wrong = "priviledge" and right = "privilege" + or + wrong = "priviledges" and right = "privileges" + or + wrong = "privledge" and right = "privilege" + or + wrong = "privte" and right = "private" + or + wrong = "probabilaty" and right = "probability" + or + wrong = "probablistic" and right = "probabilistic" + or + wrong = "probablly" and right = "probably" + or + wrong = "probalibity" and right = "probability" + or + wrong = "probaly" and right = "probably" + or + wrong = "probelm" and right = "problem" + or + wrong = "proccess" and right = "process" + or + wrong = "proccessing" and right = "processing" + or + wrong = "procede" and right = "precede" + or + wrong = "procede" and right = "proceed" + or + wrong = "proceded" and right = "preceded" + or + wrong = "proceded" and right = "proceeded" + or + wrong = "procedes" and right = "precedes" + or + wrong = "procedes" and right = "proceeds" + or + wrong = "procedger" and right = "procedure" + or + wrong = "proceding" and right = "preceding" + or + wrong = "proceding" and right = "proceeding" + or + wrong = "procedings" and right = "proceedings" + or + wrong = "proceedure" and right = "procedure" + or + wrong = "proces" and right = "process" + or + wrong = "procesed" and right = "processed" + or + wrong = "processer" and right = "processor" + or + wrong = "proclaimation" and right = "proclamation" + or + wrong = "proclamed" and right = "proclaimed" + or + wrong = "proclaming" and right = "proclaiming" + or + wrong = "proclomation" and right = "proclamation" + or + wrong = "profesion" and right = "profession" + or + wrong = "profesion" and right = "profusion" + or + wrong = "profesor" and right = "professor" + or + wrong = "professer" and right = "professor" + or + wrong = "proffesed" and right = "professed" + or + wrong = "proffesion" and right = "profession" + or + wrong = "proffesional" and right = "professional" + or + wrong = "proffesor" and right = "professor" + or + wrong = "profilic" and right = "prolific" + or + wrong = "progessed" and right = "progressed" + or + wrong = "progidy" and right = "prodigy" + or + wrong = "programable" and right = "programmable" + or + wrong = "progrom" and right = "pogrom" + or + wrong = "progrom" and right = "program" + or + wrong = "progroms" and right = "pogroms" + or + wrong = "progroms" and right = "programs" + or + wrong = "prohabition" and right = "prohibition" + or + wrong = "prologomena" and right = "prolegomena" + or + wrong = "prominance" and right = "prominence" + or + wrong = "prominant" and right = "prominent" + or + wrong = "prominantly" and right = "prominently" + or + wrong = "prominately" and right = "predominately" + or + wrong = "prominately" and right = "prominently" + or + wrong = "promiscous" and right = "promiscuous" + or + wrong = "promotted" and right = "promoted" + or + wrong = "pronomial" and right = "pronominal" + or + wrong = "pronouced" and right = "pronounced" + or + wrong = "pronounched" and right = "pronounced" + or + wrong = "pronounciation" and right = "pronunciation" + or + wrong = "proove" and right = "prove" + or + wrong = "prooved" and right = "proved" + or + wrong = "prophacy" and right = "prophecy" + or + wrong = "propietary" and right = "proprietary" + or + wrong = "propmted" and right = "prompted" + or + wrong = "propoganda" and right = "propaganda" + or + wrong = "propogate" and right = "propagate" + or + wrong = "propogates" and right = "propagates" + or + wrong = "propogation" and right = "propagation" + or + wrong = "propostion" and right = "proposition" + or + wrong = "propotions" and right = "proportions" + or + wrong = "propper" and right = "proper" + or + wrong = "propperly" and right = "properly" + or + wrong = "proprietory" and right = "proprietary" + or + wrong = "proseletyzing" and right = "proselytizing" + or + wrong = "protaganist" and right = "protagonist" + or + wrong = "protaganists" and right = "protagonists" + or + wrong = "protocal" and right = "protocol" + or + wrong = "protoganist" and right = "protagonist" + or + wrong = "prototpe" and right = "prototype" + or + wrong = "protoype" and right = "prototype" + or + wrong = "protrayed" and right = "portrayed" + or + wrong = "protruberance" and right = "protuberance" + or + wrong = "protruberances" and right = "protuberances" + or + wrong = "prouncements" and right = "pronouncements" + or + wrong = "provacative" and right = "provocative" + or + wrong = "provded" and right = "provided" + or + wrong = "provicial" and right = "provincial" + or + wrong = "provinicial" and right = "provincial" + or + wrong = "provisiosn" and right = "provision" + or + wrong = "provisonal" and right = "provisional" + or + wrong = "proximty" and right = "proximity" + or + wrong = "pseudononymous" and right = "pseudonymous" + or + wrong = "pseudonyn" and right = "pseudonym" + or + wrong = "psuedo" and right = "pseudo" + or + wrong = "psycology" and right = "psychology" + or + wrong = "psyhic" and right = "psychic" + or + wrong = "pubilsher" and right = "publisher" + or + wrong = "pubisher" and right = "publisher" + or + wrong = "publiaher" and right = "publisher" + or + wrong = "publically" and right = "publicly" + or + wrong = "publicaly" and right = "publicly" + or + wrong = "publicher" and right = "publisher" + or + wrong = "publihser" and right = "publisher" + or + wrong = "publisehr" and right = "publisher" + or + wrong = "publiser" and right = "publisher" + or + wrong = "publisger" and right = "publisher" + or + wrong = "publisheed" and right = "published" + or + wrong = "publisherr" and right = "publisher" + or + wrong = "publishher" and right = "publisher" + or + wrong = "publishor" and right = "publisher" + or + wrong = "publishre" and right = "publisher" + or + wrong = "publissher" and right = "publisher" + or + wrong = "publlisher" and right = "publisher" + or + wrong = "publsiher" and right = "publisher" + or + wrong = "publusher" and right = "publisher" + or + wrong = "puchasing" and right = "purchasing" + or + wrong = "pucini" and right = "puccini" + or + wrong = "pulisher" and right = "publisher" + or + wrong = "pumkin" and right = "pumpkin" + or + wrong = "puplisher" and right = "publisher" + or + wrong = "puritannical" and right = "puritanical" + or + wrong = "purposedly" and right = "purposely" + or + wrong = "purpotedly" and right = "purportedly" + or + wrong = "pursuade" and right = "persuade" + or + wrong = "pursuaded" and right = "persuaded" + or + wrong = "pursuades" and right = "persuades" + or + wrong = "pususading" and right = "persuading" + or + wrong = "puting" and right = "putting" + or + wrong = "pwoer" and right = "power" + or + wrong = "pyscic" and right = "psychic" + or + wrong = "qtuie" and right = "quiet" + or + wrong = "qtuie" and right = "quite" + or + wrong = "quantaty" and right = "quantity" + or + wrong = "quantitiy" and right = "quantity" + or + wrong = "quarantaine" and right = "quarantine" + or + wrong = "queenland" and right = "queensland" + or + wrong = "questonable" and right = "questionable" + or + wrong = "quicklyu" and right = "quickly" + or + wrong = "quinessential" and right = "quintessential" + or + wrong = "quitted" and right = "quit" + or + wrong = "quizes" and right = "quizzes" + or + wrong = "qutie" and right = "quiet" + or + wrong = "qutie" and right = "quite" + or + wrong = "rabinnical" and right = "rabbinical" + or + wrong = "racaus" and right = "raucous" + or + wrong = "radiactive" and right = "radioactive" + or + wrong = "radify" and right = "ratify" + or + wrong = "raelly" and right = "really" + or + wrong = "rarified" and right = "rarefied" + or + wrong = "reaccurring" and right = "recurring" + or + wrong = "reacing" and right = "reaching" + or + wrong = "reacll" and right = "recall" + or + wrong = "readmition" and right = "readmission" + or + wrong = "realitvely" and right = "relatively" + or + wrong = "realsitic" and right = "realistic" + or + wrong = "realtions" and right = "relations" + or + wrong = "realy" and right = "really" + or + wrong = "realyl" and right = "really" + or + wrong = "reasearch" and right = "research" + or + wrong = "rebiulding" and right = "rebuilding" + or + wrong = "rebllions" and right = "rebellions" + or + wrong = "rebounce" and right = "rebound" + or + wrong = "reccomend" and right = "recommend" + or + wrong = "reccomendations" and right = "recommendations" + or + wrong = "reccomended" and right = "recommended" + or + wrong = "reccomending" and right = "recommending" + or + wrong = "reccommend" and right = "recommend" + or + wrong = "reccommended" and right = "recommended" + or + wrong = "reccommending" and right = "recommending" + or + wrong = "reccuring" and right = "recurring" + or + wrong = "receeded" and right = "receded" + or + wrong = "receeding" and right = "receding" + or + wrong = "recepient" and right = "recipient" + or + wrong = "recepients" and right = "recipients" + or + wrong = "receving" and right = "receiving" + or + wrong = "rechargable" and right = "rechargeable" + or + wrong = "reched" and right = "reached" + or + wrong = "recide" and right = "reside" + or + wrong = "recided" and right = "resided" + or + wrong = "recident" and right = "resident" + or + wrong = "recidents" and right = "residents" + or + wrong = "reciding" and right = "residing" + or + wrong = "reciepents" and right = "recipients" + or + wrong = "reciept" and right = "receipt" + or + wrong = "recieve" and right = "receive" + or + wrong = "recieved" and right = "received" + or + wrong = "reciever" and right = "receiver" + or + wrong = "recievers" and right = "receivers" + or + wrong = "recieves" and right = "receives" + or + wrong = "recieving" and right = "receiving" + or + wrong = "recipiant" and right = "recipient" + or + wrong = "recipiants" and right = "recipients" + or + wrong = "recived" and right = "received" + or + wrong = "recivership" and right = "receivership" + or + wrong = "recogise" and right = "recognise" + or + wrong = "recogize" and right = "recognize" + or + wrong = "recomend" and right = "recommend" + or + wrong = "recomended" and right = "recommended" + or + wrong = "recomending" and right = "recommending" + or + wrong = "recomends" and right = "recommends" + or + wrong = "recommedations" and right = "recommendations" + or + wrong = "recompence" and right = "recompense" + or + wrong = "reconaissance" and right = "reconnaissance" + or + wrong = "reconcilation" and right = "reconciliation" + or + wrong = "reconized" and right = "recognized" + or + wrong = "reconnaisance" and right = "reconnaissance" + or + wrong = "reconnaissence" and right = "reconnaissance" + or + wrong = "recontructed" and right = "reconstructed" + or + wrong = "recquired" and right = "required" + or + wrong = "recrational" and right = "recreational" + or + wrong = "recrod" and right = "record" + or + wrong = "recuiting" and right = "recruiting" + or + wrong = "recuring" and right = "recurring" + or + wrong = "recurrance" and right = "recurrence" + or + wrong = "rediculous" and right = "ridiculous" + or + wrong = "reedeming" and right = "redeeming" + or + wrong = "reenforced" and right = "reinforced" + or + wrong = "refect" and right = "reflect" + or + wrong = "refedendum" and right = "referendum" + or + wrong = "referal" and right = "referral" + or + wrong = "referece" and right = "reference" + or + wrong = "refereces" and right = "references" + or + wrong = "refered" and right = "referred" + or + wrong = "referemce" and right = "reference" + or + wrong = "referemces" and right = "references" + or + wrong = "referencs" and right = "references" + or + wrong = "referenece" and right = "reference" + or + wrong = "refereneced" and right = "referenced" + or + wrong = "refereneces" and right = "references" + or + wrong = "referiang" and right = "referring" + or + wrong = "refering" and right = "referring" + or + wrong = "refernce" and right = "reference" + or + wrong = "refernce" and right = "references" + or + wrong = "refernces" and right = "references" + or + wrong = "referrence" and right = "reference" + or + wrong = "referrences" and right = "references" + or + wrong = "referrs" and right = "refers" + or + wrong = "reffered" and right = "referred" + or + wrong = "refference" and right = "reference" + or + wrong = "reffering" and right = "referring" + or + wrong = "refrence" and right = "reference" + or + wrong = "refrences" and right = "references" + or + wrong = "refrers" and right = "refers" + or + wrong = "refridgeration" and right = "refrigeration" + or + wrong = "refridgerator" and right = "refrigerator" + or + wrong = "refromist" and right = "reformist" + or + wrong = "refusla" and right = "refusal" + or + wrong = "regardes" and right = "regards" + or + wrong = "regluar" and right = "regular" + or + wrong = "reguarly" and right = "regularly" + or + wrong = "regulaion" and right = "regulation" + or + wrong = "regulaotrs" and right = "regulators" + or + wrong = "regularily" and right = "regularly" + or + wrong = "rehersal" and right = "rehearsal" + or + wrong = "reicarnation" and right = "reincarnation" + or + wrong = "reigining" and right = "reigning" + or + wrong = "reknown" and right = "renown" + or + wrong = "reknowned" and right = "renowned" + or + wrong = "rela" and right = "real" + or + wrong = "relaly" and right = "really" + or + wrong = "relatiopnship" and right = "relationship" + or + wrong = "relativly" and right = "relatively" + or + wrong = "relected" and right = "reelected" + or + wrong = "releive" and right = "relieve" + or + wrong = "releived" and right = "relieved" + or + wrong = "releiver" and right = "reliever" + or + wrong = "releses" and right = "releases" + or + wrong = "relevence" and right = "relevance" + or + wrong = "relevent" and right = "relevant" + or + wrong = "reliablity" and right = "reliability" + or + wrong = "relient" and right = "reliant" + or + wrong = "religeous" and right = "religious" + or + wrong = "religous" and right = "religious" + or + wrong = "religously" and right = "religiously" + or + wrong = "relinqushment" and right = "relinquishment" + or + wrong = "relitavely" and right = "relatively" + or + wrong = "relized" and right = "realised" + or + wrong = "relized" and right = "realized" + or + wrong = "relpacement" and right = "replacement" + or + wrong = "remaing" and right = "remaining" + or + wrong = "remeber" and right = "remember" + or + wrong = "rememberable" and right = "memorable" + or + wrong = "rememberance" and right = "remembrance" + or + wrong = "remembrence" and right = "remembrance" + or + wrong = "remenant" and right = "remnant" + or + wrong = "remenicent" and right = "reminiscent" + or + wrong = "reminent" and right = "remnant" + or + wrong = "reminescent" and right = "reminiscent" + or + wrong = "reminscent" and right = "reminiscent" + or + wrong = "reminsicent" and right = "reminiscent" + or + wrong = "rendevous" and right = "rendezvous" + or + wrong = "rendezous" and right = "rendezvous" + or + wrong = "renedered" and right = "rende" + or + wrong = "renewl" and right = "renewal" + or + wrong = "rennovate" and right = "renovate" + or + wrong = "rennovated" and right = "renovated" + or + wrong = "rennovating" and right = "renovating" + or + wrong = "rennovation" and right = "renovation" + or + wrong = "rentors" and right = "renters" + or + wrong = "reoccurrence" and right = "recurrence" + or + wrong = "reorganision" and right = "reorganisation" + or + wrong = "repatition" and right = "repartition" + or + wrong = "repatition" and right = "repetition" + or + wrong = "repblic" and right = "republic" + or + wrong = "repblican" and right = "republican" + or + wrong = "repblicans" and right = "republicans" + or + wrong = "repblics" and right = "republics" + or + wrong = "repectively" and right = "respectively" + or + wrong = "repeition" and right = "repetition" + or + wrong = "repentence" and right = "repentance" + or + wrong = "repentent" and right = "repentant" + or + wrong = "repeteadly" and right = "repeatedly" + or + wrong = "repetion" and right = "repetition" + or + wrong = "repid" and right = "rapid" + or + wrong = "reponse" and right = "response" + or + wrong = "reponsible" and right = "responsible" + or + wrong = "reportadly" and right = "reportedly" + or + wrong = "represantative" and right = "representative" + or + wrong = "representive" and right = "representative" + or + wrong = "representives" and right = "representatives" + or + wrong = "reproducable" and right = "reproducible" + or + wrong = "reprtoire" and right = "repertoire" + or + wrong = "repsectively" and right = "respectively" + or + wrong = "reptition" and right = "repetition" + or + wrong = "repubic" and right = "republic" + or + wrong = "repubican" and right = "republican" + or + wrong = "repubicans" and right = "republicans" + or + wrong = "repubics" and right = "republics" + or + wrong = "republi" and right = "republic" + or + wrong = "republian" and right = "republican" + or + wrong = "republians" and right = "republicans" + or + wrong = "republis" and right = "republics" + or + wrong = "repulic" and right = "republic" + or + wrong = "repulican" and right = "republican" + or + wrong = "repulicans" and right = "republicans" + or + wrong = "repulics" and right = "republics" + or + wrong = "requirment" and right = "requirement" + or + wrong = "requred" and right = "required" + or + wrong = "resaurant" and right = "restaurant" + or + wrong = "resembelance" and right = "resemblance" + or + wrong = "resembes" and right = "resembles" + or + wrong = "resemblence" and right = "resemblance" + or + wrong = "resevoir" and right = "reservoir" + or + wrong = "residental" and right = "residential" + or + wrong = "resignement" and right = "resignment" + or + wrong = "resistable" and right = "resistible" + or + wrong = "resistence" and right = "resistance" + or + wrong = "resistent" and right = "resistant" + or + wrong = "respectivly" and right = "respectively" + or + wrong = "responce" and right = "response" + or + wrong = "responibilities" and right = "responsibilities" + or + wrong = "responisble" and right = "responsible" + or + wrong = "responnsibilty" and right = "responsibility" + or + wrong = "responsability" and right = "responsibility" + or + wrong = "responsibile" and right = "responsible" + or + wrong = "responsibilites" and right = "responsibilities" + or + wrong = "responsiblities" and right = "responsibilities" + or + wrong = "responsiblity" and right = "responsibility" + or + wrong = "ressemblance" and right = "resemblance" + or + wrong = "ressemble" and right = "resemble" + or + wrong = "ressembled" and right = "resembled" + or + wrong = "ressemblence" and right = "resemblance" + or + wrong = "ressembling" and right = "resembling" + or + wrong = "resssurecting" and right = "resurrecting" + or + wrong = "ressurect" and right = "resurrect" + or + wrong = "ressurected" and right = "resurrected" + or + wrong = "ressurection" and right = "resurrection" + or + wrong = "ressurrection" and right = "resurrection" + or + wrong = "restarant" and right = "restaurant" + or + wrong = "restarants" and right = "restaurants" + or + wrong = "restaraunt" and right = "restaurant" + or + wrong = "restaraunteur" and right = "restaurateur" + or + wrong = "restaraunteurs" and right = "restaurateurs" + or + wrong = "restaraunts" and right = "restaurants" + or + wrong = "restauranteurs" and right = "restaurateurs" + or + wrong = "restauration" and right = "restoration" + or + wrong = "restauraunt" and right = "restaurant" + or + wrong = "resteraunt" and right = "restaurant" + or + wrong = "resteraunts" and right = "restaurants" + or + wrong = "resticted" and right = "restricted" + or + wrong = "restraunt" and right = "restaurant" + or + wrong = "restraunt" and right = "restraint" + or + wrong = "resturant" and right = "restaurant" + or + wrong = "resturants" and right = "restaurants" + or + wrong = "resturaunt" and right = "restaurant" + or + wrong = "resturaunts" and right = "restaurants" + or + wrong = "resurecting" and right = "resurrecting" + or + wrong = "retalitated" and right = "retaliated" + or + wrong = "retalitation" and right = "retaliation" + or + wrong = "retreive" and right = "retrieve" + or + wrong = "retrive" and right = "retrieve" + or + wrong = "returnd" and right = "returned" + or + wrong = "revaluated" and right = "reevaluated" + or + wrong = "reveiw" and right = "review" + or + wrong = "reveral" and right = "reversal" + or + wrong = "reversable" and right = "reversible" + or + wrong = "revolutionar" and right = "revolutionary" + or + wrong = "rewitten" and right = "rewritten" + or + wrong = "rewriet" and right = "rewrite" + or + wrong = "rference" and right = "reference" + or + wrong = "rferences" and right = "references" + or + wrong = "rhymme" and right = "rhyme" + or + wrong = "rhythem" and right = "rhythm" + or + wrong = "rhythim" and right = "rhythm" + or + wrong = "rhytmic" and right = "rhythmic" + or + wrong = "rigeur" and right = "rigor" + or + wrong = "rigeur" and right = "rigour" + or + wrong = "rigeur" and right = "rigueur" + or + wrong = "rigourous" and right = "rigorous" + or + wrong = "rininging" and right = "ringing" + or + wrong = "rised" and right = "raised" + or + wrong = "rised" and right = "rose" + or + wrong = "rockerfeller" and right = "rockefeller" + or + wrong = "rococco" and right = "rococo" + or + wrong = "rocord" and right = "record" + or + wrong = "roomate" and right = "roommate" + or + wrong = "rougly" and right = "roughly" + or + wrong = "rucuperate" and right = "recuperate" + or + wrong = "rudimentatry" and right = "rudimentary" + or + wrong = "rulle" and right = "rule" + or + wrong = "runing" and right = "running" + or + wrong = "runnung" and right = "running" + or + wrong = "russina" and right = "russian" + or + wrong = "russion" and right = "russian" + or + wrong = "rwite" and right = "write" + or + wrong = "rythem" and right = "rhythm" + or + wrong = "rythim" and right = "rhythm" + or + wrong = "rythm" and right = "rhythm" + or + wrong = "rythmic" and right = "rhythmic" + or + wrong = "rythyms" and right = "rhythms" + or + wrong = "sacrafice" and right = "sacrifice" + or + wrong = "sacreligious" and right = "sacrilegious" + or + wrong = "sacremento" and right = "sacramento" + or + wrong = "sacrifical" and right = "sacrificial" + or + wrong = "saftey" and right = "safety" + or + wrong = "safty" and right = "safety" + or + wrong = "salery" and right = "salary" + or + wrong = "sanctionning" and right = "sanctioning" + or + wrong = "sandwhich" and right = "sandwich" + or + wrong = "sanhedrim" and right = "sanhedrin" + or + wrong = "santioned" and right = "sanctioned" + or + wrong = "sargant" and right = "sergeant" + or + wrong = "sargeant" and right = "sergeant" + or + wrong = "sasy" and right = "sassy" + or + wrong = "sasy" and right = "says" + or + wrong = "satelite" and right = "satellite" + or + wrong = "satelites" and right = "satellites" + or + wrong = "saterday" and right = "saturday" + or + wrong = "saterdays" and right = "saturdays" + or + wrong = "satisfactority" and right = "satisfactorily" + or + wrong = "satric" and right = "satiric" + or + wrong = "satrical" and right = "satirical" + or + wrong = "satrically" and right = "satirically" + or + wrong = "sattelite" and right = "satellite" + or + wrong = "sattelites" and right = "satellites" + or + wrong = "saught" and right = "sought" + or + wrong = "saveing" and right = "saving" + or + wrong = "saxaphone" and right = "saxophone" + or + wrong = "scaleable" and right = "scalable" + or + wrong = "scandanavia" and right = "scandinavia" + or + wrong = "scaricity" and right = "scarcity" + or + wrong = "scavanged" and right = "scavenged" + or + wrong = "schedual" and right = "schedule" + or + wrong = "scholarhip" and right = "scholarship" + or + wrong = "scholarstic" and right = "scholarly" + or + wrong = "scholarstic" and right = "scholastic" + or + wrong = "scientfic" and right = "scientific" + or + wrong = "scientifc" and right = "scientific" + or + wrong = "scientis" and right = "scientist" + or + wrong = "scince" and right = "science" + or + wrong = "scinece" and right = "science" + or + wrong = "scirpt" and right = "script" + or + wrong = "scoll" and right = "scroll" + or + wrong = "screenwrighter" and right = "screenwriter" + or + wrong = "scrutinity" and right = "scrutiny" + or + wrong = "scuptures" and right = "sculptures" + or + wrong = "seach" and right = "search" + or + wrong = "seached" and right = "searched" + or + wrong = "seaches" and right = "searches" + or + wrong = "secceeded" and right = "seceded" + or + wrong = "secceeded" and right = "succeeded" + or + wrong = "seceed" and right = "secede" + or + wrong = "seceed" and right = "succeed" + or + wrong = "seceeded" and right = "seceded" + or + wrong = "seceeded" and right = "succeeded" + or + wrong = "secratary" and right = "secretary" + or + wrong = "secretery" and right = "secretary" + or + wrong = "sedereal" and right = "sidereal" + or + wrong = "seeked" and right = "sought" + or + wrong = "segementation" and right = "segmentation" + or + wrong = "seguoys" and right = "segues" + or + wrong = "seige" and right = "siege" + or + wrong = "seing" and right = "seeing" + or + wrong = "seinor" and right = "senior" + or + wrong = "seldomly" and right = "seldom" + or + wrong = "senarios" and right = "scenarios" + or + wrong = "sence" and right = "sense" + or + wrong = "sence" and right = "since" + or + wrong = "senstive" and right = "sensitive" + or + wrong = "sensure" and right = "censure" + or + wrong = "seperate" and right = "separate" + or + wrong = "seperated" and right = "separated" + or + wrong = "seperately" and right = "separately" + or + wrong = "seperates" and right = "separates" + or + wrong = "seperating" and right = "separating" + or + wrong = "seperation" and right = "separation" + or + wrong = "seperatism" and right = "separatism" + or + wrong = "seperatist" and right = "separatist" + or + wrong = "seperator" and right = "separator" + or + wrong = "sepina" and right = "subpoena" + or + wrong = "sepulchure" and right = "sepulcher" + or + wrong = "sepulchure" and right = "sepulchre" + or + wrong = "sepulcre" and right = "sepulcher" + or + wrong = "sepulcre" and right = "sepulchre" + or + wrong = "sergent" and right = "sergeant" + or + wrong = "settelement" and right = "settlement" + or + wrong = "settlment" and right = "settlement" + or + wrong = "settting" and right = "setting" + or + wrong = "severeal" and right = "several" + or + wrong = "severley" and right = "severely" + or + wrong = "severly" and right = "severely" + or + wrong = "sevice" and right = "service" + or + wrong = "shadasloo" and right = "shadaloo" + or + wrong = "shaddow" and right = "shadow" + or + wrong = "shadoloo" and right = "shadaloo" + or + wrong = "shamen" and right = "shaman" + or + wrong = "shamen" and right = "shamans" + or + wrong = "sheat" and right = "cheat" + or + wrong = "sheat" and right = "sheath" + or + wrong = "sheat" and right = "sheet" + or + wrong = "sheild" and right = "shield" + or + wrong = "sherif" and right = "sheriff" + or + wrong = "shineing" and right = "shining" + or + wrong = "shiped" and right = "shipped" + or + wrong = "shiping" and right = "shipping" + or + wrong = "shopkeeepers" and right = "shopkeepers" + or + wrong = "shorly" and right = "shortly" + or + wrong = "shoudl" and right = "should" + or + wrong = "shoudln" and right = "should" + or + wrong = "shreak" and right = "shriek" + or + wrong = "shrinked" and right = "shrunk" + or + wrong = "sicne" and right = "since" + or + wrong = "sideral" and right = "sidereal" + or + wrong = "sieze" and right = "seize" + or + wrong = "sieze" and right = "size" + or + wrong = "siezed" and right = "seized" + or + wrong = "siezed" and right = "sized" + or + wrong = "siezing" and right = "seizing" + or + wrong = "siezing" and right = "sizing" + or + wrong = "siezure" and right = "seizure" + or + wrong = "siezures" and right = "seizures" + or + wrong = "siginificant" and right = "significant" + or + wrong = "signficant" and right = "significant" + or + wrong = "signficiant" and right = "significant" + or + wrong = "signfies" and right = "signifies" + or + wrong = "signifantly" and right = "significantly" + or + wrong = "significently" and right = "significantly" + or + wrong = "signifigant" and right = "significant" + or + wrong = "signifigantly" and right = "significantly" + or + wrong = "signitories" and right = "signatories" + or + wrong = "signitory" and right = "signatory" + or + wrong = "similarily" and right = "similarly" + or + wrong = "similiar" and right = "similar" + or + wrong = "similiarity" and right = "similarity" + or + wrong = "similiarly" and right = "similarly" + or + wrong = "simmilar" and right = "similar" + or + wrong = "simpley" and right = "simply" + or + wrong = "simplier" and right = "simpler" + or + wrong = "simultanous" and right = "simultaneous" + or + wrong = "simultanously" and right = "simultaneously" + or + wrong = "sincerley" and right = "sincerely" + or + wrong = "singsog" and right = "singsong" + or + wrong = "sinse" and right = "since" + or + wrong = "sinse" and right = "sines" + or + wrong = "sionist" and right = "zionist" + or + wrong = "sionists" and right = "zionists" + or + wrong = "sixtin" and right = "sistine" + or + wrong = "skagerak" and right = "skagerrak" + or + wrong = "skateing" and right = "skating" + or + wrong = "slaugterhouses" and right = "slaughterhouses" + or + wrong = "slighly" and right = "slightly" + or + wrong = "slippy" and right = "slippery" + or + wrong = "slowy" and right = "slowly" + or + wrong = "smae" and right = "same" + or + wrong = "smealting" and right = "smelting" + or + wrong = "smoe" and right = "some" + or + wrong = "sneeks" and right = "sneaks" + or + wrong = "snese" and right = "sneeze" + or + wrong = "socalism" and right = "socialism" + or + wrong = "socities" and right = "societies" + or + wrong = "soem" and right = "some" + or + wrong = "sofware" and right = "software" + or + wrong = "sohw" and right = "show" + or + wrong = "soilders" and right = "soldiers" + or + wrong = "solatary" and right = "solitary" + or + wrong = "soley" and right = "solely" + or + wrong = "soliders" and right = "soldiers" + or + wrong = "soliliquy" and right = "soliloquy" + or + wrong = "soluable" and right = "soluble" + or + wrong = "somene" and right = "someone" + or + wrong = "somtimes" and right = "sometimes" + or + wrong = "somwhere" and right = "somewhere" + or + wrong = "sophicated" and right = "sophisticated" + or + wrong = "sophmore" and right = "sophomore" + or + wrong = "sorceror" and right = "sorcerer" + or + wrong = "sorrounding" and right = "surrounding" + or + wrong = "sotry" and right = "story" + or + wrong = "sotyr" and right = "satyr" + or + wrong = "sotyr" and right = "story" + or + wrong = "soudn" and right = "sound" + or + wrong = "soudns" and right = "sounds" + or + wrong = "sould" and right = "could" + or + wrong = "sould" and right = "should" + or + wrong = "sould" and right = "sold" + or + wrong = "sould" and right = "soul" + or + wrong = "sountrack" and right = "soundtrack" + or + wrong = "sourth" and right = "south" + or + wrong = "sourthern" and right = "southern" + or + wrong = "souvenier" and right = "souvenir" + or + wrong = "souveniers" and right = "souvenirs" + or + wrong = "soveits" and right = "soviets" + or + wrong = "sovereignity" and right = "sovereignty" + or + wrong = "soverign" and right = "sovereign" + or + wrong = "soverignity" and right = "sovereignty" + or + wrong = "soverignty" and right = "sovereignty" + or + wrong = "spainish" and right = "spanish" + or + wrong = "speach" and right = "speech" + or + wrong = "specfic" and right = "specific" + or + wrong = "speciallized" and right = "specialised" + or + wrong = "speciallized" and right = "specialized" + or + wrong = "specif" and right = "specific" + or + wrong = "specif" and right = "specify" + or + wrong = "specifiying" and right = "specifying" + or + wrong = "speciman" and right = "specimen" + or + wrong = "spectauclar" and right = "spectacular" + or + wrong = "spectaulars" and right = "spectaculars" + or + wrong = "spects" and right = "aspects" + or + wrong = "spects" and right = "expects" + or + wrong = "spectum" and right = "spectrum" + or + wrong = "speices" and right = "species" + or + wrong = "spendour" and right = "splendour" + or + wrong = "spermatozoan" and right = "spermatozoon" + or + wrong = "spoace" and right = "space" + or + wrong = "sponser" and right = "sponsor" + or + wrong = "sponsered" and right = "sponsored" + or + wrong = "spontanous" and right = "spontaneous" + or + wrong = "sponzored" and right = "sponsored" + or + wrong = "spoonfulls" and right = "spoonfuls" + or + wrong = "sppeches" and right = "speeches" + or + wrong = "spreaded" and right = "spread" + or + wrong = "sprech" and right = "speech" + or + wrong = "spred" and right = "spread" + or + wrong = "spriritual" and right = "spiritual" + or + wrong = "spritual" and right = "spiritual" + or + wrong = "sqaure" and right = "square" + or + wrong = "sring" and right = "string" + or + wrong = "stablility" and right = "stability" + or + wrong = "stainlees" and right = "stainless" + or + wrong = "staion" and right = "station" + or + wrong = "standars" and right = "standards" + or + wrong = "stange" and right = "strange" + or + wrong = "startegic" and right = "strategic" + or + wrong = "startegies" and right = "strategies" + or + wrong = "startegy" and right = "strategy" + or + wrong = "stateman" and right = "statesman" + or + wrong = "statememts" and right = "statements" + or + wrong = "statment" and right = "statement" + or + wrong = "steriods" and right = "steroids" + or + wrong = "sterotypes" and right = "stereotypes" + or + wrong = "stilus" and right = "stylus" + or + wrong = "stingent" and right = "stringent" + or + wrong = "stiring" and right = "stirring" + or + wrong = "stirrs" and right = "stirs" + or + wrong = "stlye" and right = "style" + or + wrong = "stomache" and right = "stomach" + or + wrong = "stong" and right = "strong" + or + wrong = "stopry" and right = "story" + or + wrong = "storeis" and right = "stories" + or + wrong = "storise" and right = "stories" + or + wrong = "stornegst" and right = "strongest" + or + wrong = "stoyr" and right = "story" + or + wrong = "stpo" and right = "stop" + or + wrong = "stradegies" and right = "strategies" + or + wrong = "stradegy" and right = "strategy" + or + wrong = "strat" and right = "start" + or + wrong = "strat" and right = "strata" + or + wrong = "stratagically" and right = "strategically" + or + wrong = "streemlining" and right = "streamlining" + or + wrong = "stregth" and right = "strength" + or + wrong = "strenghen" and right = "strengthen" + or + wrong = "strenghened" and right = "strengthened" + or + wrong = "strenghening" and right = "strengthening" + or + wrong = "strenght" and right = "strength" + or + wrong = "strenghten" and right = "strengthen" + or + wrong = "strenghtened" and right = "strengthened" + or + wrong = "strenghtening" and right = "strengthening" + or + wrong = "strengtened" and right = "strengthened" + or + wrong = "strenous" and right = "strenuous" + or + wrong = "strictist" and right = "strictest" + or + wrong = "strikely" and right = "strikingly" + or + wrong = "strnad" and right = "strand" + or + wrong = "stroy" and right = "destroy" + or + wrong = "stroy" and right = "story" + or + wrong = "structual" and right = "structural" + or + wrong = "stubborness" and right = "stubbornness" + or + wrong = "stucture" and right = "structure" + or + wrong = "stuctured" and right = "structured" + or + wrong = "studdy" and right = "study" + or + wrong = "studing" and right = "studying" + or + wrong = "stuggling" and right = "struggling" + or + wrong = "sturcture" and right = "structure" + or + wrong = "subcatagories" and right = "subcategories" + or + wrong = "subcatagory" and right = "subcategory" + or + wrong = "subconsiously" and right = "subconsciously" + or + wrong = "subjudgation" and right = "subjugation" + or + wrong = "submachne" and right = "submachine" + or + wrong = "subpecies" and right = "subspecies" + or + wrong = "subsidary" and right = "subsidiary" + or + wrong = "subsiduary" and right = "subsidiary" + or + wrong = "subsquent" and right = "subsequent" + or + wrong = "subsquently" and right = "subsequently" + or + wrong = "substace" and right = "substance" + or + wrong = "substancial" and right = "substantial" + or + wrong = "substatial" and right = "substantial" + or + wrong = "substituded" and right = "substituted" + or + wrong = "substract" and right = "subtract" + or + wrong = "substracted" and right = "subtracted" + or + wrong = "substracting" and right = "subtracting" + or + wrong = "substraction" and right = "subtraction" + or + wrong = "substracts" and right = "subtracts" + or + wrong = "subtances" and right = "substances" + or + wrong = "subterranian" and right = "subterranean" + or + wrong = "suburburban" and right = "suburban" + or + wrong = "succceeded" and right = "succeeded" + or + wrong = "succcesses" and right = "successes" + or + wrong = "succedded" and right = "succeeded" + or + wrong = "succeded" and right = "succeeded" + or + wrong = "succeds" and right = "succeeds" + or + wrong = "succesful" and right = "successful" + or + wrong = "succesfully" and right = "successfully" + or + wrong = "succesfuly" and right = "successfully" + or + wrong = "succesion" and right = "succession" + or + wrong = "succesive" and right = "successive" + or + wrong = "successfull" and right = "successful" + or + wrong = "successully" and right = "successfully" + or + wrong = "succsess" and right = "success" + or + wrong = "succsessfull" and right = "successful" + or + wrong = "suceed" and right = "succeed" + or + wrong = "suceeded" and right = "succeeded" + or + wrong = "suceeding" and right = "succeeding" + or + wrong = "suceeds" and right = "succeeds" + or + wrong = "sucesful" and right = "successful" + or + wrong = "sucesfully" and right = "successfully" + or + wrong = "sucesfuly" and right = "successfully" + or + wrong = "sucesion" and right = "succession" + or + wrong = "sucess" and right = "success" + or + wrong = "sucesses" and right = "successes" + or + wrong = "sucessful" and right = "successful" + or + wrong = "sucessfull" and right = "successful" + or + wrong = "sucessfully" and right = "successfully" + or + wrong = "sucessfuly" and right = "successfully" + or + wrong = "sucession" and right = "succession" + or + wrong = "sucessive" and right = "successive" + or + wrong = "sucessor" and right = "successor" + or + wrong = "sucessot" and right = "successor" + or + wrong = "sucide" and right = "suicide" + or + wrong = "sucidial" and right = "suicidal" + or + wrong = "sudent" and right = "student" + or + wrong = "sudents" and right = "students" + or + wrong = "sufferage" and right = "suffrage" + or + wrong = "sufferred" and right = "suffered" + or + wrong = "sufferring" and right = "suffering" + or + wrong = "sufficent" and right = "sufficient" + or + wrong = "sufficently" and right = "sufficiently" + or + wrong = "sumary" and right = "summary" + or + wrong = "sunglases" and right = "sunglasses" + or + wrong = "suop" and right = "soup" + or + wrong = "superceeded" and right = "superseded" + or + wrong = "superintendant" and right = "superintendent" + or + wrong = "suphisticated" and right = "sophisticated" + or + wrong = "suplimented" and right = "supplemented" + or + wrong = "suported" and right = "supported" + or + wrong = "supose" and right = "suppose" + or + wrong = "suposed" and right = "supposed" + or + wrong = "suposedly" and right = "supposedly" + or + wrong = "suposes" and right = "supposes" + or + wrong = "suposing" and right = "supposing" + or + wrong = "supplamented" and right = "supplemented" + or + wrong = "suppliementing" and right = "supplementing" + or + wrong = "suppoed" and right = "supposed" + or + wrong = "supposingly" and right = "supposedly" + or + wrong = "suppy" and right = "supply" + or + wrong = "suprassing" and right = "surpassing" + or + wrong = "supress" and right = "suppress" + or + wrong = "supressed" and right = "suppressed" + or + wrong = "supresses" and right = "suppresses" + or + wrong = "supressing" and right = "suppressing" + or + wrong = "suprise" and right = "surprise" + or + wrong = "suprised" and right = "surprised" + or + wrong = "suprising" and right = "surprising" + or + wrong = "suprisingly" and right = "surprisingly" + or + wrong = "suprize" and right = "surprise" + or + wrong = "suprized" and right = "surprised" + or + wrong = "suprizing" and right = "surprising" + or + wrong = "suprizingly" and right = "surprisingly" + or + wrong = "surfce" and right = "surface" + or + wrong = "surley" and right = "surely" + or + wrong = "surley" and right = "surly" + or + wrong = "suround" and right = "surround" + or + wrong = "surounded" and right = "surrounded" + or + wrong = "surounding" and right = "surrounding" + or + wrong = "suroundings" and right = "surroundings" + or + wrong = "surounds" and right = "surrounds" + or + wrong = "surplanted" and right = "supplanted" + or + wrong = "surpress" and right = "suppress" + or + wrong = "surpressed" and right = "suppressed" + or + wrong = "surprize" and right = "surprise" + or + wrong = "surprized" and right = "surprised" + or + wrong = "surprizing" and right = "surprising" + or + wrong = "surprizingly" and right = "surprisingly" + or + wrong = "surrended" and right = "surrendered" + or + wrong = "surrended" and right = "surrounded" + or + wrong = "surrepetitious" and right = "surreptitious" + or + wrong = "surrepetitiously" and right = "surreptitiously" + or + wrong = "surreptious" and right = "surreptitious" + or + wrong = "surreptiously" and right = "surreptitiously" + or + wrong = "surronded" and right = "surrounded" + or + wrong = "surrouded" and right = "surrounded" + or + wrong = "surrouding" and right = "surrounding" + or + wrong = "surrundering" and right = "surrendering" + or + wrong = "surveilence" and right = "surveillance" + or + wrong = "surveill" and right = "surveil" + or + wrong = "surveyer" and right = "surveyor" + or + wrong = "surviver" and right = "survivor" + or + wrong = "survivers" and right = "survivors" + or + wrong = "survivied" and right = "survived" + or + wrong = "suseptable" and right = "susceptible" + or + wrong = "suseptible" and right = "susceptible" + or + wrong = "suspention" and right = "suspension" + or + wrong = "swaer" and right = "swear" + or + wrong = "swaers" and right = "swears" + or + wrong = "swepth" and right = "swept" + or + wrong = "swiming" and right = "swimming" + or + wrong = "syas" and right = "says" + or + wrong = "symetrical" and right = "symmetrical" + or + wrong = "symetrically" and right = "symmetrically" + or + wrong = "symetry" and right = "symmetry" + or + wrong = "symettric" and right = "symmetric" + or + wrong = "symmetral" and right = "symmetric" + or + wrong = "symmetricaly" and right = "symmetrically" + or + wrong = "synagouge" and right = "synagogue" + or + wrong = "syncronization" and right = "synchronization" + or + wrong = "synonomous" and right = "synonymous" + or + wrong = "synonymns" and right = "synonyms" + or + wrong = "synphony" and right = "symphony" + or + wrong = "syphyllis" and right = "syphilis" + or + wrong = "sypmtoms" and right = "symptoms" + or + wrong = "syrap" and right = "syrup" + or + wrong = "sysmatically" and right = "systematically" + or + wrong = "sytem" and right = "system" + or + wrong = "sytle" and right = "style" + or + wrong = "tabacco" and right = "tobacco" + or + wrong = "tahn" and right = "than" + or + wrong = "taht" and right = "that" + or + wrong = "talekd" and right = "talked" + or + wrong = "targetted" and right = "targeted" + or + wrong = "targetting" and right = "targeting" + or + wrong = "tast" and right = "taste" + or + wrong = "tath" and right = "that" + or + wrong = "tatoo" and right = "tattoo" + or + wrong = "tattooes" and right = "tattoos" + or + wrong = "taxanomic" and right = "taxonomic" + or + wrong = "taxanomy" and right = "taxonomy" + or + wrong = "teached" and right = "taught" + or + wrong = "techician" and right = "technician" + or + wrong = "techicians" and right = "technicians" + or + wrong = "techiniques" and right = "techniques" + or + wrong = "technitian" and right = "technician" + or + wrong = "technnology" and right = "technology" + or + wrong = "technolgy" and right = "technology" + or + wrong = "teh" and right = "the" + or + wrong = "tehy" and right = "they" + or + wrong = "telelevision" and right = "television" + or + wrong = "televsion" and right = "television" + or + wrong = "telphony" and right = "telephony" + or + wrong = "temerature" and right = "temperature" + or + wrong = "tempalte" and right = "template" + or + wrong = "tempaltes" and right = "templates" + or + wrong = "temparate" and right = "temperate" + or + wrong = "temperarily" and right = "temporarily" + or + wrong = "temperment" and right = "temperament" + or + wrong = "tempertaure" and right = "temperature" + or + wrong = "temperture" and right = "temperature" + or + wrong = "temprary" and right = "temporary" + or + wrong = "tenacle" and right = "tentacle" + or + wrong = "tenacles" and right = "tentacles" + or + wrong = "tendacy" and right = "tendency" + or + wrong = "tendancies" and right = "tendencies" + or + wrong = "tendancy" and right = "tendency" + or + wrong = "tepmorarily" and right = "temporarily" + or + wrong = "terrestial" and right = "terrestrial" + or + wrong = "terriories" and right = "territories" + or + wrong = "terriory" and right = "territory" + or + wrong = "territorist" and right = "terrorist" + or + wrong = "territoy" and right = "territory" + or + wrong = "terroist" and right = "terrorist" + or + wrong = "testiclular" and right = "testicular" + or + wrong = "testomony" and right = "testimony" + or + wrong = "tghe" and right = "the" + or + wrong = "thast" and right = "that" + or + wrong = "theather" and right = "theater" + or + wrong = "theese" and right = "these" + or + wrong = "theif" and right = "thief" + or + wrong = "theives" and right = "thieves" + or + wrong = "themselfs" and right = "themselves" + or + wrong = "themslves" and right = "themselves" + or + wrong = "ther" and right = "the" + or + wrong = "ther" and right = "their" + or + wrong = "ther" and right = "there" + or + wrong = "therafter" and right = "thereafter" + or + wrong = "therby" and right = "thereby" + or + wrong = "theri" and right = "their" + or + wrong = "thgat" and right = "that" + or + wrong = "thge" and right = "the" + or + wrong = "thier" and right = "their" + or + wrong = "thign" and right = "thing" + or + wrong = "thigns" and right = "things" + or + wrong = "thigsn" and right = "things" + or + wrong = "thikn" and right = "think" + or + wrong = "thikning" and right = "thickening" + or + wrong = "thikning" and right = "thinking" + or + wrong = "thikns" and right = "thinks" + or + wrong = "thiunk" and right = "think" + or + wrong = "thn" and right = "then" + or + wrong = "thna" and right = "than" + or + wrong = "thne" and right = "then" + or + wrong = "thnig" and right = "thing" + or + wrong = "thnigs" and right = "things" + or + wrong = "thoughout" and right = "throughout" + or + wrong = "threatend" and right = "threatened" + or + wrong = "threatning" and right = "threatening" + or + wrong = "threee" and right = "three" + or + wrong = "threshhold" and right = "threshold" + or + wrong = "thrid" and right = "third" + or + wrong = "throrough" and right = "thorough" + or + wrong = "throughly" and right = "thoroughly" + or + wrong = "throught" and right = "thought" + or + wrong = "throught" and right = "through" + or + wrong = "throught" and right = "throughout" + or + wrong = "througout" and right = "throughout" + or + wrong = "thru" and right = "through" + or + wrong = "thsi" and right = "this" + or + wrong = "thsoe" and right = "those" + or + wrong = "thta" and right = "that" + or + wrong = "thyat" and right = "that" + or + wrong = "tiem" and right = "tim" + or + wrong = "tiem" and right = "time" + or + wrong = "tihkn" and right = "think" + or + wrong = "tihs" and right = "this" + or + wrong = "timne" and right = "time" + or + wrong = "tiome" and right = "time" + or + wrong = "tiome" and right = "tome" + or + wrong = "tje" and right = "the" + or + wrong = "tjhe" and right = "the" + or + wrong = "tjpanishad" and right = "upanishad" + or + wrong = "tkae" and right = "take" + or + wrong = "tkaes" and right = "takes" + or + wrong = "tkaing" and right = "taking" + or + wrong = "tlaking" and right = "talking" + or + wrong = "tobbaco" and right = "tobacco" + or + wrong = "todya" and right = "today" + or + wrong = "toghether" and right = "together" + or + wrong = "toke" and right = "took" + or + wrong = "tolerence" and right = "tolerance" + or + wrong = "tolkein" and right = "tolkien" + or + wrong = "tomatos" and right = "tomatoes" + or + wrong = "tommorow" and right = "tomorrow" + or + wrong = "tommorrow" and right = "tomorrow" + or + wrong = "tongiht" and right = "tonight" + or + wrong = "toriodal" and right = "toroidal" + or + wrong = "tormenters" and right = "tormentors" + or + wrong = "tornadoe" and right = "tornado" + or + wrong = "torpeados" and right = "torpedoes" + or + wrong = "torpedos" and right = "torpedoes" + or + wrong = "tortise" and right = "tortoise" + or + wrong = "toubles" and right = "troubles" + or + wrong = "tounge" and right = "tongue" + or + wrong = "tourch" and right = "torch" + or + wrong = "tourch" and right = "touch" + or + wrong = "towords" and right = "towards" + or + wrong = "towrad" and right = "toward" + or + wrong = "tradionally" and right = "traditionally" + or + wrong = "traditionaly" and right = "traditionally" + or + wrong = "traditionnal" and right = "traditional" + or + wrong = "traditition" and right = "tradition" + or + wrong = "tradtionally" and right = "traditionally" + or + wrong = "trafficed" and right = "trafficked" + or + wrong = "trafficing" and right = "trafficking" + or + wrong = "trafic" and right = "traffic" + or + wrong = "trancendent" and right = "transcendent" + or + wrong = "trancending" and right = "transcending" + or + wrong = "tranform" and right = "transform" + or + wrong = "tranformed" and right = "transformed" + or + wrong = "transcendance" and right = "transcendence" + or + wrong = "transcendant" and right = "transcendent" + or + wrong = "transcendentational" and right = "transcendental" + or + wrong = "transcripting" and right = "transcribing" + or + wrong = "transcripting" and right = "transcription" + or + wrong = "transending" and right = "transcending" + or + wrong = "transesxuals" and right = "transsexuals" + or + wrong = "transfered" and right = "transferred" + or + wrong = "transfering" and right = "transferring" + or + wrong = "transformaton" and right = "transformation" + or + wrong = "transistion" and right = "transition" + or + wrong = "translater" and right = "translator" + or + wrong = "translaters" and right = "translators" + or + wrong = "transmissable" and right = "transmissible" + or + wrong = "transporation" and right = "transportation" + or + wrong = "tremelo" and right = "tremolo" + or + wrong = "tremelos" and right = "tremolos" + or + wrong = "treshold" and right = "threshold" + or + wrong = "triguered" and right = "triggered" + or + wrong = "triology" and right = "trilogy" + or + wrong = "troling" and right = "trolling" + or + wrong = "troup" and right = "troupe" + or + wrong = "troups" and right = "troops" + or + wrong = "troups" and right = "troupes" + or + wrong = "truely" and right = "truly" + or + wrong = "trustworthyness" and right = "trustworthiness" + or + wrong = "turnk" and right = "trunk" + or + wrong = "turnk" and right = "turnkey" + or + wrong = "tuscon" and right = "tucson" + or + wrong = "tust" and right = "trust" + or + wrong = "twelth" and right = "twelfth" + or + wrong = "twon" and right = "town" + or + wrong = "twpo" and right = "two" + or + wrong = "tyhat" and right = "that" + or + wrong = "tyhe" and right = "they" + or + wrong = "typcial" and right = "typical" + or + wrong = "typicaly" and right = "typically" + or + wrong = "tyranies" and right = "tyrannies" + or + wrong = "tyrany" and right = "tyranny" + or + wrong = "tyrranies" and right = "tyrannies" + or + wrong = "tyrrany" and right = "tyranny" + or + wrong = "ubiquitious" and right = "ubiquitous" + or + wrong = "ublisher" and right = "publisher" + or + wrong = "udpate" and right = "update" + or + wrong = "uise" and right = "use" + or + wrong = "ukranian" and right = "ukrainian" + or + wrong = "ultimely" and right = "ultimately" + or + wrong = "unacompanied" and right = "unaccompanied" + or + wrong = "unahppy" and right = "unhappy" + or + wrong = "unanymous" and right = "unanimous" + or + wrong = "unathorised" and right = "unauthorised" + or + wrong = "unavailible" and right = "unavailable" + or + wrong = "unballance" and right = "unbalance" + or + wrong = "unbeknowst" and right = "unbeknownst" + or + wrong = "unbeleivable" and right = "unbelievable" + or + wrong = "uncertainity" and right = "uncertainty" + or + wrong = "unchallengable" and right = "unchallengeable" + or + wrong = "unchangable" and right = "unchangeable" + or + wrong = "uncompetive" and right = "uncompetitive" + or + wrong = "unconcious" and right = "unconscious" + or + wrong = "unconciousness" and right = "unconsciousness" + or + wrong = "unconfortability" and right = "discomfort" + or + wrong = "uncontitutional" and right = "unconstitutional" + or + wrong = "unconvential" and right = "unconventional" + or + wrong = "undecideable" and right = "undecidable" + or + wrong = "understoon" and right = "understood" + or + wrong = "undesireable" and right = "undesirable" + or + wrong = "undetecable" and right = "undetectable" + or + wrong = "undoubtely" and right = "undoubtedly" + or + wrong = "undreground" and right = "underground" + or + wrong = "uneccesary" and right = "unnecessary" + or + wrong = "unecessary" and right = "unnecessary" + or + wrong = "unequalities" and right = "inequalities" + or + wrong = "unforetunately" and right = "unfortunately" + or + wrong = "unforgetable" and right = "unforgettable" + or + wrong = "unforgiveable" and right = "unforgivable" + or + wrong = "unforseen" and right = "unforeseen" + or + wrong = "unfortunatley" and right = "unfortunately" + or + wrong = "unfortunatly" and right = "unfortunately" + or + wrong = "unfourtunately" and right = "unfortunately" + or + wrong = "unihabited" and right = "uninhabited" + or + wrong = "unilateraly" and right = "unilaterally" + or + wrong = "unilatreal" and right = "unilateral" + or + wrong = "unilatreally" and right = "unilaterally" + or + wrong = "uninterruped" and right = "uninterrupted" + or + wrong = "uninterupted" and right = "uninterrupted" + or + wrong = "unintialized" and right = "uninitialized" + or + wrong = "unitesstates" and right = "unitedstates" + or + wrong = "univeral" and right = "universal" + or + wrong = "univeristies" and right = "universities" + or + wrong = "univeristy" and right = "university" + or + wrong = "univerity" and right = "university" + or + wrong = "universtiy" and right = "university" + or + wrong = "univesities" and right = "universities" + or + wrong = "univesity" and right = "university" + or + wrong = "unkown" and right = "unknown" + or + wrong = "unlikey" and right = "unlikely" + or + wrong = "unmanouverable" and right = "unmaneuverable" + or + wrong = "unmanouverable" and right = "unmanoeuvrable" + or + wrong = "unmistakeably" and right = "unmistakably" + or + wrong = "unneccesarily" and right = "unnecessarily" + or + wrong = "unneccesary" and right = "unnecessary" + or + wrong = "unneccessarily" and right = "unnecessarily" + or + wrong = "unneccessary" and right = "unnecessary" + or + wrong = "unnecesarily" and right = "unnecessarily" + or + wrong = "unnecesary" and right = "unnecessary" + or + wrong = "unoffical" and right = "unofficial" + or + wrong = "unoperational" and right = "nonoperational" + or + wrong = "unoticeable" and right = "unnoticeable" + or + wrong = "unplease" and right = "displease" + or + wrong = "unplesant" and right = "unpleasant" + or + wrong = "unprecendented" and right = "unprecedented" + or + wrong = "unprecidented" and right = "unprecedented" + or + wrong = "unrepentent" and right = "unrepentant" + or + wrong = "unrepetant" and right = "unrepentant" + or + wrong = "unrepetent" and right = "unrepentant" + or + wrong = "unsed" and right = "unsaid" + or + wrong = "unsed" and right = "unused" + or + wrong = "unsed" and right = "used" + or + wrong = "unsubstanciated" and right = "unsubstantiated" + or + wrong = "unsuccesful" and right = "unsuccessful" + or + wrong = "unsuccesfully" and right = "unsuccessfully" + or + wrong = "unsuccessfull" and right = "unsuccessful" + or + wrong = "unsucesful" and right = "unsuccessful" + or + wrong = "unsucesfuly" and right = "unsuccessfully" + or + wrong = "unsucessful" and right = "unsuccessful" + or + wrong = "unsucessfull" and right = "unsuccessful" + or + wrong = "unsucessfully" and right = "unsuccessfully" + or + wrong = "unsuprised" and right = "unsurprised" + or + wrong = "unsuprising" and right = "unsurprising" + or + wrong = "unsuprisingly" and right = "unsurprisingly" + or + wrong = "unsuprized" and right = "unsurprised" + or + wrong = "unsuprizing" and right = "unsurprising" + or + wrong = "unsuprizingly" and right = "unsurprisingly" + or + wrong = "unsurprized" and right = "unsurprised" + or + wrong = "unsurprizing" and right = "unsurprising" + or + wrong = "unsurprizingly" and right = "unsurprisingly" + or + wrong = "untill" and right = "until" + or + wrong = "untranslateable" and right = "untranslatable" + or + wrong = "unuseable" and right = "unusable" + or + wrong = "unusuable" and right = "unusable" + or + wrong = "unviersity" and right = "university" + or + wrong = "unwarrented" and right = "unwarranted" + or + wrong = "unweildly" and right = "unwieldy" + or + wrong = "unwieldly" and right = "unwieldy" + or + wrong = "upcomming" and right = "upcoming" + or + wrong = "upgradded" and right = "upgraded" + or + wrong = "usally" and right = "usually" + or + wrong = "useage" and right = "usage" + or + wrong = "usefull" and right = "useful" + or + wrong = "usefuly" and right = "usefully" + or + wrong = "useing" and right = "using" + or + wrong = "usualy" and right = "usually" + or + wrong = "ususally" and right = "usually" + or + wrong = "vaccum" and right = "vacuum" + or + wrong = "vaccume" and right = "vacuum" + or + wrong = "vacinity" and right = "vicinity" + or + wrong = "vaguaries" and right = "vagaries" + or + wrong = "vaieties" and right = "varieties" + or + wrong = "vailidty" and right = "validity" + or + wrong = "valetta" and right = "valletta" + or + wrong = "valuble" and right = "valuable" + or + wrong = "valueable" and right = "valuable" + or + wrong = "varations" and right = "variations" + or + wrong = "varient" and right = "variant" + or + wrong = "variey" and right = "variety" + or + wrong = "varing" and right = "varying" + or + wrong = "varities" and right = "varieties" + or + wrong = "varity" and right = "variety" + or + wrong = "vasall" and right = "vassal" + or + wrong = "vasalls" and right = "vassals" + or + wrong = "vaule" and right = "value" + or + wrong = "vegatarian" and right = "vegetarian" + or + wrong = "vegitable" and right = "vegetable" + or + wrong = "vegitables" and right = "vegetables" + or + wrong = "vegtable" and right = "vegetable" + or + wrong = "vehicule" and right = "vehicle" + or + wrong = "vell" and right = "well" + or + wrong = "venemous" and right = "venomous" + or + wrong = "vengance" and right = "vengeance" + or + wrong = "vengence" and right = "vengeance" + or + wrong = "verfication" and right = "verification" + or + wrong = "verison" and right = "version" + or + wrong = "verisons" and right = "versions" + or + wrong = "vermillion" and right = "vermilion" + or + wrong = "versitilaty" and right = "versatility" + or + wrong = "versitlity" and right = "versatility" + or + wrong = "vetween" and right = "between" + or + wrong = "veyr" and right = "very" + or + wrong = "vigeur" and right = "vigor" + or + wrong = "vigeur" and right = "vigour" + or + wrong = "vigeur" and right = "vigueur" + or + wrong = "vigilence" and right = "vigilance" + or + wrong = "vigourous" and right = "vigorous" + or + wrong = "villian" and right = "villain" + or + wrong = "villification" and right = "vilification" + or + wrong = "villify" and right = "vilify" + or + wrong = "villin" and right = "villain" + or + wrong = "villin" and right = "villein" + or + wrong = "villin" and right = "villi" + or + wrong = "vincinity" and right = "vicinity" + or + wrong = "violentce" and right = "violence" + or + wrong = "virtualy" and right = "virtually" + or + wrong = "virutal" and right = "virtual" + or + wrong = "virutally" and right = "virtually" + or + wrong = "visable" and right = "visible" + or + wrong = "visably" and right = "visibly" + or + wrong = "visting" and right = "visiting" + or + wrong = "vistors" and right = "visitors" + or + wrong = "vitories" and right = "victories" + or + wrong = "volcanoe" and right = "volcano" + or + wrong = "voleyball" and right = "volleyball" + or + wrong = "volontary" and right = "voluntary" + or + wrong = "volonteer" and right = "volunteer" + or + wrong = "volonteered" and right = "volunteered" + or + wrong = "volonteering" and right = "volunteering" + or + wrong = "volonteers" and right = "volunteers" + or + wrong = "volounteer" and right = "volunteer" + or + wrong = "volounteered" and right = "volunteered" + or + wrong = "volounteering" and right = "volunteering" + or + wrong = "volounteers" and right = "volunteers" + or + wrong = "volumne" and right = "volume" + or + wrong = "vreity" and right = "variety" + or + wrong = "vrey" and right = "very" + or + wrong = "vriety" and right = "variety" + or + wrong = "vulnerablility" and right = "vulnerability" + or + wrong = "vyer" and right = "very" + or + wrong = "vyre" and right = "very" + or + wrong = "waht" and right = "what" + or + wrong = "warantee" and right = "warranty" + or + wrong = "wardobe" and right = "wardrobe" + or + wrong = "warrent" and right = "warrant" + or + wrong = "warrriors" and right = "warriors" + or + wrong = "wass" and right = "was" + or + wrong = "watn" and right = "want" + or + wrong = "wayword" and right = "wayward" + or + wrong = "weaponary" and right = "weaponry" + or + wrong = "weas" and right = "was" + or + wrong = "wehn" and right = "when" + or + wrong = "weild" and right = "wield" + or + wrong = "weild" and right = "wild" + or + wrong = "weilded" and right = "wielded" + or + wrong = "wendsay" and right = "wednesday" + or + wrong = "wensday" and right = "wednesday" + or + wrong = "wereabouts" and right = "whereabouts" + or + wrong = "whant" and right = "want" + or + wrong = "whants" and right = "wants" + or + wrong = "whcih" and right = "which" + or + wrong = "wheras" and right = "whereas" + or + wrong = "wherease" and right = "whereas" + or + wrong = "whereever" and right = "wherever" + or + wrong = "whic" and right = "which" + or + wrong = "whihc" and right = "which" + or + wrong = "whith" and right = "with" + or + wrong = "whlch" and right = "which" + or + wrong = "whn" and right = "when" + or + wrong = "wholey" and right = "wholly" + or + wrong = "wholy" and right = "holy" + or + wrong = "wholy" and right = "wholly" + or + wrong = "whta" and right = "what" + or + wrong = "whther" and right = "whether" + or + wrong = "wich" and right = "which" + or + wrong = "wich" and right = "witch" + or + wrong = "widesread" and right = "widespread" + or + wrong = "wief" and right = "wife" + or + wrong = "wierd" and right = "weird" + or + wrong = "wiew" and right = "view" + or + wrong = "wih" and right = "with" + or + wrong = "wiht" and right = "with" + or + wrong = "wille" and right = "will" + or + wrong = "willingless" and right = "willingness" + or + wrong = "willk" and right = "will" + or + wrong = "wirting" and right = "writing" + or + wrong = "withdrawl" and right = "withdraw" + or + wrong = "withdrawl" and right = "withdrawal" + or + wrong = "witheld" and right = "withheld" + or + wrong = "withh" and right = "with" + or + wrong = "withing" and right = "within" + or + wrong = "withold" and right = "withhold" + or + wrong = "witht" and right = "with" + or + wrong = "witn" and right = "with" + or + wrong = "wiull" and right = "will" + or + wrong = "wnat" and right = "want" + or + wrong = "wnated" and right = "wanted" + or + wrong = "wnats" and right = "wants" + or + wrong = "wohle" and right = "whole" + or + wrong = "wokr" and right = "work" + or + wrong = "wokring" and right = "working" + or + wrong = "wonderfull" and right = "wonderful" + or + wrong = "wordlwide" and right = "worldwide" + or + wrong = "workststion" and right = "workstation" + or + wrong = "worls" and right = "world" + or + wrong = "worstened" and right = "worsened" + or + wrong = "woudl" and right = "would" + or + wrong = "wresters" and right = "wrestlers" + or + wrong = "wriet" and right = "write" + or + wrong = "writen" and right = "written" + or + wrong = "wroet" and right = "wrote" + or + wrong = "wrok" and right = "work" + or + wrong = "wroking" and right = "working" + or + wrong = "wtih" and right = "with" + or + wrong = "wupport" and right = "support" + or + wrong = "xenophoby" and right = "xenophobia" + or + wrong = "yaching" and right = "yachting" + or + wrong = "yaer" and right = "year" + or + wrong = "yaerly" and right = "yearly" + or + wrong = "yaers" and right = "years" + or + wrong = "yatch" and right = "yacht" + or + wrong = "yearm" and right = "year" + or + wrong = "yeasr" and right = "years" + or + wrong = "yeild" and right = "yield" + or + wrong = "yeilding" and right = "yielding" + or + wrong = "yementite" and right = "yemeni" + or + wrong = "yementite" and right = "yemenite" + or + wrong = "yera" and right = "year" + or + wrong = "yeras" and right = "years" + or + wrong = "yersa" and right = "years" + or + wrong = "yotube" and right = "youtube" + or + wrong = "youseff" and right = "yousef" + or + wrong = "youself" and right = "yourself" + or + wrong = "yrea" and right = "year" + or + wrong = "ytou" and right = "you" + or + wrong = "yuo" and right = "you" + or + wrong = "zeebra" and right = "zebra" +} diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml new file mode 100644 index 00000000000..f915e6407f8 --- /dev/null +++ b/shared/typos/qlpack.yml @@ -0,0 +1,4 @@ +name: codeql/typos +version: 0.0.1-dev +groups: shared +library: true From e69a8269ad8eb8a207726d0f8810277fc35e8a6f Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 8 Sep 2022 10:33:05 -0400 Subject: [PATCH 068/203] Move CleartextStorage test files into separate dir Move the files for the CleartextStorage tests into their own directory to avoid issues with extraction --- .../CWE-312/{ => android/CleartextStorage}/AndroidManifest.xml | 0 .../CleartextStorageAndroidDatabaseTest.expected | 0 .../CleartextStorage}/CleartextStorageAndroidDatabaseTest.java | 0 .../CleartextStorage}/CleartextStorageAndroidDatabaseTest.ql | 0 .../CleartextStorageAndroidFilesystemTest.expected | 0 .../CleartextStorageAndroidFilesystemTest.java | 0 .../CleartextStorage}/CleartextStorageAndroidFilesystemTest.ql | 0 .../CleartextStorage}/CleartextStorageSharedPrefsTest.expected | 0 .../CleartextStorage}/CleartextStorageSharedPrefsTest.java | 0 .../CleartextStorage}/CleartextStorageSharedPrefsTest.ql | 0 .../CleartextStorage}/CleartextStorageSharedPrefsTestKt.kt | 0 .../security/CWE-312/android/CleartextStorage/options | 2 ++ java/ql/test/query-tests/security/CWE-312/options | 2 -- 13 files changed, 2 insertions(+), 2 deletions(-) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/AndroidManifest.xml (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidDatabaseTest.expected (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidDatabaseTest.java (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidDatabaseTest.ql (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidFilesystemTest.expected (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidFilesystemTest.java (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageAndroidFilesystemTest.ql (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageSharedPrefsTest.expected (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageSharedPrefsTest.java (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageSharedPrefsTest.ql (100%) rename java/ql/test/query-tests/security/CWE-312/{ => android/CleartextStorage}/CleartextStorageSharedPrefsTestKt.kt (100%) create mode 100644 java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/options delete mode 100644 java/ql/test/query-tests/security/CWE-312/options diff --git a/java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/AndroidManifest.xml similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/AndroidManifest.xml rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/AndroidManifest.xml diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.expected rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.expected diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.java b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.java rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.java diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidDatabaseTest.ql rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidDatabaseTest.ql diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.expected rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.expected diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.java b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.java rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.java diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageAndroidFilesystemTest.ql rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageAndroidFilesystemTest.ql diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.expected b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.expected rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.java b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.java similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.java rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.java diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.ql b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTest.ql rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.ql diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTestKt.kt similarity index 100% rename from java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt rename to java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTestKt.kt diff --git a/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/options b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/options new file mode 100644 index 00000000000..250480dbe1a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/options @@ -0,0 +1,2 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/google-android-9.0.0 +// codeql-extractor-kotlin-options: ${testdir}/../../../../../stubs/google-android-9.0.0 diff --git a/java/ql/test/query-tests/security/CWE-312/options b/java/ql/test/query-tests/security/CWE-312/options deleted file mode 100644 index 93845c4b2a8..00000000000 --- a/java/ql/test/query-tests/security/CWE-312/options +++ /dev/null @@ -1,2 +0,0 @@ -// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 -// codeql-extractor-kotlin-options: ${testdir}/../../../stubs/google-android-9.0.0 From 59909751ae0385b34829e400f7970e0937ebc329 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Thu, 8 Sep 2022 10:34:17 -0400 Subject: [PATCH 069/203] Change allowBackup tests to use qlref test format Due to some limitations of comments in XML, it is simpler to implement the `android:allowBackup` tests using the qlref/expectations test format. --- .../backup/AllowBackupEnabledTest.expected | 2 ++ .../android/backup/AllowBackupEnabledTest.ql | 18 ------------------ .../backup/AllowBackupEnabledTest.qlref | 1 + .../TestExplicitlyEnabled/AndroidManifest.xml | 2 +- .../backup/TestMissing/AndroidManifest.xml | 2 +- .../security/CWE-312/android/backup/options | 2 ++ 6 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.qlref create mode 100644 java/ql/test/query-tests/security/CWE-312/android/backup/options diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected index e69de29bb2d..72deef0a120 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.expected @@ -0,0 +1,2 @@ +| TestExplicitlyEnabled/AndroidManifest.xml:6:5:27:19 | application | The 'android:allowBackup' attribute is enabled. | +| TestMissing/AndroidManifest.xml:6:5:27:19 | application | The 'android:allowBackup' attribute is enabled. | diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql deleted file mode 100644 index c79276402fe..00000000000 --- a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.ql +++ /dev/null @@ -1,18 +0,0 @@ -import java -import semmle.code.xml.AndroidManifest -import TestUtilities.InlineExpectationsTest - -class AllowBackupEnabledTest extends InlineExpectationsTest { - AllowBackupEnabledTest() { this = "AllowBackupEnabledTest" } - - override string getARelevantTag() { result = "hasAllowBackupEnabled" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasAllowedBackupEnabled" and - exists(AndroidApplicationXmlElement androidAppElem | androidAppElem.allowsBackup() | - androidAppElem.getAttribute("allowBackup").getLocation() = location and - element = androidAppElem.getAttribute("debuggable").toString() and - value = "" - ) - } -} diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.qlref b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.qlref new file mode 100644 index 00000000000..2b7a5375dab --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/AllowBackupEnabledTest.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml index 959c14c8507..4b69c52ccae 100644 --- a/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml +++ b/java/ql/test/query-tests/security/CWE-312/android/backup/TestExplicitlyEnabled/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" package="com.example.myapplication"> - - Date: Thu, 8 Sep 2022 13:38:19 +0200 Subject: [PATCH 070/203] find a main module in more cases --- .../javascript/NodeModuleResolutionImpl.qll | 22 +++++++++++++++---- .../UnsafeHtmlConstruction.expected | 18 +++++++++++++++ .../UnsafeHtmlConstruction/lib/package.json | 10 +++++++++ .../UnsafeHtmlConstruction/lib/src/MyNode.ts | 4 ++++ .../UnsafeHtmlConstruction/lib2/index.ts | 4 ++++ .../UnsafeHtmlConstruction/lib2/package.json | 10 +++++++++ .../UnsafeHtmlConstruction/lib2/src/MyNode.ts | 4 ++++ 7 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/package.json create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/src/MyNode.ts create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/index.ts create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/package.json create mode 100644 javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/src/MyNode.ts diff --git a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll index 7660d374216..674f9e916bf 100644 --- a/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll +++ b/javascript/ql/lib/semmle/javascript/NodeModuleResolutionImpl.qll @@ -93,14 +93,28 @@ private string getStem(string name) { result = name.regexpCapture("(.+?)(?:\\.([ * Gets the main module described by `pkg` with the given `priority`. */ File resolveMainModule(PackageJson pkg, int priority) { - exists(PathExpr main | main = MainModulePath::of(pkg, ".") | - result = main.resolve() and priority = 0 + exists(PathExpr main, int subPriority, string mainPath | + main = MainModulePath::of(pkg, mainPath) and + if mainPath = "." then subPriority = priority else priority = subPriority + 1000 + | + result = main.resolve() and subPriority = 0 or - result = tryExtensions(main.resolve(), "index", priority) + result = tryExtensions(main.resolve(), "index", subPriority) or not main.resolve() instanceof File and exists(int n | n = main.getNumComponent() | - result = tryExtensions(main.resolveUpTo(n - 1), getStem(main.getComponent(n - 1)), priority) + result = + tryExtensions(main.resolveUpTo(n - 1), getStem(main.getComponent(n - 1)), subPriority) + ) + or + // assuming the files get moved from one dir to another during compilation: + not exists(main.resolve()) and // didn't resolve + count(int i, string comp | comp = main.getComponent(i) and not comp = "." | i) = 2 and // is down one folder + exists(Folder subFolder | subFolder = pkg.getFile().getParentContainer().getAFolder() | + // is in one folder below the package.json, and has the right basename + result = + tryExtensions(subFolder, getStem(main.getComponent(main.getNumComponent() - 1)), + subPriority - 999) ) ) or diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index 1781accbe82..dfab0bdcf2b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -8,6 +8,14 @@ nodes | jquery-plugin.js:12:31:12:41 | options.foo | | jquery-plugin.js:14:31:14:35 | stuff | | jquery-plugin.js:14:31:14:35 | stuff | +| lib2/index.ts:1:28:1:28 | s | +| lib2/index.ts:1:28:1:28 | s | +| lib2/index.ts:2:29:2:29 | s | +| lib2/index.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | +| lib/src/MyNode.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:2:29:2:29 | s | | main.js:1:55:1:55 | s | | main.js:1:55:1:55 | s | | main.js:2:29:2:29 | s | @@ -96,6 +104,14 @@ edges | jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | | jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | | jquery-plugin.js:12:31:12:37 | options | jquery-plugin.js:12:31:12:41 | options.foo | +| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:29:2:29 | s | +| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:29:2:29 | s | +| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:29:2:29 | s | +| lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | +| lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | @@ -183,6 +199,8 @@ edges #select | jquery-plugin.js:12:31:12:41 | options.foo | jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:41 | options.foo | $@ based on $@ might later cause $@. | jquery-plugin.js:12:31:12:41 | options.foo | HTML construction | jquery-plugin.js:11:34:11:40 | options | library input | jquery-plugin.js:12:20:12:53 | " ... /span>" | cross-site scripting | | jquery-plugin.js:14:31:14:35 | stuff | jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | $@ based on $@ might later cause $@. | jquery-plugin.js:14:31:14:35 | stuff | HTML construction | jquery-plugin.js:11:27:11:31 | stuff | library input | jquery-plugin.js:14:20:14:47 | " ... /span>" | cross-site scripting | +| lib2/index.ts:2:29:2:29 | s | lib2/index.ts:1:28:1:28 | s | lib2/index.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | lib2/index.ts:2:29:2:29 | s | HTML construction | lib2/index.ts:1:28:1:28 | s | library input | lib2/index.ts:3:49:3:52 | html | cross-site scripting | +| lib/src/MyNode.ts:2:29:2:29 | s | lib/src/MyNode.ts:1:28:1:28 | s | lib/src/MyNode.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | lib/src/MyNode.ts:2:29:2:29 | s | HTML construction | lib/src/MyNode.ts:1:28:1:28 | s | library input | lib/src/MyNode.ts:3:49:3:52 | html | cross-site scripting | | main.js:2:29:2:29 | s | main.js:1:55:1:55 | s | main.js:2:29:2:29 | s | $@ based on $@ might later cause $@. | main.js:2:29:2:29 | s | HTML construction | main.js:1:55:1:55 | s | library input | main.js:3:49:3:52 | html | cross-site scripting | | main.js:7:49:7:49 | s | main.js:6:49:6:49 | s | main.js:7:49:7:49 | s | $@ based on $@ might later cause $@. | main.js:7:49:7:49 | s | XML parsing | main.js:6:49:6:49 | s | library input | main.js:8:48:8:66 | doc.documentElement | cross-site scripting | | main.js:12:49:12:49 | s | main.js:11:60:11:60 | s | main.js:12:49:12:49 | s | $@ based on $@ might later cause $@. | main.js:12:49:12:49 | s | XML parsing | main.js:11:60:11:60 | s | library input | main.js:16:21:16:35 | xml.cloneNode() | cross-site scripting | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/package.json b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/package.json new file mode 100644 index 00000000000..b849ee492e2 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/package.json @@ -0,0 +1,10 @@ +{ + "name": "my-unsafe-library", + "main": "./index.js", + "exports": { + "./MyNode": { + "require": "./lib/MyNode.cjs", + "import": "./lib/MyNode.mjs" + } + } +} \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/src/MyNode.ts b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/src/MyNode.ts new file mode 100644 index 00000000000..91e81238605 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib/src/MyNode.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // NOT OK + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/index.ts b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/index.ts new file mode 100644 index 00000000000..21bb420b71f --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/index.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // NOT OK - this file is recognized as a main file. + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/package.json b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/package.json new file mode 100644 index 00000000000..8c1cbff3c1d --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/package.json @@ -0,0 +1,10 @@ +{ + "name": "my-unsafe-library", + "main": "./foobar.js", + "exports": { + "./MyNode": { + "require": "./lib/MyNode.cjs", + "import": "./lib/MyNode.mjs" + } + } +} \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/src/MyNode.ts b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/src/MyNode.ts new file mode 100644 index 00000000000..35908c88f16 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/lib2/src/MyNode.ts @@ -0,0 +1,4 @@ +export function trivialXss(s: string) { + const html = "" + s + ""; // OK - this file is not recognized as a main file. + document.querySelector("#html").innerHTML = html; +} \ No newline at end of file From 83c8e22225bf38297e6fc2e89abad8f3a4646891 Mon Sep 17 00:00:00 2001 From: Edward Minnix III Date: Thu, 8 Sep 2022 15:55:00 -0400 Subject: [PATCH 071/203] Apply suggestions from documentation review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../CWE-312/AllowBackupAttributeEnabled.qhelp | 20 +++++++------------ .../CWE-312/AllowBackupAttributeEnabled.ql | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp index 8945f40172f..4f57a2659f0 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.qhelp @@ -3,35 +3,29 @@ "qhelp.dtd"> -

    The Android manifest file defines configuration settings for Android -applications. In this file, the android:allowBackup attribute of -the application element can be used to define whether or not the -application can have automatic backups.

    +

    In the Android manifest file, you can use the android:allowBackup attribute of the application element to define whether the +application will have automatic backups or not.

    -

    Enabling backups may allow an attacker to extract sensitive data. Therefore, -it is advised to set android:allowBackup to false if -your application uses any sensitive data.

    +

    If your application uses any sensitive data, you should disable automatic backups to prevent attackers from extracting it.

    -

    For Android applications which process sensitive data, set the -android:allowBackup setting to false in the manifest +

    For Android applications which process sensitive data, set android:allowBackup to false in the manifest file.

    -

    Note: Since Android 6.0 (Marshmallow), applications default to participating -in automatic backups. Therefore, it is necessary to explicitly disable backups. +

    Note: Since Android 6.0 (Marshmallow), automatic backups for applications are switched on by default.

    -

    In the two examples below, the android:allowBackup setting is enabled:

    +

    In the following two (bad) examples, the android:allowBackup setting is enabled:

    -

    A corrected version explicity sets android:allowBackup to false:

    +

    In the following (good) example, android:allowBackup is set to false:

    diff --git a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql index 89421289765..43827aeb081 100644 --- a/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-312/AllowBackupAttributeEnabled.ql @@ -1,6 +1,6 @@ /** * @name Android allowBackup attribute enabled - * @description Android manifests which do not disable the `android:allowBackup` attribute allow backups, which can store sensitive information. + * @description Enabling the `android:allowBackup` attribute may allow an attacker to extract sensitive data. * @kind problem * @problem.severity recommendation * @security-severity 7.5 From 1ec77136ec6717c584a86c83a55fdae59e17abfe Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 9 Sep 2022 08:37:38 +0200 Subject: [PATCH 072/203] depend on an explicit version of the typo database --- javascript/ql/src/qlpack.yml | 2 +- ql/ql/src/qlpack.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index a364849d264..cdc71881258 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -9,4 +9,4 @@ defaultSuiteFile: codeql-suites/javascript-code-scanning.qls dependencies: codeql/javascript-all: "*" codeql/suite-helpers: "*" - codeql/typos: "*" + codeql/typos: 0.0.1 diff --git a/ql/ql/src/qlpack.yml b/ql/ql/src/qlpack.yml index 9ee790bdfe5..4101674828b 100644 --- a/ql/ql/src/qlpack.yml +++ b/ql/ql/src/qlpack.yml @@ -6,4 +6,4 @@ suites: codeql-suites defaultSuiteFile: codeql-suites/ql-code-scanning.qls extractor: ql dependencies: - codeql/typos: "*" + codeql/typos: 0.0.1 From 26d8553f6e778595470b83ea28c6e4620acd5ce8 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Fri, 9 Sep 2022 10:28:57 +0200 Subject: [PATCH 073/203] ensure consistent casing of names --- .../aliased_ssa/internal/SSAConsistency.qll | 4 +- .../aliased_ssa/internal/SSAConstruction.qll | 5 +- .../implementation/internal/TInstruction.qll | 18 +++---- .../unaliased_ssa/internal/SSAConsistency.qll | 4 +- .../internal/SSAConstruction.qll | 5 +- .../lib/semmle/code/cil/CallableReturns.qll | 2 +- .../ql/lib/semmle/code/cil/Instructions.qll | 10 +++- .../internal/AliasedSSAStub.qll | 5 +- .../implementation/internal/TInstruction.qll | 18 +++---- .../unaliased_ssa/internal/SSAConsistency.qll | 4 +- .../internal/SSAConstruction.qll | 5 +- go/ql/lib/semmle/go/concepts/HTTP.qll | 9 ++-- go/ql/lib/semmle/go/frameworks/Beego.qll | 24 ++++----- go/ql/lib/semmle/go/frameworks/Echo.qll | 14 ++--- .../semmle/go/frameworks/ElazarlGoproxy.qll | 18 +++---- go/ql/lib/semmle/go/frameworks/Macaron.qll | 6 +-- go/ql/lib/semmle/go/frameworks/Revel.qll | 12 ++--- go/ql/lib/semmle/go/frameworks/Stdlib.qll | 5 +- .../semmle/go/frameworks/stdlib/NetHttp.qll | 38 ++++++------- .../OpenUrlRedirectCustomizations.qll | 6 +-- .../security/RequestForgeryCustomizations.qll | 2 +- .../go/security/SafeUrlFlowCustomizations.qll | 2 +- go/ql/lib/semmle/go/security/Xss.qll | 8 +-- .../CWE-020/IncompleteHostnameRegexp.ql | 6 +-- .../Security/CWE-209/StackTraceExposure.ql | 2 +- go/ql/src/experimental/CWE-918/SSRF.qll | 2 +- .../CWE-942/CorsMisconfiguration.ql | 4 +- .../src/experimental/frameworks/CleverGo.qll | 28 +++++----- go/ql/src/experimental/frameworks/Fiber.qll | 16 +++--- .../frameworks/CleverGo/HeaderWrite.ql | 6 +-- .../frameworks/CleverGo/HttpRedirect.ql | 2 +- .../frameworks/CleverGo/HttpResponseBody.ql | 2 +- .../frameworks/Fiber/HeaderWrite.ql | 6 +-- .../experimental/frameworks/Fiber/Redirect.ql | 2 +- .../frameworks/Fiber/ResponseBody.ql | 2 +- .../semmle/go/concepts/HTTP/Handler.ql | 2 +- .../semmle/go/concepts/HTTP/Header.ql | 2 +- .../semmle/go/concepts/HTTP/RequestBody.ql | 2 +- .../semmle/go/concepts/HTTP/ResponseBody.ql | 2 +- .../go/frameworks/ElazarlGoproxy/test.ql | 2 +- .../semmle/go/frameworks/Macaron/Redirect.ql | 2 +- .../semmle/go/frameworks/Revel/test.ql | 2 +- .../NosqlInjectionATM.qll | 4 +- .../ql/lib/semmle/javascript/ApiGraphs.qll | 2 +- .../lib/semmle/javascript/RangeAnalysis.qll | 4 +- .../ql/lib/semmle/javascript/Routing.qll | 12 ++--- javascript/ql/lib/semmle/javascript/SSA.qll | 5 +- .../javascript/dataflow/Configuration.qll | 4 +- .../semmle/javascript/dataflow/Sources.qll | 2 +- .../javascript/frameworks/ClientRequests.qll | 2 +- .../semmle/javascript/frameworks/Connect.qll | 6 +-- .../frameworks/ConnectExpressShared.qll | 2 +- .../javascript/frameworks/CookieLibraries.qll | 2 +- .../semmle/javascript/frameworks/Express.qll | 54 +++++++++---------- .../javascript/frameworks/ExpressModules.qll | 30 +++++------ .../semmle/javascript/frameworks/Fastify.qll | 30 +++++------ .../semmle/javascript/frameworks/Firebase.qll | 4 +- .../lib/semmle/javascript/frameworks/HTTP.qll | 9 ++-- .../lib/semmle/javascript/frameworks/Hapi.qll | 26 ++++----- .../lib/semmle/javascript/frameworks/Koa.qll | 26 ++++----- .../javascript/frameworks/LiveServer.qll | 4 +- .../semmle/javascript/frameworks/Logging.qll | 2 +- .../semmle/javascript/frameworks/Micro.qll | 24 ++++----- .../lib/semmle/javascript/frameworks/Nest.qll | 22 ++++---- .../lib/semmle/javascript/frameworks/Next.qll | 14 ++--- .../javascript/frameworks/NodeJSLib.qll | 42 +++++++-------- .../semmle/javascript/frameworks/Request.qll | 2 +- .../semmle/javascript/frameworks/Restify.qll | 16 +++--- .../javascript/frameworks/Templating.qll | 2 +- .../javascript/frameworks/WebSocket.qll | 12 ++--- .../heuristics/AdditionalRouteHandlers.qll | 8 +-- .../javascript/security/SensitiveActions.qll | 2 +- .../javascript/security/TaintedObject.qll | 2 +- .../javascript/security/UselessUseOfCat.qll | 2 +- .../CleartextStorageCustomizations.qll | 2 +- ...figurationForCredentialsCustomizations.qll | 8 +-- ...entKindsComparisonBypassCustomizations.qll | 4 +- ...tHeaderPoisoningInEmailGenerationQuery.qll | 2 +- .../dataflow/HttpToFileAccessSpecific.qll | 2 +- .../dataflow/ReflectedXssCustomizations.qll | 20 +++---- .../RemotePropertyInjectionCustomizations.qll | 2 +- .../ServerSideUrlRedirectCustomizations.qll | 6 +-- .../StackTraceExposureCustomizations.qll | 2 +- ...hroughParameterTamperingCustomizations.qll | 2 +- .../regexp/PolynomialReDoSCustomizations.qll | 4 +- .../Security/CWE-352/MissingCsrfMiddleware.ql | 6 +-- .../Security/CWE-451/MissingXFrameOptions.ql | 2 +- .../src/Security/CWE-598/SensitiveGetQuery.ql | 2 +- .../ql/src/Security/CWE-730/ServerCrash.ql | 4 +- javascript/ql/src/experimental/poi/PoI.qll | 10 ++-- .../analysis-quality/CandidateTracking.qll | 2 +- .../meta/analysis-quality/RouteHandlers.ql | 2 +- .../UnpromotedRouteHandlerCandidate.ql | 6 +-- .../UnpromotedRouteSetupCandidate.ql | 6 +-- .../Express/CookieMiddlewareInstance.qll | 2 +- .../frameworks/Express/HeaderAccess.qll | 2 +- .../frameworks/Express/HeaderDefinition.qll | 2 +- .../Express/HeaderDefinition_defines.qll | 2 +- .../HeaderDefinition_getAHeaderName.qll | 2 +- .../Express/HeaderDefinition_getNameExpr.qll | 2 +- .../frameworks/Express/RedirectInvocation.qll | 2 +- .../frameworks/Express/RequestExpr.qll | 2 +- .../frameworks/Express/RequestInputAccess.qll | 2 +- .../frameworks/Express/ResponseBody.qll | 2 +- .../frameworks/Express/ResponseExpr.qll | 2 +- .../Express/ResponseSendArgument.qll | 2 +- .../Express/RouteHandlerContainer.qll | 2 +- .../Express/RouteHandler_getARequestExpr.qll | 2 +- .../Express/RouteHandler_getAResponseExpr.qll | 2 +- .../RouteHandler_getAResponseHeader.qll | 2 +- .../Express/RouteSetup_getRequestMethod.qll | 2 +- .../RouterDefinition_getARouteHandler.qll | 2 +- .../frameworks/Express/SetCookie.qll | 2 +- .../frameworks/Firebase/tests.ql | 6 +-- .../AdditionalRouteHandlers.ql | 2 +- .../frameworks/HTTP-heuristics/tests.ql | 8 +-- .../frameworks/HTTP/RemoteRequestInput.ql | 2 +- .../frameworks/HTTP/ResponseBody.ql | 2 +- .../frameworks/Micro/TestMicro.ql | 14 ++--- .../library-tests/frameworks/Nest/test.ql | 12 ++--- .../frameworks/NodeJSLib/HeaderAccess.qll | 2 +- .../frameworks/NodeJSLib/HeaderDefinition.qll | 2 +- .../NodeJSLib/HeaderDefinition_defines.qll | 2 +- .../HeaderDefinition_getAHeaderName.qll | 2 +- .../HeaderDefinition_getNameExpr.qll | 2 +- .../frameworks/NodeJSLib/RequestExpr.qll | 2 +- .../NodeJSLib/RequestInputAccess.qll | 2 +- .../frameworks/NodeJSLib/ResponseExpr.qll | 2 +- .../NodeJSLib/ResponseSendArgument.qll | 2 +- .../RouteHandler_getARequestExpr.qll | 2 +- .../RouteHandler_getAResponseExpr.qll | 2 +- .../RouteHandler_getAResponseHeader.qll | 2 +- .../ServerDefinition_getARouteHandler.qll | 2 +- .../library-tests/frameworks/connect/tests.ql | 18 +++---- .../frameworks/fastify/HeaderAccess.qll | 2 +- .../frameworks/fastify/HeaderDefinition.qll | 2 +- .../fastify/HeaderDefinition_defines.qll | 2 +- .../HeaderDefinition_getAHeaderName.qll | 2 +- .../frameworks/fastify/RedirectInvocation.qll | 2 +- .../frameworks/fastify/RequestInputAccess.qll | 2 +- .../fastify/ResponseSendArgument.qll | 2 +- .../fastify/RouteHandler_getARequestExpr.qll | 2 +- .../RouteHandler_getAResponseHeader.qll | 2 +- .../frameworks/hapi/HeaderAccess.qll | 2 +- .../frameworks/hapi/HeaderDefinition.qll | 2 +- .../hapi/HeaderDefinition_defines.qll | 2 +- .../hapi/HeaderDefinition_getAHeaderName.qll | 2 +- .../frameworks/hapi/RequestExpr.qll | 2 +- .../frameworks/hapi/RequestInputAccess.qll | 2 +- .../frameworks/hapi/ResponseExpr.qll | 2 +- .../hapi/RouteHandler_getARequestExpr.qll | 2 +- .../hapi/RouteHandler_getAResponseHeader.qll | 2 +- .../frameworks/koa/HeaderAccess.qll | 2 +- .../frameworks/koa/HeaderDefinition.qll | 2 +- .../koa/HeaderDefinition_defines.qll | 2 +- .../koa/HeaderDefinition_getAHeaderName.qll | 2 +- .../frameworks/koa/RedirectInvocation.qll | 2 +- .../frameworks/koa/RequestExpr.qll | 2 +- .../frameworks/koa/RequestInputAccess.qll | 2 +- .../frameworks/koa/ResponseExpr.qll | 2 +- .../frameworks/koa/ResponseSendArgument.qll | 2 +- .../koa/RouteHandler_getARequestExpr.qll | 2 +- .../koa/RouteHandler_getAResponseExpr.qll | 2 +- .../koa/RouteHandler_getAResponseHeader.qll | 2 +- .../frameworks/restify/HeaderDefinition.qll | 2 +- .../restify/HeaderDefinition_defines.qll | 2 +- .../HeaderDefinition_getAHeaderName.qll | 2 +- .../frameworks/restify/RequestExpr.qll | 2 +- .../frameworks/restify/RequestInputAccess.qll | 2 +- .../frameworks/restify/ResponseExpr.qll | 2 +- .../restify/RouteHandler_getARequestExpr.qll | 2 +- .../restify/RouteHandler_getAResponseExpr.qll | 2 +- .../RouteHandler_getAResponseHeader.qll | 2 +- python/ql/lib/semmle/python/Concepts.qll | 12 +++-- .../lib/semmle/python/frameworks/Aiohttp.qll | 26 ++++----- .../lib/semmle/python/frameworks/Django.qll | 54 +++++++++---------- .../lib/semmle/python/frameworks/FastApi.qll | 16 +++--- .../ql/lib/semmle/python/frameworks/Flask.qll | 16 +++--- .../ql/lib/semmle/python/frameworks/Httpx.qll | 8 +-- .../ql/lib/semmle/python/frameworks/Ldap.qll | 4 +- .../ql/lib/semmle/python/frameworks/Ldap3.qll | 2 +- .../lib/semmle/python/frameworks/Libtaxii.qll | 2 +- .../semmle/python/frameworks/Multidict.qll | 5 +- .../lib/semmle/python/frameworks/Pycurl.qll | 2 +- .../lib/semmle/python/frameworks/Requests.qll | 4 +- .../python/frameworks/RestFramework.qll | 8 +-- .../semmle/python/frameworks/Starlette.qll | 7 ++- .../lib/semmle/python/frameworks/Stdlib.qll | 20 +++---- .../python/frameworks/Stdlib/Urllib.qll | 4 +- .../python/frameworks/Stdlib/Urllib2.qll | 4 +- .../lib/semmle/python/frameworks/Tornado.qll | 12 ++--- .../lib/semmle/python/frameworks/Twisted.qll | 12 ++--- .../lib/semmle/python/frameworks/Urllib3.qll | 2 +- .../ql/lib/semmle/python/frameworks/Yarl.qll | 2 +- .../CleartextStorageCustomizations.qll | 2 +- .../dataflow/LdapInjectionCustomizations.qll | 4 +- .../dataflow/ReflectedXSSCustomizations.qll | 2 +- ...ServerSideRequestForgeryCustomizations.qll | 6 +-- .../ServerSideRequestForgeryQuery.qll | 2 +- .../StackTraceExposureCustomizations.qll | 2 +- .../dataflow/UrlRedirectCustomizations.qll | 2 +- .../CWE-295/RequestWithoutValidation.ql | 2 +- .../CWE-352/CSRFProtectionDisabled.ql | 10 ++-- .../CWE-918/FullServerSideRequestForgery.ql | 2 +- .../PartialServerSideRequestForgery.ql | 2 +- .../experimental/semmle/python/Concepts.qll | 4 +- .../semmle/python/frameworks/Django.qll | 6 +-- python/ql/src/meta/alerts/RequestHandlers.ql | 2 +- .../test/experimental/meta/ConceptsTest.qll | 26 ++++----- ruby/ql/lib/codeql/ruby/Concepts.qll | 7 ++- .../ruby/frameworks/ActionController.qll | 8 +-- .../lib/codeql/ruby/frameworks/ActionView.qll | 2 +- .../codeql/ruby/frameworks/ActiveResource.qll | 4 +- .../ql/lib/codeql/ruby/frameworks/GraphQL.qll | 6 +-- .../ruby/frameworks/http_clients/Excon.qll | 2 +- .../ruby/frameworks/http_clients/Faraday.qll | 2 +- .../frameworks/http_clients/HttpClient.qll | 2 +- .../ruby/frameworks/http_clients/Httparty.qll | 2 +- .../ruby/frameworks/http_clients/NetHttp.qll | 2 +- .../ruby/frameworks/http_clients/OpenURI.qll | 4 +- .../frameworks/http_clients/RestClient.qll | 2 +- .../ruby/frameworks/http_clients/Typhoeus.qll | 2 +- .../security/HttpToFileAccessSpecific.qll | 4 +- .../InsecureDownloadCustomizations.qll | 6 +-- ...ServerSideRequestForgeryCustomizations.qll | 2 +- .../security/UrlRedirectCustomizations.qll | 2 +- .../cwe-295/RequestWithoutValidation.ql | 2 +- .../library-tests/frameworks/ActionView.ql | 2 +- .../frameworks/http_clients/HttpClients.ql | 2 +- .../Security/CWE-311/CleartextTransmission.ql | 4 +- 230 files changed, 702 insertions(+), 657 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll index 1c75529be00..873a3c635f8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ -private import SSAConstruction as SSA -import SSA::SsaConsistency +private import SSAConstruction as Ssa +import Ssa::SsaConsistency diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index 901735069c0..21c03e176a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -1135,7 +1135,7 @@ deprecated module SSAConsistency = SsaConsistency; * These predicates are all just aliases for predicates defined in the `Cached` module. This ensures * that all of SSA construction will be evaluated in the same stage. */ -module SSA { +module Ssa { class MemoryLocation = Alias::MemoryLocation; predicate hasPhiInstruction = Cached::hasPhiInstructionCached/2; @@ -1144,3 +1144,6 @@ module SSA { predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1; } + +/** DEPRECATED: Alias for Ssa */ +deprecated module SSA = Ssa; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll index b30372a791b..5564a16f215 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/TInstruction.qll @@ -20,24 +20,24 @@ newtype TInstruction = IRConstruction::Raw::hasInstruction(tag1, tag2) } or TUnaliasedSsaPhiInstruction( - TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation ) { - UnaliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + UnaliasedSsa::Ssa::hasPhiInstruction(blockStartInstr, memoryLocation) } or TUnaliasedSsaChiInstruction(TRawInstruction primaryInstruction) { none() } or TUnaliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { - UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc) + UnaliasedSsa::Ssa::hasUnreachedInstruction(irFunc) } or TAliasedSsaPhiInstruction( - TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, AliasedSsa::Ssa::MemoryLocation memoryLocation ) { - AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + AliasedSsa::Ssa::hasPhiInstruction(blockStartInstr, memoryLocation) } or TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) { - AliasedSsa::SSA::hasChiInstruction(primaryInstruction) + AliasedSsa::Ssa::hasChiInstruction(primaryInstruction) } or TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { - AliasedSsa::SSA::hasUnreachedInstruction(irFunc) + AliasedSsa::Ssa::hasUnreachedInstruction(irFunc) } /** @@ -50,7 +50,7 @@ module UnaliasedSsaInstructions { class TPhiInstruction = TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation ) { result = TUnaliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } @@ -83,7 +83,7 @@ module AliasedSsaInstructions { class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, AliasedSsa::Ssa::MemoryLocation memoryLocation ) { result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll index 1c75529be00..873a3c635f8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ -private import SSAConstruction as SSA -import SSA::SsaConsistency +private import SSAConstruction as Ssa +import Ssa::SsaConsistency diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 901735069c0..21c03e176a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -1135,7 +1135,7 @@ deprecated module SSAConsistency = SsaConsistency; * These predicates are all just aliases for predicates defined in the `Cached` module. This ensures * that all of SSA construction will be evaluated in the same stage. */ -module SSA { +module Ssa { class MemoryLocation = Alias::MemoryLocation; predicate hasPhiInstruction = Cached::hasPhiInstructionCached/2; @@ -1144,3 +1144,6 @@ module SSA { predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1; } + +/** DEPRECATED: Alias for Ssa */ +deprecated module SSA = Ssa; diff --git a/csharp/ql/lib/semmle/code/cil/CallableReturns.qll b/csharp/ql/lib/semmle/code/cil/CallableReturns.qll index 6a86ef72170..4cd46c10941 100644 --- a/csharp/ql/lib/semmle/code/cil/CallableReturns.qll +++ b/csharp/ql/lib/semmle/code/cil/CallableReturns.qll @@ -56,7 +56,7 @@ private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) { /** Holds if expression `expr` always evaluates to non-null. */ private predicate alwaysNotNullExpr(Expr expr) { - expr instanceof Opcodes::Newobj + expr instanceof Opcodes::NewObj or expr instanceof Literal and not expr instanceof NullLiteral or diff --git a/csharp/ql/lib/semmle/code/cil/Instructions.qll b/csharp/ql/lib/semmle/code/cil/Instructions.qll index 91bc1f37ea6..7d425594b8d 100644 --- a/csharp/ql/lib/semmle/code/cil/Instructions.qll +++ b/csharp/ql/lib/semmle/code/cil/Instructions.qll @@ -766,7 +766,7 @@ module Opcodes { } /** A `newobj` instruction. */ - class Newobj extends Call, @cil_newobj { + class NewObj extends Call, @cil_newobj { override string getOpcodeName() { result = "newobj" } override int getPushCount() { result = 1 } @@ -788,6 +788,9 @@ module Opcodes { } } + /** DEPRECATED: Alias for NewObj */ + deprecated class Newobj = NewObj; + /** An `initobj` instruction. */ class Initobj extends Instruction, @cil_initobj { override string getOpcodeName() { result = "initobj" } @@ -847,10 +850,13 @@ module Opcodes { } /** A `rethrow` instruction. */ - class Rethrow extends Throw, @cil_rethrow { + class ReThrow extends Throw, @cil_rethrow { override string getOpcodeName() { result = "rethrow" } } + /** DEPRECATED: Alias for ReThrow */ + deprecated class Rethrow = ReThrow; + /** A `ldlen` instruction. */ class Ldlen extends UnaryExpr, @cil_ldlen { override string getOpcodeName() { result = "ldlen" } diff --git a/csharp/ql/src/experimental/ir/implementation/internal/AliasedSSAStub.qll b/csharp/ql/src/experimental/ir/implementation/internal/AliasedSSAStub.qll index 0fedd38bfbd..6fca9e3b974 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/AliasedSSAStub.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/AliasedSSAStub.qll @@ -6,7 +6,7 @@ private import IRFunctionBase private import TInstruction -module SSA { +module Ssa { class MemoryLocation = boolean; predicate hasPhiInstruction(TRawInstruction blockStartInstr, MemoryLocation memoryLocation) { @@ -17,3 +17,6 @@ module SSA { predicate hasUnreachedInstruction(IRFunctionBase irFunc) { none() } } + +/** DEPRECATED: Alias for Ssa */ +deprecated module SSA = Ssa; diff --git a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll index b30372a791b..5564a16f215 100644 --- a/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/internal/TInstruction.qll @@ -20,24 +20,24 @@ newtype TInstruction = IRConstruction::Raw::hasInstruction(tag1, tag2) } or TUnaliasedSsaPhiInstruction( - TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation ) { - UnaliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + UnaliasedSsa::Ssa::hasPhiInstruction(blockStartInstr, memoryLocation) } or TUnaliasedSsaChiInstruction(TRawInstruction primaryInstruction) { none() } or TUnaliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { - UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc) + UnaliasedSsa::Ssa::hasUnreachedInstruction(irFunc) } or TAliasedSsaPhiInstruction( - TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, AliasedSsa::Ssa::MemoryLocation memoryLocation ) { - AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation) + AliasedSsa::Ssa::hasPhiInstruction(blockStartInstr, memoryLocation) } or TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) { - AliasedSsa::SSA::hasChiInstruction(primaryInstruction) + AliasedSsa::Ssa::hasChiInstruction(primaryInstruction) } or TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) { - AliasedSsa::SSA::hasUnreachedInstruction(irFunc) + AliasedSsa::Ssa::hasUnreachedInstruction(irFunc) } /** @@ -50,7 +50,7 @@ module UnaliasedSsaInstructions { class TPhiInstruction = TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, UnaliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation ) { result = TUnaliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } @@ -83,7 +83,7 @@ module AliasedSsaInstructions { class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction; TPhiInstruction phiInstruction( - TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation + TRawInstruction blockStartInstr, AliasedSsa::Ssa::MemoryLocation memoryLocation ) { result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation) } diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll index 1c75529be00..873a3c635f8 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConsistency.qll @@ -1,2 +1,2 @@ -private import SSAConstruction as SSA -import SSA::SsaConsistency +private import SSAConstruction as Ssa +import Ssa::SsaConsistency diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 901735069c0..21c03e176a5 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -1135,7 +1135,7 @@ deprecated module SSAConsistency = SsaConsistency; * These predicates are all just aliases for predicates defined in the `Cached` module. This ensures * that all of SSA construction will be evaluated in the same stage. */ -module SSA { +module Ssa { class MemoryLocation = Alias::MemoryLocation; predicate hasPhiInstruction = Cached::hasPhiInstructionCached/2; @@ -1144,3 +1144,6 @@ module SSA { predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1; } + +/** DEPRECATED: Alias for Ssa */ +deprecated module SSA = Ssa; diff --git a/go/ql/lib/semmle/go/concepts/HTTP.qll b/go/ql/lib/semmle/go/concepts/HTTP.qll index 89a716d4f1a..740611710a8 100644 --- a/go/ql/lib/semmle/go/concepts/HTTP.qll +++ b/go/ql/lib/semmle/go/concepts/HTTP.qll @@ -5,7 +5,7 @@ import go /** Provides classes for modeling HTTP-related APIs. */ -module HTTP { +module Http { /** Provides a class for modeling new HTTP response-writer APIs. */ module ResponseWriter { /** @@ -191,7 +191,7 @@ module HTTP { /** Gets a content-type associated with this body. */ string getAContentType() { - exists(HTTP::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() | + exists(Http::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() | hw.getHeaderName() = "content-type" and result = hw.getHeaderValue() ) @@ -201,7 +201,7 @@ module HTTP { /** Gets a dataflow node for a content-type associated with this body. */ DataFlow::Node getAContentTypeNode() { - exists(HTTP::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() | + exists(Http::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() | hw.getHeaderName() = "content-type" and result = hw.getValue() ) @@ -378,3 +378,6 @@ module HTTP { predicate guardedBy(DataFlow::Node check) { self.guardedBy(check) } } } + +/** DEPRECATED: Alias for Http */ +deprecated module HTTP = Http; diff --git a/go/ql/lib/semmle/go/frameworks/Beego.qll b/go/ql/lib/semmle/go/frameworks/Beego.qll index edcf383c6be..6d927112584 100644 --- a/go/ql/lib/semmle/go/frameworks/Beego.qll +++ b/go/ql/lib/semmle/go/frameworks/Beego.qll @@ -114,7 +114,7 @@ module Beego { } } - private class BeegoOutputInstance extends HTTP::ResponseWriter::Range { + private class BeegoOutputInstance extends Http::ResponseWriter::Range { SsaWithFields v; BeegoOutputInstance() { @@ -131,7 +131,7 @@ module Beego { } } - private class BeegoHeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::MethodCallNode { + private class BeegoHeaderWrite extends Http::HeaderWrite::Range, DataFlow::MethodCallNode { string methodName; BeegoHeaderWrite() { @@ -142,7 +142,7 @@ module Beego { override DataFlow::Node getName() { methodName = "Header" and result = this.getArgument(0) } override string getHeaderName() { - result = HTTP::HeaderWrite::Range.super.getHeaderName() + result = Http::HeaderWrite::Range.super.getHeaderName() or methodName = "ContentType" and result = "content-type" } @@ -153,12 +153,12 @@ module Beego { else result = this.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { + override Http::ResponseWriter getResponseWriter() { result.(BeegoOutputInstance).getAHeaderObject() = this } } - private class BeegoResponseBody extends HTTP::ResponseBody::Range { + private class BeegoResponseBody extends Http::ResponseBody::Range { DataFlow::MethodCallNode call; string methodName; @@ -170,7 +170,7 @@ module Beego { methodName in ["Body", "JSON", "JSONP", "ServeFormatted", "XML", "YAML"] } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = call.getReceiver() } + override Http::ResponseWriter getResponseWriter() { result.getANode() = call.getReceiver() } override string getAContentType() { // Super-method provides content-types for `Body`, which requires us to search @@ -192,7 +192,7 @@ module Beego { } } - private class ControllerResponseBody extends HTTP::ResponseBody::Range { + private class ControllerResponseBody extends Http::ResponseBody::Range { string name; ControllerResponseBody() { @@ -203,7 +203,7 @@ module Beego { ) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } override string getAContentType() { // Actually SetData can serve JSON, XML or YAML depending on the incoming @@ -213,7 +213,7 @@ module Beego { } } - private class ContextResponseBody extends HTTP::ResponseBody::Range { + private class ContextResponseBody extends Http::ResponseBody::Range { string name; ContextResponseBody() { @@ -224,7 +224,7 @@ module Beego { ) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } // Neither method is likely to be used with well-typed data such as JSON output, // because there are better methods to do this. Assume the Content-Type could @@ -314,7 +314,7 @@ module Beego { } } - private class RedirectMethods extends HTTP::Redirect::Range, DataFlow::CallNode { + private class RedirectMethods extends Http::Redirect::Range, DataFlow::CallNode { string package; string className; @@ -333,7 +333,7 @@ module Beego { className = "Context" and result = this.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } private class UtilsTaintPropagators extends TaintTracking::FunctionModel { diff --git a/go/ql/lib/semmle/go/frameworks/Echo.qll b/go/ql/lib/semmle/go/frameworks/Echo.qll index df58b492b87..c4d243b504c 100644 --- a/go/ql/lib/semmle/go/frameworks/Echo.qll +++ b/go/ql/lib/semmle/go/frameworks/Echo.qll @@ -29,7 +29,7 @@ private module Echo { /** * Data from a `Context` interface method that is not generally exploitable for open-redirect attacks. */ - private class EchoContextRedirectUnexploitableSource extends HTTP::Redirect::UnexploitableSource { + private class EchoContextRedirectUnexploitableSource extends Http::Redirect::UnexploitableSource { EchoContextRedirectUnexploitableSource() { exists(DataFlow::MethodCallNode call, string methodName | methodName = ["FormValue", "FormParams", "FormFile", "MultipartForm", "Cookie", "Cookies"] and @@ -77,14 +77,14 @@ private module Echo { /** * `echo.Context` methods which set the content-type to `text/html` and write a result in one operation. */ - private class EchoHtmlOutputs extends HTTP::ResponseBody::Range { + private class EchoHtmlOutputs extends Http::ResponseBody::Range { EchoHtmlOutputs() { exists(Method m | m.hasQualifiedName(packagePath(), "Context", ["HTML", "HTMLBlob"]) | this = m.getACall().getArgument(1) ) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } override string getAContentType() { result = "text/html" } } @@ -92,7 +92,7 @@ private module Echo { /** * `echo.Context` methods which take a content-type as a parameter. */ - private class EchoParameterizedOutputs extends HTTP::ResponseBody::Range { + private class EchoParameterizedOutputs extends Http::ResponseBody::Range { DataFlow::CallNode callNode; EchoParameterizedOutputs() { @@ -101,7 +101,7 @@ private module Echo { ) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } override DataFlow::Node getAContentTypeNode() { result = callNode.getArgument(1) } } @@ -109,7 +109,7 @@ private module Echo { /** * The `echo.Context.Redirect` method. */ - private class EchoRedirectMethod extends HTTP::Redirect::Range, DataFlow::CallNode { + private class EchoRedirectMethod extends Http::Redirect::Range, DataFlow::CallNode { EchoRedirectMethod() { exists(Method m | m.hasQualifiedName(packagePath(), "Context", "Redirect") | this = m.getACall() @@ -118,6 +118,6 @@ private module Echo { override DataFlow::Node getUrl() { result = this.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } } diff --git a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll index 87c091fc3c5..42fb474a5f0 100644 --- a/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll +++ b/go/ql/lib/semmle/go/frameworks/ElazarlGoproxy.qll @@ -11,7 +11,7 @@ module ElazarlGoproxy { /** Gets the package name. */ string packagePath() { result = package("github.com/elazarl/goproxy", "") } - private class NewResponse extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class NewResponse extends Http::HeaderWrite::Range, DataFlow::CallNode { NewResponse() { this.getTarget().hasQualifiedName(packagePath(), "NewResponse") } override string getHeaderName() { this.definesHeader(result, _) } @@ -28,21 +28,21 @@ module ElazarlGoproxy { header = "content-type" and value = this.getArgument(1).getStringValue() } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } /** A body argument to a `NewResponse` call. */ - private class NewResponseBody extends HTTP::ResponseBody::Range { + private class NewResponseBody extends Http::ResponseBody::Range { NewResponse call; NewResponseBody() { this = call.getArgument(3) } override DataFlow::Node getAContentTypeNode() { result = call.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } - private class TextResponse extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class TextResponse extends Http::HeaderWrite::Range, DataFlow::CallNode { TextResponse() { this.getTarget().hasQualifiedName(packagePath(), "TextResponse") } override string getHeaderName() { this.definesHeader(result, _) } @@ -59,22 +59,22 @@ module ElazarlGoproxy { header = "content-type" and value = "text/plain" } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } /** A body argument to a `TextResponse` call. */ - private class TextResponseBody extends HTTP::ResponseBody::Range, TextResponse { + private class TextResponseBody extends Http::ResponseBody::Range, TextResponse { TextResponse call; TextResponseBody() { this = call.getArgument(2) } override DataFlow::Node getAContentTypeNode() { result = call.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } /** A handler attached to a goproxy proxy type. */ - private class ProxyHandler extends HTTP::RequestHandler::Range { + private class ProxyHandler extends Http::RequestHandler::Range { DataFlow::MethodCallNode handlerReg; ProxyHandler() { diff --git a/go/ql/lib/semmle/go/frameworks/Macaron.qll b/go/ql/lib/semmle/go/frameworks/Macaron.qll index a38b2b20da0..f107ec208ee 100644 --- a/go/ql/lib/semmle/go/frameworks/Macaron.qll +++ b/go/ql/lib/semmle/go/frameworks/Macaron.qll @@ -5,7 +5,7 @@ import go private module Macaron { - private class Context extends HTTP::ResponseWriter::Range { + private class Context extends Http::ResponseWriter::Range { SsaWithFields v; Context() { @@ -18,13 +18,13 @@ private module Macaron { override DataFlow::Node getANode() { result = v.similar().getAUse().getASuccessor*() } } - private class RedirectCall extends HTTP::Redirect::Range, DataFlow::MethodCallNode { + private class RedirectCall extends Http::Redirect::Range, DataFlow::MethodCallNode { RedirectCall() { this.getTarget().hasQualifiedName("gopkg.in/macaron.v1", "Context", "Redirect") } override DataFlow::Node getUrl() { result = this.getArgument(0) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } } } diff --git a/go/ql/lib/semmle/go/frameworks/Revel.qll b/go/ql/lib/semmle/go/frameworks/Revel.qll index 1ccad431b84..d006f46b2ee 100644 --- a/go/ql/lib/semmle/go/frameworks/Revel.qll +++ b/go/ql/lib/semmle/go/frameworks/Revel.qll @@ -114,7 +114,7 @@ module Revel { * We look particularly for html file extensions, since these are the only ones we currently have special rules * for (in particular, detecting XSS vulnerabilities). */ - private class ControllerRenderMethods extends HTTP::ResponseBody::Range { + private class ControllerRenderMethods extends Http::ResponseBody::Range { string contentType; ControllerRenderMethods() { @@ -149,7 +149,7 @@ module Revel { ) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } override string getAContentType() { result = contentType } } @@ -174,7 +174,7 @@ module Revel { * It is currently assumed that a tainted `value` in `Redirect(url, value)`, which calls `Sprintf(url, value)` * internally, cannot lead to an open redirect vulnerability. */ - private class ControllerRedirectMethod extends HTTP::Redirect::Range, DataFlow::CallNode { + private class ControllerRedirectMethod extends Http::Redirect::Range, DataFlow::CallNode { ControllerRedirectMethod() { exists(Method m | m.hasQualifiedName(packagePath(), "Controller", "Redirect") | this = m.getACall() @@ -183,7 +183,7 @@ module Revel { override DataFlow::Node getUrl() { result = this.getArgument(0) } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } } /** @@ -226,7 +226,7 @@ module Revel { /** * A write to a template argument field that is read raw inside of a template. */ - private class RawTemplateArgument extends HTTP::TemplateResponseBody::Range { + private class RawTemplateArgument extends Http::TemplateResponseBody::Range { RawTemplateRead read; RawTemplateArgument() { @@ -261,7 +261,7 @@ module Revel { override string getAContentType() { result = "text/html" } - override HTTP::ResponseWriter getResponseWriter() { none() } + override Http::ResponseWriter getResponseWriter() { none() } override HtmlTemplate::TemplateRead getRead() { result = read } } diff --git a/go/ql/lib/semmle/go/frameworks/Stdlib.qll b/go/ql/lib/semmle/go/frameworks/Stdlib.qll index b8481175216..db46167d205 100644 --- a/go/ql/lib/semmle/go/frameworks/Stdlib.qll +++ b/go/ql/lib/semmle/go/frameworks/Stdlib.qll @@ -128,7 +128,7 @@ module IntegerParser { } /** Provides models of commonly used functions in the `net/url` package. */ -module URL { +module Url { /** The `PathEscape` or `QueryEscape` function. */ class Escaper extends TaintTracking::FunctionModel { Escaper() { @@ -263,3 +263,6 @@ module URL { } } } + +/** DEPRECATED: Alias for Url */ +deprecated module URL = Url; diff --git a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll index c5e48e7d295..e0518ecf465 100644 --- a/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll +++ b/go/ql/lib/semmle/go/frameworks/stdlib/NetHttp.qll @@ -35,7 +35,7 @@ module NetHttp { } /** The declaration of a variable which either is or has a field that implements the http.ResponseWriter type */ - private class StdlibResponseWriter extends HTTP::ResponseWriter::Range { + private class StdlibResponseWriter extends Http::ResponseWriter::Range { SsaWithFields v; StdlibResponseWriter() { @@ -52,7 +52,7 @@ module NetHttp { } } - private class HeaderWriteCall extends HTTP::HeaderWrite::Range, DataFlow::MethodCallNode { + private class HeaderWriteCall extends Http::HeaderWrite::Range, DataFlow::MethodCallNode { HeaderWriteCall() { this.getTarget().hasQualifiedName("net/http", "Header", "Add") or this.getTarget().hasQualifiedName("net/http", "Header", "Set") @@ -62,7 +62,7 @@ module NetHttp { override DataFlow::Node getValue() { result = this.getArgument(1) } - override HTTP::ResponseWriter getResponseWriter() { + override Http::ResponseWriter getResponseWriter() { // find `v` in // ``` // header := v.Header() @@ -72,7 +72,7 @@ module NetHttp { } } - private class MapWrite extends HTTP::HeaderWrite::Range, DataFlow::Node { + private class MapWrite extends Http::HeaderWrite::Range, DataFlow::Node { Write write; DataFlow::Node index; DataFlow::Node rhs; @@ -86,7 +86,7 @@ module NetHttp { override DataFlow::Node getValue() { result = rhs } - override HTTP::ResponseWriter getResponseWriter() { + override Http::ResponseWriter getResponseWriter() { // find `v` in // ``` // header := v.Header() @@ -96,7 +96,7 @@ module NetHttp { } } - private class ResponseWriteHeaderCall extends HTTP::HeaderWrite::Range, DataFlow::MethodCallNode { + private class ResponseWriteHeaderCall extends Http::HeaderWrite::Range, DataFlow::MethodCallNode { ResponseWriteHeaderCall() { this.getTarget().implements("net/http", "ResponseWriter", "WriteHeader") } @@ -107,10 +107,10 @@ module NetHttp { override DataFlow::Node getValue() { result = this.getArgument(0) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } } - private class ResponseErrorCall extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class ResponseErrorCall extends Http::HeaderWrite::Range, DataFlow::CallNode { ResponseErrorCall() { this.getTarget().hasQualifiedName("net/http", "Error") } override string getHeaderName() { result = "status" } @@ -119,10 +119,10 @@ module NetHttp { override DataFlow::Node getValue() { result = this.getArgument(2) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getArgument(0) } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getArgument(0) } } - private class RequestBody extends HTTP::RequestBody::Range, DataFlow::ExprNode { + private class RequestBody extends Http::RequestBody::Range, DataFlow::ExprNode { RequestBody() { exists(Function newRequest | newRequest.hasQualifiedName("net/http", "NewRequest") and @@ -137,7 +137,7 @@ module NetHttp { } } - private class ResponseBody extends HTTP::ResponseBody::Range, DataFlow::ArgumentNode { + private class ResponseBody extends Http::ResponseBody::Range, DataFlow::ArgumentNode { DataFlow::Node responseWriter; ResponseBody() { @@ -156,19 +156,19 @@ module NetHttp { ) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = responseWriter } + override Http::ResponseWriter getResponseWriter() { result.getANode() = responseWriter } } - private class RedirectCall extends HTTP::Redirect::Range, DataFlow::CallNode { + private class RedirectCall extends Http::Redirect::Range, DataFlow::CallNode { RedirectCall() { this.getTarget().hasQualifiedName("net/http", "Redirect") } override DataFlow::Node getUrl() { result = this.getArgument(2) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getArgument(0) } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getArgument(0) } } /** A call to a function in the `net/http` package that performs an HTTP request to a URL. */ - private class RequestCall extends HTTP::ClientRequest::Range, DataFlow::CallNode { + private class RequestCall extends Http::ClientRequest::Range, DataFlow::CallNode { RequestCall() { exists(string functionName | ( @@ -185,7 +185,7 @@ module NetHttp { } /** A call to the Client.Do function in the `net/http` package. */ - private class ClientDo extends HTTP::ClientRequest::Range, DataFlow::MethodCallNode { + private class ClientDo extends Http::ClientRequest::Range, DataFlow::MethodCallNode { ClientDo() { this.getTarget().hasQualifiedName("net/http", "Client", "Do") } override DataFlow::Node getUrl() { @@ -212,7 +212,7 @@ module NetHttp { } /** A call to the `Transport.RoundTrip` function in the `net/http` package. */ - private class TransportRoundTrip extends HTTP::ClientRequest::Range, DataFlow::MethodCallNode { + private class TransportRoundTrip extends Http::ClientRequest::Range, DataFlow::MethodCallNode { TransportRoundTrip() { this.getTarget().hasQualifiedName("net/http", "Transport", "RoundTrip") } override DataFlow::Node getUrl() { @@ -239,7 +239,7 @@ module NetHttp { } /** Fields and methods of `net/http.Request` that are not generally exploitable in an open-redirect attack. */ - private class RedirectUnexploitableRequestFields extends HTTP::Redirect::UnexploitableSource { + private class RedirectUnexploitableRequestFields extends Http::Redirect::UnexploitableSource { RedirectUnexploitableRequestFields() { exists(Field f, string fieldName | f.hasQualifiedName("net/http", "Request", fieldName) and @@ -257,7 +257,7 @@ module NetHttp { } } - private class Handler extends HTTP::RequestHandler::Range { + private class Handler extends Http::RequestHandler::Range { DataFlow::CallNode handlerReg; Handler() { diff --git a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll index d883c3c0101..80b9bb4a126 100644 --- a/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll +++ b/go/ql/lib/semmle/go/security/OpenUrlRedirectCustomizations.qll @@ -56,7 +56,7 @@ module OpenUrlRedirect { UntrustedFlowAsSource() { // exclude some fields and methods of URLs that are generally not attacker-controllable for // open redirect exploits - not this instanceof HTTP::Redirect::UnexploitableSource + not this instanceof Http::Redirect::UnexploitableSource } } @@ -64,7 +64,7 @@ module OpenUrlRedirect { * An HTTP redirect, considered as a sink for `Configuration`. */ class RedirectSink extends Sink, DataFlow::Node { - RedirectSink() { this = any(HTTP::Redirect redir).getUrl() } + RedirectSink() { this = any(Http::Redirect redir).getUrl() } } /** @@ -73,7 +73,7 @@ module OpenUrlRedirect { */ class LocationHeaderSink extends Sink, DataFlow::Node { LocationHeaderSink() { - exists(HTTP::HeaderWrite hw | hw.getHeaderName() = "location" | this = hw.getValue()) + exists(Http::HeaderWrite hw | hw.getHeaderName() = "location" | this = hw.getValue()) } } diff --git a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll index b75b3503d55..b11157daa06 100644 --- a/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll +++ b/go/ql/lib/semmle/go/security/RequestForgeryCustomizations.qll @@ -48,7 +48,7 @@ module RequestForgery { * The URL of an HTTP request, viewed as a sink for request forgery. */ private class ClientRequestUrlAsSink extends Sink { - HTTP::ClientRequest request; + Http::ClientRequest request; ClientRequestUrlAsSink() { this = request.getUrl() } diff --git a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll index de0f95f8f3a..dbdb96a10a7 100644 --- a/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll +++ b/go/ql/lib/semmle/go/security/SafeUrlFlowCustomizations.qll @@ -27,7 +27,7 @@ module SafeUrlFlow { /** * A method on a `net/url.URL` that is considered unsafe to use. */ - private class UnsafeUrlMethod extends URL::UrlGetter { + private class UnsafeUrlMethod extends Url::UrlGetter { UnsafeUrlMethod() { this.getName() = "Query" } } diff --git a/go/ql/lib/semmle/go/security/Xss.qll b/go/ql/lib/semmle/go/security/Xss.qll index 2ed5c5761a7..e9301646f77 100644 --- a/go/ql/lib/semmle/go/security/Xss.qll +++ b/go/ql/lib/semmle/go/security/Xss.qll @@ -46,14 +46,14 @@ module SharedXss { * a content type that does not (case-insensitively) contain the string "html". This * is to prevent us from flagging plain-text or JSON responses as vulnerable. */ - class HttpResponseBodySink extends Sink, HTTP::ResponseBody { + class HttpResponseBodySink extends Sink, Http::ResponseBody { HttpResponseBodySink() { not nonHtmlContentType(this) } } /** * An expression that is rendered as part of a template. */ - class RawTemplateInstantiationSink extends HttpResponseBodySink, HTTP::TemplateResponseBody { + class RawTemplateInstantiationSink extends HttpResponseBodySink, Http::TemplateResponseBody { override string getSinkKind() { result = "rawtemplate" } override Locatable getAssociatedLoc() { result = this.getRead().getEnclosingTextNode() } @@ -62,7 +62,7 @@ module SharedXss { /** * Holds if `body` may send a response with a content type other than HTML. */ - private predicate nonHtmlContentType(HTTP::ResponseBody body) { + private predicate nonHtmlContentType(Http::ResponseBody body) { not htmlTypeSpecified(body) and ( exists(body.getAContentType()) @@ -90,7 +90,7 @@ module SharedXss { /** * Holds if `body` specifies the response's content type to be HTML. */ - private predicate htmlTypeSpecified(HTTP::ResponseBody body) { + private predicate htmlTypeSpecified(Http::ResponseBody body) { body.getAContentType().regexpMatch("(?i).*html.*") } diff --git a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql index a6ce8c8c8b6..4272d1cc27e 100644 --- a/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql +++ b/go/ql/src/Security/CWE-020/IncompleteHostnameRegexp.ql @@ -33,7 +33,7 @@ predicate isIncompleteHostNameRegexpPattern(string pattern, string hostPart) { /** Holds if `b` sets the HTTP status code (represented by a pseudo-header named `status`) */ predicate writesHttpError(ReachableBasicBlock b) { - forex(HTTP::HeaderWrite hw | + forex(Http::HeaderWrite hw | hw.getHeaderName() = "status" and hw.asInstruction().getBasicBlock() = b | exists(string code | code.matches("4__") or code.matches("5__") | @@ -65,7 +65,7 @@ DataFlow::Node getASafeHandler() { } /** Holds if `regexp` is used in a check before `handler` is called. */ -predicate regexpGuardsHandler(RegexpPattern regexp, HTTP::RequestHandler handler) { +predicate regexpGuardsHandler(RegexpPattern regexp, Http::RequestHandler handler) { handler.guardedBy(DataFlow::exprNode(regexp.getAUse().asExpr().getParent*())) } @@ -99,7 +99,7 @@ class Config extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof RegexpPattern and - forall(HTTP::RequestHandler handler | regexpGuardsHandler(sink, handler) | + forall(Http::RequestHandler handler | regexpGuardsHandler(sink, handler) | not handler = getASafeHandler() ) and not regexpGuardsError(sink) diff --git a/go/ql/src/Security/CWE-209/StackTraceExposure.ql b/go/ql/src/Security/CWE-209/StackTraceExposure.ql index a2005663784..369c8109d47 100644 --- a/go/ql/src/Security/CWE-209/StackTraceExposure.ql +++ b/go/ql/src/Security/CWE-209/StackTraceExposure.ql @@ -60,7 +60,7 @@ class StackTraceExposureConfig extends TaintTracking::Configuration { node = any(DebugStackFunction f).getACall().getResult() } - override predicate isSink(DataFlow::Node node) { node instanceof HTTP::ResponseBody } + override predicate isSink(DataFlow::Node node) { node instanceof Http::ResponseBody } override predicate isSanitizer(DataFlow::Node node) { // Sanitise everything controlled by an is-debug-mode check. diff --git a/go/ql/src/experimental/CWE-918/SSRF.qll b/go/ql/src/experimental/CWE-918/SSRF.qll index b7a408902d0..cf264c8c0b6 100644 --- a/go/ql/src/experimental/CWE-918/SSRF.qll +++ b/go/ql/src/experimental/CWE-918/SSRF.qll @@ -74,7 +74,7 @@ module ServerSideRequestForgery { * The URL of an HTTP request, viewed as a sink for request forgery. */ private class ClientRequestUrlAsSink extends Sink { - HTTP::ClientRequest request; + Http::ClientRequest request; ClientRequestUrlAsSink() { this = request.getUrl() } diff --git a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql index 4e4b452fb8e..372b1c21642 100644 --- a/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql +++ b/go/ql/src/experimental/CWE-942/CorsMisconfiguration.ql @@ -41,14 +41,14 @@ string headerAllowCredentials() { result = "Access-Control-Allow-Credentials".to /** * An `Access-Control-Allow-Origin` header write. */ -class AllowOriginHeaderWrite extends HTTP::HeaderWrite { +class AllowOriginHeaderWrite extends Http::HeaderWrite { AllowOriginHeaderWrite() { this.getHeaderName() = headerAllowOrigin() } } /** * An `Access-Control-Allow-Credentials` header write. */ -class AllowCredentialsHeaderWrite extends HTTP::HeaderWrite { +class AllowCredentialsHeaderWrite extends Http::HeaderWrite { AllowCredentialsHeaderWrite() { this.getHeaderName() = headerAllowCredentials() } } diff --git a/go/ql/src/experimental/frameworks/CleverGo.qll b/go/ql/src/experimental/frameworks/CleverGo.qll index c061c416b88..99d57a46189 100644 --- a/go/ql/src/experimental/frameworks/CleverGo.qll +++ b/go/ql/src/experimental/frameworks/CleverGo.qll @@ -174,7 +174,7 @@ private module CleverGo { /** * Models HTTP redirects. */ - private class HttpRedirect extends HTTP::Redirect::Range, DataFlow::CallNode { + private class HttpRedirect extends Http::Redirect::Range, DataFlow::CallNode { string package; DataFlow::Node urlNode; @@ -191,13 +191,13 @@ private module CleverGo { override DataFlow::Node getUrl() { result = urlNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } } /** * Models HTTP ResponseBody where the content-type is static and non-modifiable. */ - private class HttpResponseBodyStaticContentType extends HTTP::ResponseBody::Range { + private class HttpResponseBodyStaticContentType extends Http::ResponseBody::Range { string contentTypeString; DataFlow::Node receiverNode; @@ -209,7 +209,7 @@ private module CleverGo { override string getAContentType() { result = contentTypeString } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the body; the content-type is implicitly set. @@ -304,7 +304,7 @@ private module CleverGo { /** * Models HTTP ResponseBody where the content-type can be dynamically set by the caller. */ - private class HttpResponseBodyDynamicContentType extends HTTP::ResponseBody::Range { + private class HttpResponseBodyDynamicContentType extends Http::ResponseBody::Range { DataFlow::Node contentTypeNode; DataFlow::Node receiverNode; @@ -316,7 +316,7 @@ private module CleverGo { override DataFlow::Node getAContentTypeNode() { result = contentTypeNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the body; the content-type is a parameter. @@ -352,7 +352,7 @@ private module CleverGo { /** * Models HTTP ResponseBody where only the body is set. */ - private class HttpResponseBodyNoContentType extends HTTP::ResponseBody::Range { + private class HttpResponseBodyNoContentType extends Http::ResponseBody::Range { DataFlow::Node receiverNode; HttpResponseBodyNoContentType() { @@ -361,7 +361,7 @@ private module CleverGo { ) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the body. The content-type is not defined. @@ -394,7 +394,7 @@ private module CleverGo { * Models HTTP header writers. * The write is done with a call where you can set both the key and the value of the header. */ - private class HeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class HeaderWrite extends Http::HeaderWrite::Range, DataFlow::CallNode { DataFlow::Node receiverNode; DataFlow::Node headerNameNode; DataFlow::Node headerValueNode; @@ -407,7 +407,7 @@ private module CleverGo { override DataFlow::Node getValue() { result = headerValueNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets a header with a key-value combination. @@ -437,7 +437,7 @@ private module CleverGo { /** * Models an HTTP static content-type header setter. */ - private class StaticContentTypeHeaderSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class StaticContentTypeHeaderSetter extends Http::HeaderWrite::Range, DataFlow::CallNode { DataFlow::Node receiverNode; string valueString; @@ -453,7 +453,7 @@ private module CleverGo { override DataFlow::Node getValue() { none() } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the content-type header (implicit). @@ -494,7 +494,7 @@ private module CleverGo { /** * Models an HTTP dynamic content-type header setter. */ - private class DynamicContentTypeHeaderSetter extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class DynamicContentTypeHeaderSetter extends Http::HeaderWrite::Range, DataFlow::CallNode { DataFlow::Node receiverNode; DataFlow::Node valueNode; @@ -508,7 +508,7 @@ private module CleverGo { override DataFlow::Node getValue() { result = valueNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the content-type header via a parameter. diff --git a/go/ql/src/experimental/frameworks/Fiber.qll b/go/ql/src/experimental/frameworks/Fiber.qll index a3240a0b85a..3a7e71e204e 100644 --- a/go/ql/src/experimental/frameworks/Fiber.qll +++ b/go/ql/src/experimental/frameworks/Fiber.qll @@ -129,7 +129,7 @@ private module Fiber { /** * Models HTTP redirects. */ - private class Redirect extends HTTP::Redirect::Range, DataFlow::CallNode { + private class Redirect extends Http::Redirect::Range, DataFlow::CallNode { string package; DataFlow::Node urlNode; @@ -146,14 +146,14 @@ private module Fiber { override DataFlow::Node getUrl() { result = urlNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } + override Http::ResponseWriter getResponseWriter() { result.getANode() = this.getReceiver() } } /** * Models HTTP header writers. * The write is done with a call where you can set both the key and the value of the header. */ - private class HeaderWrite extends HTTP::HeaderWrite::Range, DataFlow::CallNode { + private class HeaderWrite extends Http::HeaderWrite::Range, DataFlow::CallNode { DataFlow::Node receiverNode; DataFlow::Node headerNameNode; DataFlow::Node headerValueNode; @@ -166,7 +166,7 @@ private module Fiber { override DataFlow::Node getValue() { result = headerValueNode } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets a header with a key-value combination. @@ -201,7 +201,7 @@ private module Fiber { /** * Models HTTP ResponseBody where the content-type is static and non-modifiable. */ - private class ResponseBodyStaticContentType extends HTTP::ResponseBody::Range { + private class ResponseBodyStaticContentType extends Http::ResponseBody::Range { string contentTypeString; DataFlow::Node receiverNode; @@ -213,7 +213,7 @@ private module Fiber { override string getAContentType() { result = contentTypeString } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the body; the content-type is implicitly set. @@ -248,7 +248,7 @@ private module Fiber { /** * Models HTTP ResponseBody where only the body is set. */ - private class ResponseBodyNoContentType extends HTTP::ResponseBody::Range { + private class ResponseBodyNoContentType extends Http::ResponseBody::Range { DataFlow::Node receiverNode; ResponseBodyNoContentType() { @@ -257,7 +257,7 @@ private module Fiber { ) } - override HTTP::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } + override Http::ResponseWriter getResponseWriter() { result.getANode() = receiverNode } } // Holds for a call that sets the body. The content-type is not defined. diff --git a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql index 3f33ae98248..20dc73705a8 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HeaderWrite.ql @@ -11,7 +11,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { // Dynamic key-value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( @@ -26,7 +26,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) or // Static key, dynamic value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( @@ -41,7 +41,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) or // Static key, static value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql index 5ceb813cec9..4b7bcb7823c 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpRedirect.ql @@ -9,7 +9,7 @@ class HttpRedirectTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "redirectUrl" and - exists(HTTP::Redirect rd | + exists(Http::Redirect rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and element = rd.getUrl().toString() and diff --git a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql index 33c3f94ec07..a2b3dc62167 100644 --- a/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql +++ b/go/ql/test/experimental/frameworks/CleverGo/HttpResponseBody.ql @@ -8,7 +8,7 @@ class HttpResponseBodyTest extends InlineExpectationsTest { override string getARelevantTag() { result = ["contentType", "responseBody"] } override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(HTTP::ResponseBody rd | + exists(Http::ResponseBody rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( diff --git a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql index d83883f45a7..0130172e7d0 100644 --- a/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql +++ b/go/ql/test/experimental/frameworks/Fiber/HeaderWrite.ql @@ -11,7 +11,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { // Dynamic key-value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( @@ -26,7 +26,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) or // Static key, dynamic value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( @@ -41,7 +41,7 @@ class HttpHeaderWriteTest extends InlineExpectationsTest { ) or // Static key, static value header: - exists(HTTP::HeaderWrite hw | + exists(Http::HeaderWrite hw | hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( diff --git a/go/ql/test/experimental/frameworks/Fiber/Redirect.ql b/go/ql/test/experimental/frameworks/Fiber/Redirect.ql index 68d5bee465c..37bb0f97bfb 100644 --- a/go/ql/test/experimental/frameworks/Fiber/Redirect.ql +++ b/go/ql/test/experimental/frameworks/Fiber/Redirect.ql @@ -9,7 +9,7 @@ class HttpRedirectTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "redirectUrl" and - exists(HTTP::Redirect rd | + exists(Http::Redirect rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and element = rd.getUrl().toString() and diff --git a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql index 4361b2fda6a..74a9008749d 100644 --- a/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql +++ b/go/ql/test/experimental/frameworks/Fiber/ResponseBody.ql @@ -8,7 +8,7 @@ class HttpResponseBodyTest extends InlineExpectationsTest { override string getARelevantTag() { result = ["contentType", "responseBody"] } override predicate hasActualResult(Location location, string element, string tag, string value) { - exists(HTTP::ResponseBody rd | + exists(Http::ResponseBody rd | rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and ( diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql index e0b0acd426b..c6972eba275 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Handler.ql @@ -8,7 +8,7 @@ class HttpHandler extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "handler" and - exists(HTTP::RequestHandler h, DataFlow::Node check | + exists(Http::RequestHandler h, DataFlow::Node check | element = h.toString() and value = check.toString() | h.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Header.ql b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Header.ql index e5449bf3e53..0ec82e5ad89 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/Header.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/Header.ql @@ -1,6 +1,6 @@ import go -from HTTP::HeaderWrite headerWrite, string name, string value, string definedName, string definedVal +from Http::HeaderWrite headerWrite, string name, string value, string definedName, string definedVal where ( name = headerWrite.getName().toString() diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/RequestBody.ql b/go/ql/test/library-tests/semmle/go/concepts/HTTP/RequestBody.ql index d49b7e95bb4..90d58b2db8d 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/RequestBody.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/RequestBody.ql @@ -1,4 +1,4 @@ import go -from HTTP::RequestBody rb +from Http::RequestBody rb select rb diff --git a/go/ql/test/library-tests/semmle/go/concepts/HTTP/ResponseBody.ql b/go/ql/test/library-tests/semmle/go/concepts/HTTP/ResponseBody.ql index d8d89b7f5bb..80394628bfc 100644 --- a/go/ql/test/library-tests/semmle/go/concepts/HTTP/ResponseBody.ql +++ b/go/ql/test/library-tests/semmle/go/concepts/HTTP/ResponseBody.ql @@ -1,4 +1,4 @@ import go -from HTTP::ResponseBody rb +from Http::ResponseBody rb select rb diff --git a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql index 106d28b48f5..0b07a0a20f0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/ElazarlGoproxy/test.ql @@ -23,7 +23,7 @@ class HeaderWriteTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "headerwrite" and - exists(HTTP::HeaderWrite hw, string name, string val | element = hw.toString() | + exists(Http::HeaderWrite hw, string name, string val | element = hw.toString() | hw.definesHeader(name, val) and value = name + ":" + val and hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Redirect.ql b/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Redirect.ql index 813ad53f2e0..c73e0dac04c 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Redirect.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Macaron/Redirect.ql @@ -1,4 +1,4 @@ import go -from HTTP::Redirect redir +from Http::Redirect redir select redir, redir.getResponseWriter() diff --git a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql index e3d2cd16be4..9d2b876d803 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql +++ b/go/ql/test/library-tests/semmle/go/frameworks/Revel/test.ql @@ -39,7 +39,7 @@ class HttpResponseBodyTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "responsebody" and - exists(HTTP::ResponseBody rb | + exists(Http::ResponseBody rb | rb.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and element = rb.toString() and diff --git a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll index 3acb5c315f7..ed1da2dc38b 100644 --- a/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll +++ b/javascript/ql/experimental/adaptivethreatmodeling/lib/experimental/adaptivethreatmodeling/NosqlInjectionATM.qll @@ -42,10 +42,10 @@ module SinkEndpointFilter { result = "modeled database access" or // Remove calls to APIs that aren't relevant to NoSQL injection - call.getReceiver() instanceof HTTP::RequestNode and + call.getReceiver() instanceof Http::RequestNode and result = "receiver is a HTTP request expression" or - call.getReceiver() instanceof HTTP::ResponseNode and + call.getReceiver() instanceof Http::ResponseNode and result = "receiver is a HTTP response expression" ) or diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index 909d5d22f98..72d5a50cebe 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -652,7 +652,7 @@ module API { exports(m, _, _) or exists(NodeModule nm | nm = mod | - exists(SSA::implicitInit([nm.getModuleVariable(), nm.getExportsVariable()])) + exists(Ssa::implicitInit([nm.getModuleVariable(), nm.getExportsVariable()])) ) ) } or diff --git a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll index 9d8b3967b1c..a385df662ce 100644 --- a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll +++ b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll @@ -103,7 +103,7 @@ module RangeAnalysis { * the given increment/decrement expression. */ private DataFlow::Node updateExprResult(UpdateExpr expr) { - result = DataFlow::ssaDefinitionNode(SSA::definition(expr)) + result = DataFlow::ssaDefinitionNode(Ssa::definition(expr)) or expr.isPrefix() and result = expr.flow() @@ -113,7 +113,7 @@ module RangeAnalysis { * Gets a data flow node holding the result of the given componund assignment. */ private DataFlow::Node compoundAssignResult(CompoundAssignExpr expr) { - result = DataFlow::ssaDefinitionNode(SSA::definition(expr)) + result = DataFlow::ssaDefinitionNode(Ssa::definition(expr)) or result = expr.flow() } diff --git a/javascript/ql/lib/semmle/javascript/Routing.qll b/javascript/ql/lib/semmle/javascript/Routing.qll index 96d3e0a7f51..a7e37c10743 100644 --- a/javascript/ql/lib/semmle/javascript/Routing.qll +++ b/javascript/ql/lib/semmle/javascript/Routing.qll @@ -282,7 +282,7 @@ module Routing { * Gets an HTTP method name which this node will accept, or nothing if the node accepts all HTTP methods, not * taking into account the context from ancestors or children nodes. */ - HTTP::RequestMethodName getOwnHttpMethod() { none() } // Overridden in subclass + Http::RequestMethodName getOwnHttpMethod() { none() } // Overridden in subclass private Node getAUseSiteInRouteSetup() { if this.getParent() instanceof RouteSetup @@ -383,7 +383,7 @@ module Routing { * Gets an HTTP request method name (in upper case) matched by this node, or nothing * if all HTTP request method names are accepted. */ - HTTP::RequestMethodName getHttpMethod() { none() } + Http::RequestMethodName getHttpMethod() { none() } } private class ValueNodeImpl extends Node, MkValueNode { @@ -407,7 +407,7 @@ module Routing { override string getRelativePath() { result = range.getRelativePath() } - override HTTP::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() } + override Http::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() } } private StepSummary routeStepSummary() { @@ -434,7 +434,7 @@ module Routing { or StepSummary::smallstep(result, this, routeStepSummary()) or - HTTP::routeHandlerStep(result, this) + Http::routeHandlerStep(result, this) or RouteHandlerTrackingStep::step(result, this) or @@ -599,7 +599,7 @@ module Routing { * Gets an HTTP request method name (in upper case) matched by this node, or nothing * if all HTTP request method names are accepted. */ - HTTP::RequestMethodName getHttpMethod() { none() } + Http::RequestMethodName getHttpMethod() { none() } /** * Holds if this route setup targets `router` and occurs at the given `cfgNode`. @@ -635,7 +635,7 @@ module Routing { override string getRelativePath() { result = range.getRelativePath() } - override HTTP::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() } + override Http::RequestMethodName getOwnHttpMethod() { result = range.getHttpMethod() } } /** diff --git a/javascript/ql/lib/semmle/javascript/SSA.qll b/javascript/ql/lib/semmle/javascript/SSA.qll index 8e60fb0c3e4..3ba64d0200d 100644 --- a/javascript/ql/lib/semmle/javascript/SSA.qll +++ b/javascript/ql/lib/semmle/javascript/SSA.qll @@ -737,7 +737,7 @@ class SsaRefinementNode extends SsaPseudoDefinition, TRefinement { } } -module SSA { +module Ssa { /** Gets the SSA definition corresponding to the implicit initialization of `v`. */ SsaImplicitInit implicitInit(SsaSourceVariable v) { result.getSourceVariable() = v } @@ -747,3 +747,6 @@ module SSA { /** Gets the SSA variable corresponding to `d`. */ SsaVariable variable(VarDef d) { result.getDefinition() = definition(d) } } + +/** DEPRECATED: Alias for Ssa */ +deprecated module SSA = Ssa; diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 9dcf6bb1913..2449f8a8eb8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -770,7 +770,7 @@ private class FlowStepThroughImport extends SharedFlowStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists(ImportSpecifier specifier | pred = DataFlow::valueNode(specifier) and - succ = DataFlow::ssaDefinitionNode(SSA::definition(specifier)) + succ = DataFlow::ssaDefinitionNode(Ssa::definition(specifier)) ) } } @@ -1777,7 +1777,7 @@ class MidPathNode extends PathNode, MkMidNode { SsaImplicitDefinition or // Skip SSA definition of parameter as its location coincides with the parameter node - nd = DataFlow::ssaDefinitionNode(SSA::definition(any(SimpleParameter p))) + nd = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p))) or // Skip to the top of big left-leaning string concatenation trees. nd = any(AddExpr add).flow() and diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll b/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll index c3cf7ab15a4..6e7f8bc3461 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll @@ -348,7 +348,7 @@ private class NodeModuleSourcesNodes extends SourceNode::Range { NodeModuleSourcesNodes() { exists(NodeModule m | - this = DataFlow::ssaDefinitionNode(SSA::implicitInit(v)) and + this = DataFlow::ssaDefinitionNode(Ssa::implicitInit(v)) and v = [m.getModuleVariable(), m.getExportsVariable()] ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll index e721508ff06..f570c9d3a38 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ClientRequests.qll @@ -112,7 +112,7 @@ module ClientRequest { /** * Gets the name of an HTTP request method, in all-lowercase. */ - private string httpMethodName() { result = any(HTTP::RequestMethodName m).toLowerCase() } + private string httpMethodName() { result = any(Http::RequestMethodName m).toLowerCase() } /** * Gets a model of an instance of the `request` library, or one of diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll b/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll index fe130648cd5..59518a2f4f3 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Connect.qll @@ -10,7 +10,7 @@ module Connect { /** * An expression that creates a new Connect server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode { + class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::CallNode { ServerDefinition() { // `app = connect()` this = DataFlow::moduleImport("connect").getAnInvocation() @@ -61,7 +61,7 @@ module Connect { /** * A call to a Connect method that sets up a route. */ - class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup { ServerDefinition server; RouteSetup() { @@ -125,7 +125,7 @@ module Connect { /** * An access to a user-controlled Connect request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess instanceof DataFlow::MethodCallNode { + private class RequestInputAccess extends Http::RequestInputAccess instanceof DataFlow::MethodCallNode { RequestNode request; string kind; diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll index f0ea2f03f68..87956ef38c8 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll @@ -115,7 +115,7 @@ module ConnectExpressShared { * * For example, this could be the function `function(req, res, next){...}`. */ - class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate { + class RouteHandlerCandidate extends Http::RouteHandlerCandidate { RouteHandlerCandidate() { matchesSignature(this, _) and not ( diff --git a/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll b/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll index 1efc7da5dc4..b78fd0834db 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/CookieLibraries.qll @@ -368,7 +368,7 @@ private class HttpCookieWrite extends CookieWrites::CookieWrite { string header; HttpCookieWrite() { - exists(HTTP::CookieDefinition setCookie | + exists(Http::CookieDefinition setCookie | this = setCookie.getHeaderArgument() and not this instanceof DataFlow::ArrayCreationNode or diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index 86abe01f5d6..a48b7d1719a 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -70,7 +70,7 @@ module Express { result = "param" or result = "all" or result = "use" or - result = any(HTTP::RequestMethodName m).toLowerCase() or + result = any(Http::RequestMethodName m).toLowerCase() or // deprecated methods result = "error" or result = "del" @@ -92,7 +92,7 @@ module Express { result = this.getArgument(0).getStringValue() } - override HTTP::RequestMethodName getHttpMethod() { result.toLowerCase() = this.getMethodName() } + override Http::RequestMethodName getHttpMethod() { result.toLowerCase() = this.getMethodName() } } /** @@ -136,7 +136,7 @@ module Express { /** * A call to an Express router method that sets up a route. */ - class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode { + class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::MethodCallNode { RouteSetup() { isRouter(this.getReceiver()) and this.getMethodName() = routeSetupMethodName() @@ -219,7 +219,7 @@ module Express { | result = succ.backtrack(t2, t) or - HTTP::routeHandlerStep(result, succ) and + Http::routeHandlerStep(result, succ) and t = t2 ) } @@ -233,7 +233,7 @@ module Express { * * Has no result for `use`, `all`, or `param` calls. */ - HTTP::RequestMethodName getRequestMethod() { result.toLowerCase() = this.getMethodName() } + Http::RequestMethodName getRequestMethod() { result.toLowerCase() = this.getMethodName() } /** * Holds if this registers a route for all request methods. @@ -260,7 +260,7 @@ module Express { /** * A call that sets up a Passport router that includes the request object. */ - private class PassportRouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode { + private class PassportRouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::CallNode { DataFlow::ModuleImportNode importNode; DataFlow::FunctionNode callback; @@ -285,7 +285,7 @@ module Express { /** * The callback given to passport in PassportRouteSetup. */ - private class PassportRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler, + private class PassportRouteHandler extends RouteHandler, Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { PassportRouteHandler() { this = any(PassportRouteSetup setup).getARouteHandler() } @@ -470,7 +470,7 @@ module Express { * but support for other kinds of route handlers can be added by implementing * additional subclasses of this class. */ - abstract class RouteHandler extends HTTP::RouteHandler { + abstract class RouteHandler extends Http::RouteHandler { /** * Gets the parameter of kind `kind` of this route handler. * @@ -501,7 +501,7 @@ module Express { /** * An Express route handler installed by a route setup. */ - class StandardRouteHandler extends RouteHandler, HTTP::Servers::StandardRouteHandler, + class StandardRouteHandler extends RouteHandler, Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { RouteSetup routeSetup; @@ -530,7 +530,7 @@ module Express { } /** An Express response source. */ - abstract class ResponseSource extends HTTP::Servers::ResponseSource { } + abstract class ResponseSource extends Http::Servers::ResponseSource { } /** * An Express response source, that is, the response parameter of a @@ -561,7 +561,7 @@ module Express { } /** An Express request source. */ - abstract class RequestSource extends HTTP::Servers::RequestSource { } + abstract class RequestSource extends Http::Servers::RequestSource { } /** * An Express request source, that is, the request parameter of a @@ -632,7 +632,7 @@ module Express { } /** The input parameter to an `app.param()` route handler. */ - private class ParamHandlerInputAccess extends HTTP::RequestInputAccess { + private class ParamHandlerInputAccess extends Http::RequestInputAccess { RouteHandler rh; ParamHandlerInputAccess() { @@ -641,7 +641,7 @@ module Express { ) } - override HTTP::RouteHandler getRouteHandler() { result = rh } + override Http::RouteHandler getRouteHandler() { result = rh } override string getKind() { result = "parameter" } } @@ -675,7 +675,7 @@ module Express { /** * An access to a user-controlled Express request input. */ - class RequestInputAccess extends HTTP::RequestInputAccess { + class RequestInputAccess extends Http::RequestInputAccess { RequestSource request; string kind; @@ -733,7 +733,7 @@ module Express { /** * An access to a header on an Express request. */ - private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { + private class RequestHeaderAccess extends Http::RequestHeaderAccess { RequestSource request; RequestHeaderAccess() { @@ -762,7 +762,7 @@ module Express { /** * HTTP headers created by Express calls */ - abstract private class ExplicitHeader extends HTTP::ExplicitHeaderDefinition { } + abstract private class ExplicitHeader extends Http::ExplicitHeaderDefinition { } /** * Holds if `e` is an HTTP request object. @@ -781,7 +781,7 @@ module Express { RequestBodyAccess() { any(RouteHandler h).getARequestBodyAccess() = this } } - abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { + abstract private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition { HeaderDefinition() { isResponse(this.getReceiver()) } override RouteHandler getRouteHandler() { this.getReceiver() = result.getAResponseNode() } @@ -790,7 +790,7 @@ module Express { /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode { + private class RedirectInvocation extends Http::RedirectInvocation, DataFlow::MethodCallNode { ResponseSource response; RedirectInvocation() { this = response.ref().getAMethodCall("redirect") } @@ -854,7 +854,7 @@ module Express { /** * An argument passed to the `send` or `end` method of an HTTP response object. */ - private class ResponseSendArgument extends HTTP::ResponseSendArgument { + private class ResponseSendArgument extends Http::ResponseSendArgument { ResponseSource response; ResponseSendArgument() { this = response.ref().getAMethodCall("send").getArgument(0) } @@ -865,7 +865,7 @@ module Express { /** * An invocation of the `cookie` method on an HTTP response object. */ - class SetCookie extends HTTP::CookieDefinition, DataFlow::MethodCallNode { + class SetCookie extends Http::CookieDefinition, DataFlow::MethodCallNode { ResponseSource response; SetCookie() { this = response.ref().getAMethodCall("cookie") } @@ -881,7 +881,7 @@ module Express { * An expression passed to the `render` method of an HTTP response object * as the value of a template variable. */ - private class TemplateInput extends HTTP::ResponseBody { + private class TemplateInput extends Http::ResponseBody { TemplateObjectInput obj; TemplateInput() { @@ -913,13 +913,13 @@ module Express { /** * An Express server application. */ - private class Application extends HTTP::ServerDefinition { + private class Application extends Http::ServerDefinition { Application() { this = appCreation() } /** * Gets a route handler of the application, regardless of nesting. */ - override HTTP::RouteHandler getARouteHandler() { + override Http::RouteHandler getARouteHandler() { result = this.(RouterDefinition).getASubRouter*().getARouteHandler() } } @@ -960,7 +960,7 @@ module Express { * * Example: `fun` for `router1.use(fun)` or `router.use("/route", fun)` */ - HTTP::RouteHandler getARouteHandler() { + Http::RouteHandler getARouteHandler() { result.(DataFlow::SourceNode).flowsTo(this.getARouteSetup().getAnArgument()) } @@ -1044,7 +1044,7 @@ module Express { * A function that flows to a route setup. */ private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler, - HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { RouteSetup routeSetup; TrackedRouteHandlerCandidateWithSetup() { this = routeSetup.getARouteHandler() } @@ -1063,14 +1063,14 @@ module Express { * `router.post(handler)` where it is unknown if `router` is an * Express router. */ - class RouteSetupCandidate extends HTTP::RouteSetupCandidate, DataFlow::MethodCallNode { + class RouteSetupCandidate extends Http::RouteSetupCandidate, DataFlow::MethodCallNode { DataFlow::ValueNode routeHandlerArg; RouteSetupCandidate() { exists(string methodName | methodName = "all" or methodName = "use" or - methodName = any(HTTP::RequestMethodName m).toLowerCase() + methodName = any(Http::RequestMethodName m).toLowerCase() | this.getMethodName() = methodName and exists(DataFlow::ValueNode arg | arg = this.getAnArgument() | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ExpressModules.qll b/javascript/ql/lib/semmle/javascript/frameworks/ExpressModules.qll index 64b4122fb46..6052d97cef8 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ExpressModules.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ExpressModules.qll @@ -18,25 +18,25 @@ module ExpressLibraries { /** * A header produced by a route handler of the "x-frame-options" module. */ - class XFrameOptionsRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition { + class XFrameOptionsRouteHandlerHeader extends Http::ImplicitHeaderDefinition { XFrameOptionsRouteHandlerHeader() { this instanceof XFrameOptionsRouteHandler } override predicate defines(string headerName, string headerValue) { xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue) } - override HTTP::RouteHandler getRouteHandler() { result = this } + override Http::RouteHandler getRouteHandler() { result = this } } /** * A route handler from the "x-frame-options" module. */ - class XFrameOptionsRouteHandler extends HTTP::RouteHandler { + class XFrameOptionsRouteHandler extends Http::RouteHandler { XFrameOptionsRouteHandler() { this = DataFlow::moduleImport("x-frame-options").getAnInvocation() } - override HTTP::HeaderDefinition getAResponseHeader(string name) { + override Http::HeaderDefinition getAResponseHeader(string name) { name = this.(XFrameOptionsRouteHandlerHeader).getAHeaderName() and result = this } @@ -45,23 +45,23 @@ module ExpressLibraries { /** * A header produced by a route handler of the "frameguard" module. */ - class FrameGuardRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition { + class FrameGuardRouteHandlerHeader extends Http::ImplicitHeaderDefinition { FrameGuardRouteHandlerHeader() { this instanceof FrameGuardRouteHandler } override predicate defines(string headerName, string headerValue) { xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue) } - override HTTP::RouteHandler getRouteHandler() { result = this } + override Http::RouteHandler getRouteHandler() { result = this } } /** * A route handler from the "frameguard" module. */ - class FrameGuardRouteHandler extends HTTP::RouteHandler { + class FrameGuardRouteHandler extends Http::RouteHandler { FrameGuardRouteHandler() { this = DataFlow::moduleImport("frameguard").getAnInvocation() } - override HTTP::HeaderDefinition getAResponseHeader(string name) { + override Http::HeaderDefinition getAResponseHeader(string name) { name = this.(FrameGuardRouteHandlerHeader).getAHeaderName() and result = this } @@ -70,20 +70,20 @@ module ExpressLibraries { /** * A header produced by a route handler of the "helmet" module. */ - class HelmetRouteHandlerHeader extends HTTP::ImplicitHeaderDefinition { + class HelmetRouteHandlerHeader extends Http::ImplicitHeaderDefinition { HelmetRouteHandlerHeader() { this instanceof HelmetRouteHandler } override predicate defines(string headerName, string headerValue) { xFrameOptionsDefaultImplicitHeaderDefinition(headerName, headerValue) } - override HTTP::RouteHandler getRouteHandler() { result = this } + override Http::RouteHandler getRouteHandler() { result = this } } /** * A route handler from the "helmet" module. */ - class HelmetRouteHandler extends HTTP::RouteHandler { + class HelmetRouteHandler extends Http::RouteHandler { HelmetRouteHandler() { exists(DataFlow::ModuleImportNode m | "helmet" = m.getPath() | this = m.getAnInvocation() or @@ -91,7 +91,7 @@ module ExpressLibraries { ) } - override HTTP::HeaderDefinition getAResponseHeader(string name) { + override Http::HeaderDefinition getAResponseHeader(string name) { name = this.(HelmetRouteHandlerHeader).getAHeaderName() and result = this } @@ -108,7 +108,7 @@ module ExpressLibraries { /** * A call that creates an `express-session` middleware instance. */ - class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance { + class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance { MiddlewareInstance() { this = expressSession().getACall() } /** @@ -135,7 +135,7 @@ module ExpressLibraries { /** * A call that creates a `cookie-parser` middleware instance. */ - class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance { + class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance { MiddlewareInstance() { this = cookieParser().getACall() } /** @@ -164,7 +164,7 @@ module ExpressLibraries { /** * A call that creates a `cookie-session` middleware instance. */ - class MiddlewareInstance extends DataFlow::InvokeNode, HTTP::CookieMiddlewareInstance { + class MiddlewareInstance extends DataFlow::InvokeNode, Http::CookieMiddlewareInstance { MiddlewareInstance() { this = cookieSession().getACall() } /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll index 76d1c9825b3..d12c4278601 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll @@ -12,7 +12,7 @@ module Fastify { /** * An expression that creates a new Fastify server. */ - abstract class ServerDefinition extends HTTP::Servers::StandardServerDefinition { } + abstract class ServerDefinition extends Http::Servers::StandardServerDefinition { } /** * A standard way to create a Fastify server. @@ -76,7 +76,7 @@ module Fastify { * but support for other kinds of route handlers can be added by implementing * additional subclasses of this class. */ - abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode { + abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::ValueNode { /** * Gets the parameter of the route handler that contains the request object. */ @@ -103,7 +103,7 @@ module Fastify { * A Fastify reply source, that is, the `reply` parameter of a * route handler. */ - private class ReplySource extends HTTP::Servers::ResponseSource { + private class ReplySource extends Http::Servers::ResponseSource { RouteHandler rh; ReplySource() { this = rh.getReplyParameter() } @@ -118,7 +118,7 @@ module Fastify { * A Fastify request source, that is, the request parameter of a * route handler. */ - private class RequestSource extends HTTP::Servers::RequestSource { + private class RequestSource extends Http::Servers::RequestSource { RouteHandler rh; RequestSource() { this = rh.getRequestParameter() } @@ -132,7 +132,7 @@ module Fastify { /** * A call to a Fastify method that sets up a route. */ - class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup { ServerDefinition server; string methodName; @@ -176,7 +176,7 @@ module Fastify { override string getRelativePath() { result = this.getArgument(0).getStringValue() } - override HTTP::RequestMethodName getHttpMethod() { result = this.getMethodName().toUpperCase() } + override Http::RequestMethodName getHttpMethod() { result = this.getMethodName().toUpperCase() } } /** Gets the name of the `n`th handler function that can be installed a route setup, in order of execution. */ @@ -194,7 +194,7 @@ module Fastify { override string getRelativePath() { result = this.getOptionArgument(0, "url").getStringValue() } - override HTTP::RequestMethodName getHttpMethod() { + override Http::RequestMethodName getHttpMethod() { result = this.getOptionArgument(0, "method").getStringValue().toUpperCase() } @@ -226,7 +226,7 @@ module Fastify { result = this.pluginBody(DataFlow::TypeBackTracker::end()) } - override HTTP::RequestMethodName getHttpMethod() { + override Http::RequestMethodName getHttpMethod() { result = this.getOptionArgument(1, "method").getStringValue().toUpperCase() } @@ -252,7 +252,7 @@ module Fastify { /** * An access to a user-controlled Fastify request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { + private class RequestInputAccess extends Http::RequestInputAccess { RouteHandler rh; string kind; @@ -308,7 +308,7 @@ module Fastify { /** * An access to a header on a Fastify request. */ - private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { + private class RequestHeaderAccess extends Http::RequestHeaderAccess { RouteHandler rh; RequestHeaderAccess() { @@ -327,7 +327,7 @@ module Fastify { /** * An argument passed to the `send` or `end` method of an HTTP response object. */ - private class ResponseSendArgument extends HTTP::ResponseSendArgument { + private class ResponseSendArgument extends Http::ResponseSendArgument { RouteHandler rh; ResponseSendArgument() { @@ -342,7 +342,7 @@ module Fastify { /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation, DataFlow::MethodCallNode { + private class RedirectInvocation extends Http::RedirectInvocation, DataFlow::MethodCallNode { RouteHandler rh; RedirectInvocation() { this = rh.getAResponseSource().ref().getAMethodCall("redirect") } @@ -355,7 +355,7 @@ module Fastify { /** * An invocation that sets a single header of the HTTP response. */ - private class SetOneHeader extends HTTP::Servers::StandardHeaderDefinition, + private class SetOneHeader extends Http::Servers::StandardHeaderDefinition, DataFlow::MethodCallNode { RouteHandler rh; @@ -370,7 +370,7 @@ module Fastify { /** * An invocation that sets any number of headers of the HTTP response. */ - class SetMultipleHeaders extends HTTP::ExplicitHeaderDefinition, DataFlow::MethodCallNode { + class SetMultipleHeaders extends Http::ExplicitHeaderDefinition, DataFlow::MethodCallNode { RouteHandler rh; SetMultipleHeaders() { @@ -414,7 +414,7 @@ module Fastify { override DataFlow::Node getTemplateParamsNode() { result = this.getArgument(1) } } - private class FastifyCookieMiddleware extends HTTP::CookieMiddlewareInstance { + private class FastifyCookieMiddleware extends Http::CookieMiddlewareInstance { FastifyCookieMiddleware() { this = DataFlow::moduleImport(["fastify-cookie", "fastify-session", "fastify-secure-session"]) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll b/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll index d22bb782630..35a8d329643 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Firebase.qll @@ -195,7 +195,7 @@ module Firebase { /** * A call to a Firebase method that sets up a route. */ - private class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::CallNode { + private class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::CallNode { RouteSetup() { this = namespace().getAPropertyRead("https").getAMemberCall("onRequest") } override DataFlow::SourceNode getARouteHandler() { @@ -215,7 +215,7 @@ module Firebase { /** * A function used as a route handler. */ - private class RouteHandler extends Express::RouteHandler, HTTP::Servers::StandardRouteHandler, + private class RouteHandler extends Express::RouteHandler, Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { RouteHandler() { this = any(RouteSetup setup).getARouteHandler() } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll index 626b29423c8..62788b2a3d7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/HTTP.qll @@ -8,7 +8,7 @@ private import semmle.javascript.dataflow.internal.StepSummary private import semmle.javascript.dataflow.internal.CallGraphs private import DataFlow::PseudoProperties as PseudoProperties -module HTTP { +module Http { /** * A function invocation that causes a redirect response to be sent. */ @@ -242,7 +242,7 @@ module HTTP { DataFlow::functionOneWayForwardingStep(pred.getALocalUse(), succ) or // a container containing route-handlers. - exists(HTTP::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ)) + exists(Http::RouteHandlerCandidateContainer container | pred = container.getRouteHandler(succ)) or // (function (req, res) {}).bind(this); exists(DataFlow::PartialInvokeNode call | @@ -677,7 +677,7 @@ module HTTP { /** * A collection that contains one or more route potential handlers. */ - private class ContainerCollection extends HTTP::RouteHandlerCandidateContainer::Range, + private class ContainerCollection extends Http::RouteHandlerCandidateContainer::Range, DataFlow::NewNode { ContainerCollection() { this = DataFlow::globalVarRef("Map").getAnInstantiation() and // restrict to Map for now @@ -699,3 +699,6 @@ module HTTP { } } } + +/** DEPRECATED: Alias for Http */ +deprecated module HTTP = Http; diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll index c5700f25728..e4bc922951c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll @@ -9,7 +9,7 @@ module Hapi { /** * An expression that creates a new Hapi server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::NewNode { + class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::NewNode { ServerDefinition() { // `server = new Hapi.Server()` this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation() @@ -19,7 +19,7 @@ module Hapi { /** * A Hapi route handler. */ - class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { RouteHandler() { exists(RouteSetup setup | this = setup.getARouteHandler()) } /** @@ -43,7 +43,7 @@ module Hapi { * A Hapi response source, that is, an access to the `response` property * of a request object. */ - private class ResponseSource extends HTTP::Servers::ResponseSource { + private class ResponseSource extends Http::Servers::ResponseSource { RequestNode req; ResponseSource() { this.(DataFlow::PropRead).accesses(req, "response") } @@ -58,7 +58,7 @@ module Hapi { * A Hapi request source, that is, the request parameter of a * route handler. */ - private class RequestSource extends HTTP::Servers::RequestSource { + private class RequestSource extends Http::Servers::RequestSource { RouteHandler rh; RequestSource() { this = rh.getRequestParameter() } @@ -80,7 +80,7 @@ module Hapi { /** * A Hapi response node. */ - class ResponseNode extends HTTP::Servers::StandardResponseNode { + class ResponseNode extends Http::Servers::StandardResponseNode { override ResponseSource src; } @@ -95,14 +95,14 @@ module Hapi { /** * A Hapi request node. */ - class RequestNode extends HTTP::Servers::StandardRequestNode { + class RequestNode extends Http::Servers::StandardRequestNode { override RequestSource src; } /** * An access to a user-controlled Hapi request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { + private class RequestInputAccess extends Http::RequestInputAccess { RouteHandler rh; string kind; @@ -156,7 +156,7 @@ module Hapi { /** * An access to an HTTP header on a Hapi request. */ - private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { + private class RequestHeaderAccess extends Http::RequestHeaderAccess { RouteHandler rh; RequestHeaderAccess() { @@ -181,7 +181,7 @@ module Hapi { /** * An HTTP header defined in a Hapi server. */ - private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { + private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition { ResponseNode res; HeaderDefinition() { @@ -195,7 +195,7 @@ module Hapi { /** * A call to a Hapi method that sets up a route. */ - class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup { ServerDefinition server; DataFlow::Node handler; @@ -236,7 +236,7 @@ module Hapi { * * For example, this could be the function `function(request, h){...}`. */ - class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate { + class RouteHandlerCandidate extends Http::RouteHandlerCandidate { RouteHandlerCandidate() { exists(string request, string responseToolkit | (request = "request" or request = "req") and @@ -256,7 +256,7 @@ module Hapi { * A function that looks like a Hapi route handler and flows to a route setup. */ private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler, - HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() } } @@ -276,7 +276,7 @@ module Hapi { /** * A return from a route handler. */ - private class HandlerReturn extends HTTP::ResponseSendArgument { + private class HandlerReturn extends Http::ResponseSendArgument { RouteHandler handler; HandlerReturn() { this = handler.(DataFlow::FunctionNode).getAReturn() } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll b/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll index 49104de9263..e8ca5ef2ac1 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Koa.qll @@ -9,7 +9,7 @@ module Koa { /** * An expression that creates a new Koa application. */ - class AppDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::InvokeNode { + class AppDefinition extends Http::Servers::StandardServerDefinition, DataFlow::InvokeNode { AppDefinition() { // `app = new Koa()` / `app = Koa()` this = DataFlow::moduleImport("koa").getAnInvocation() @@ -19,7 +19,7 @@ module Koa { /** * An HTTP header defined in a Koa application. */ - private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { + private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition { RouteHandler rh; HeaderDefinition() { @@ -36,7 +36,7 @@ module Koa { /** * A Koa route handler. */ - abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::SourceNode { + abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::SourceNode { /** * Gets the parameter of the route handler that contains the context object. */ @@ -227,7 +227,7 @@ module Koa { * A Koa request source, that is, an access to the `request` property * of a context object. */ - private class RequestSource extends HTTP::Servers::RequestSource instanceof DataFlow::PropRead { + private class RequestSource extends Http::Servers::RequestSource instanceof DataFlow::PropRead { ContextNode ctx; RequestSource() { super.accesses(ctx, "request") } @@ -242,7 +242,7 @@ module Koa { * A Koa request source, accessed through the a request property of a * generator route handler (deprecated in Koa 3). */ - private class GeneratorRequestSource extends HTTP::Servers::RequestSource { + private class GeneratorRequestSource extends Http::Servers::RequestSource { RouteHandler rh; GeneratorRequestSource() { @@ -262,7 +262,7 @@ module Koa { * A Koa response source, that is, an access to the `response` property * of a context object. */ - private class ResponseSource extends HTTP::Servers::ResponseSource instanceof DataFlow::PropRead { + private class ResponseSource extends Http::Servers::ResponseSource instanceof DataFlow::PropRead { ContextNode ctx; ResponseSource() { super.accesses(ctx, "response") } @@ -311,7 +311,7 @@ module Koa { /** * An expression that may hold a Koa request object. */ - class RequestNode extends HTTP::Servers::StandardRequestNode { + class RequestNode extends Http::Servers::StandardRequestNode { override RequestSource src; } @@ -326,14 +326,14 @@ module Koa { /** * An expression that may hold a Koa response object. */ - class ResponseNode extends HTTP::Servers::StandardResponseNode { + class ResponseNode extends Http::Servers::StandardResponseNode { override ResponseSource src; } /** * An access to a user-controlled Koa request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { + private class RequestInputAccess extends Http::RequestInputAccess { RouteHandler rh; string kind; @@ -399,7 +399,7 @@ module Koa { /** * An access to an HTTP header on a Koa request. */ - private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { + private class RequestHeaderAccess extends Http::RequestHeaderAccess { RouteHandler rh; RequestHeaderAccess() { @@ -435,7 +435,7 @@ module Koa { /** * A call to a Koa method that sets up a route. */ - class RouteSetup extends HTTP::Servers::StandardRouteSetup, DataFlow::MethodCallNode { + class RouteSetup extends Http::Servers::StandardRouteSetup, DataFlow::MethodCallNode { AppDefinition server; RouteSetup() { @@ -457,7 +457,7 @@ module Koa { /** * A value assigned to the body of an HTTP response object. */ - private class ResponseSendArgument extends HTTP::ResponseSendArgument { + private class ResponseSendArgument extends Http::ResponseSendArgument { RouteHandler rh; ResponseSendArgument() { @@ -470,7 +470,7 @@ module Koa { /** * An invocation of the `redirect` method of an HTTP response object. */ - private class RedirectInvocation extends HTTP::RedirectInvocation instanceof DataFlow::MethodCallNode { + private class RedirectInvocation extends Http::RedirectInvocation instanceof DataFlow::MethodCallNode { RouteHandler rh; RedirectInvocation() { super.calls(rh.getAResponseOrContextNode(), "redirect") } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll b/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll index cc90dc8d720..5a8075ed366 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/LiveServer.qll @@ -9,7 +9,7 @@ private module LiveServer { /** * An expression that imports the live-server package, seen as a server-definition. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition { + class ServerDefinition extends Http::Servers::StandardServerDefinition { ServerDefinition() { this = DataFlow::moduleImport("live-server") } API::Node getImportNode() { result.asSource() = this } @@ -30,7 +30,7 @@ private module LiveServer { /** * The call to `require("live-server").start()`, seen as a route setup. */ - class RouteSetup extends HTTP::Servers::StandardRouteSetup instanceof API::CallNode { + class RouteSetup extends Http::Servers::StandardRouteSetup instanceof API::CallNode { ServerDefinition server; RouteSetup() { this = server.getImportNode().getMember("start").getACall() } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll b/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll index ba99fc014d1..a5599e4ee79 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Logging.qll @@ -349,7 +349,7 @@ private module Pino { or // `pino` is installed as the "log" property on the request object in `Express` and similar libraries. // in `Hapi` the property is "logger". - exists(HTTP::RequestNode req, API::Node reqNode | + exists(Http::RequestNode req, API::Node reqNode | reqNode.asSource() = req.getALocalSource() and result = reqNode.getMember(["log", "logger"]) ) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll b/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll index 7ac9b1349d8..abdc97fe0b7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Micro.qll @@ -42,24 +42,24 @@ private module Micro { /** * A function passed to `micro` or `micro.run`. */ - class MicroRouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + class MicroRouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { MicroRouteHandler() { this = microRouteHandler().getAFunctionValue() } } - class MicroRequestSource extends HTTP::Servers::RequestSource { + class MicroRequestSource extends Http::Servers::RequestSource { MicroRouteHandler h; MicroRequestSource() { this = h.getParameter(0) } - override HTTP::RouteHandler getRouteHandler() { result = h } + override Http::RouteHandler getRouteHandler() { result = h } } - class MicroResponseSource extends HTTP::Servers::ResponseSource { + class MicroResponseSource extends Http::Servers::ResponseSource { MicroRouteHandler h; MicroResponseSource() { this = h.getParameter(1) } - override HTTP::RouteHandler getRouteHandler() { result = h } + override Http::RouteHandler getRouteHandler() { result = h } } deprecated class MicroRequestExpr extends NodeJSLib::RequestExpr { @@ -78,19 +78,19 @@ private module Micro { override MicroResponseSource src; } - private HTTP::RouteHandler getRouteHandlerFromReqRes(DataFlow::Node node) { - exists(HTTP::Servers::RequestSource src | + private Http::RouteHandler getRouteHandlerFromReqRes(DataFlow::Node node) { + exists(Http::Servers::RequestSource src | src.ref().flowsTo(node) and result = src.getRouteHandler() ) or - exists(HTTP::Servers::ResponseSource src | + exists(Http::Servers::ResponseSource src | src.ref().flowsTo(node) and result = src.getRouteHandler() ) } - class MicroBodyParserCall extends HTTP::RequestInputAccess, DataFlow::CallNode { + class MicroBodyParserCall extends Http::RequestInputAccess, DataFlow::CallNode { string name; MicroBodyParserCall() { @@ -100,14 +100,14 @@ private module Micro { override string getKind() { result = "body" } - override HTTP::RouteHandler getRouteHandler() { + override Http::RouteHandler getRouteHandler() { result = getRouteHandlerFromReqRes(getArgument(0)) } override predicate isUserControlledObject() { name = "json" } } - class MicroSendArgument extends HTTP::ResponseSendArgument { + class MicroSendArgument extends Http::ResponseSendArgument { CallNode send; MicroSendArgument() { @@ -115,7 +115,7 @@ private module Micro { this = send.getLastArgument() } - override HTTP::RouteHandler getRouteHandler() { + override Http::RouteHandler getRouteHandler() { result = getRouteHandlerFromReqRes(send.getArgument([0, 1])) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll index 80cba72fd3c..16a57eb1b98 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll @@ -34,7 +34,7 @@ module NestJS { * } * ``` */ - private class NestJSRouteHandler extends HTTP::RouteHandler, DataFlow::FunctionNode { + private class NestJSRouteHandler extends Http::RouteHandler, DataFlow::FunctionNode { NestJSRouteHandler() { getAFunctionDecorator(this) = nestjs() @@ -42,7 +42,7 @@ module NestJS { .getACall() } - override HTTP::HeaderDefinition getAResponseHeader(string name) { none() } + override Http::HeaderDefinition getAResponseHeader(string name) { none() } /** * Holds if this has the `@Redirect()` decorator. @@ -257,7 +257,7 @@ module NestJS { * The type of remote flow depends on which decorator is applied at the parameter, so * we just classify it as a `RemoteFlowSource`. */ - private class NestJSCustomPipeInput extends HTTP::RequestInputAccess { + private class NestJSCustomPipeInput extends Http::RequestInputAccess { CustomPipeClass pipe; NestJSCustomPipeInput() { @@ -273,7 +273,7 @@ module NestJS { result = pipe.getAnAffectedParameter().getInputKind() } - override HTTP::RouteHandler getRouteHandler() { + override Http::RouteHandler getRouteHandler() { result = pipe.getAnAffectedParameter().getNestRouteHandler() } } @@ -295,13 +295,13 @@ module NestJS { * as a source of untrusted data. */ private class NestJSRequestInputAsRequestInputAccess extends NestJSRequestInput, - HTTP::RequestInputAccess { + Http::RequestInputAccess { NestJSRequestInputAsRequestInputAccess() { not this.isSanitizedByPipe() and not this = any(CustomPipeClass cls).getAnAffectedParameter() } - override HTTP::RouteHandler getRouteHandler() { result = this.getNestRouteHandler() } + override Http::RouteHandler getRouteHandler() { result = this.getNestRouteHandler() } override string getKind() { result = this.getInputKind() } @@ -316,7 +316,7 @@ module NestJS { } private class NestJSHeaderAccess extends NestJSRequestInputAsRequestInputAccess, - HTTP::RequestHeaderAccess { + Http::RequestHeaderAccess { NestJSHeaderAccess() { decoratorName = "Headers" and decorator.getNumArgument() > 0 } override string getAHeaderName() { @@ -344,7 +344,7 @@ module NestJS { * ``` * writes `Hello` to the response. */ - private class ReturnValueAsResponseSend extends HTTP::ResponseSendArgument { + private class ReturnValueAsResponseSend extends Http::ResponseSendArgument { NestJSRouteHandler handler; ReturnValueAsResponseSend() { @@ -357,7 +357,7 @@ module NestJS { ) } - override HTTP::RouteHandler getRouteHandler() { result = handler } + override Http::RouteHandler getRouteHandler() { result = handler } } /** @@ -439,7 +439,7 @@ module NestJS { /** * Gets the route handler that handles this request. */ - override HTTP::RouteHandler getRouteHandler() { + override Http::RouteHandler getRouteHandler() { result.(DataFlow::FunctionNode).getAParameter() = this } } @@ -456,7 +456,7 @@ module NestJS { /** * Gets the route handler that handles this request. */ - override HTTP::RouteHandler getRouteHandler() { + override Http::RouteHandler getRouteHandler() { result.(DataFlow::FunctionNode).getAParameter() = this } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll index 495543eb1b3..50671e37796 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Next.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Next.qll @@ -153,14 +153,14 @@ module NextJS { /** * A Next.js function that is exected on the server for every request, seen as a routehandler. */ - class NextHttpRouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + class NextHttpRouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { NextHttpRouteHandler() { this = getServerSidePropsFunction(_) or this = getInitialProps(_) } } /** * A function that handles both a request and response from Next.js, seen as a routehandler. */ - class NextReqResHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + class NextReqResHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { DataFlow::ParameterNode req; DataFlow::ParameterNode res; @@ -182,28 +182,28 @@ module NextJS { * A NodeJS HTTP request object in a Next.js page. */ class NextHttpRequestSource extends NodeJSLib::RequestSource { - HTTP::RouteHandler rh; + Http::RouteHandler rh; NextHttpRequestSource() { this = rh.(NextHttpRouteHandler).getParameter(0).getAPropertyRead("req") or this = rh.(NextReqResHandler).getRequest() } - override HTTP::RouteHandler getRouteHandler() { result = rh } + override Http::RouteHandler getRouteHandler() { result = rh } } /** * A NodeJS HTTP response object in a Next.js page. */ class NextHttpResponseSource extends NodeJSLib::ResponseSource { - HTTP::RouteHandler rh; + Http::RouteHandler rh; NextHttpResponseSource() { this = rh.(NextHttpRouteHandler).getParameter(0).getAPropertyRead("res") or this = rh.(NextReqResHandler).getResponse() } - override HTTP::RouteHandler getRouteHandler() { result = rh } + override Http::RouteHandler getRouteHandler() { result = rh } } /** @@ -222,7 +222,7 @@ module NextJS { * and we therefore model the routehandler as an Express.js routehandler. */ class NextApiRouteHandler extends DataFlow::FunctionNode, Express::RouteHandler, - HTTP::Servers::StandardRouteHandler { + Http::Servers::StandardRouteHandler { NextApiRouteHandler() { exists(Module mod | mod.getFile().getParentContainer() = apiFolder() | this = mod.getAnExportedValue("default").getAFunctionValue() diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 0c5fdbd6a15..36c3cb78cb9 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -81,7 +81,7 @@ module NodeJSLib { * A server library that provides an (enhanced) NodesJS HTTP response * object should implement a library specific subclass of this class. */ - abstract class ResponseNode extends HTTP::Servers::StandardResponseNode { } + abstract class ResponseNode extends Http::Servers::StandardResponseNode { } /** * DEPRECATED: Use `RequestNode` instead. @@ -100,7 +100,7 @@ module NodeJSLib { * A server library that provides an (enhanced) NodesJS HTTP request * object should implement a library specific subclass of this class. */ - abstract class RequestNode extends HTTP::Servers::StandardRequestNode { } + abstract class RequestNode extends Http::Servers::StandardRequestNode { } /** * A function used as an Node.js server route handler. @@ -109,7 +109,7 @@ module NodeJSLib { * but support for other kinds of route handlers can be added by implementing * additional subclasses of this class. */ - abstract class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + abstract class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { /** * Gets the parameter of the route handler that contains the request object. */ @@ -131,7 +131,7 @@ module NodeJSLib { /** * A Node.js response source. */ - abstract class ResponseSource extends HTTP::Servers::ResponseSource { } + abstract class ResponseSource extends Http::Servers::ResponseSource { } /** * A standard Node.js response source, that is, the response parameter of a @@ -151,7 +151,7 @@ module NodeJSLib { /** * A Node.js request source. */ - abstract class RequestSource extends HTTP::Servers::RequestSource { } + abstract class RequestSource extends Http::Servers::RequestSource { } /** * A standard Node.js request source, that is, the request parameter of a @@ -201,7 +201,7 @@ module NodeJSLib { /** * An access to a user-controlled Node.js request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { + private class RequestInputAccess extends Http::RequestInputAccess { RequestNode request; string kind; @@ -223,7 +223,7 @@ module NodeJSLib { ) } - override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() } + override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() } override string getKind() { result = kind } } @@ -231,7 +231,7 @@ module NodeJSLib { /** * An access to an HTTP header (other than "Cookie") on an incoming Node.js request object. */ - private class RequestHeaderAccess extends HTTP::RequestHeaderAccess { + private class RequestHeaderAccess extends Http::RequestHeaderAccess { RequestNode request; RequestHeaderAccess() { @@ -247,14 +247,14 @@ module NodeJSLib { result = this.(DataFlow::PropRead).getPropertyName().toLowerCase() } - override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() } + override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() } override string getKind() { result = "header" } RequestNode getRequest() { result = request } } - class RouteSetup extends DataFlow::CallNode, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::CallNode, Http::Servers::StandardRouteSetup { ServerDefinition server; DataFlow::Node handler; @@ -282,7 +282,7 @@ module NodeJSLib { result = succ.backtrack(t2, t) or t = t2 and - HTTP::routeHandlerStep(result, succ) + Http::routeHandlerStep(result, succ) ) } @@ -300,12 +300,12 @@ module NodeJSLib { DataFlow::Node getRouteHandlerNode() { result = handler } } - abstract private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { + abstract private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition { ResponseNode r; HeaderDefinition() { this.getReceiver() = r } - override HTTP::RouteHandler getRouteHandler() { result = r.getRouteHandler() } + override Http::RouteHandler getRouteHandler() { result = r.getRouteHandler() } } /** @@ -403,8 +403,8 @@ module NodeJSLib { * An expression passed as the first argument to the `write` or `end` method * of an HTTP response. */ - private class ResponseSendArgument extends HTTP::ResponseSendArgument { - HTTP::RouteHandler rh; + private class ResponseSendArgument extends Http::ResponseSendArgument { + Http::RouteHandler rh; ResponseSendArgument() { exists(DataFlow::MethodCallNode mcn, string m | m = "write" or m = "end" | @@ -415,13 +415,13 @@ module NodeJSLib { ) } - override HTTP::RouteHandler getRouteHandler() { result = rh } + override Http::RouteHandler getRouteHandler() { result = rh } } /** * An expression that creates a new Node.js server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition { + class ServerDefinition extends Http::Servers::StandardServerDefinition { ServerDefinition() { isCreateServer(this) } } @@ -820,7 +820,7 @@ module NodeJSLib { * * For example, this could be the function `function(req, res){...}`. */ - class RouteHandlerCandidate extends HTTP::RouteHandlerCandidate { + class RouteHandlerCandidate extends Http::RouteHandlerCandidate { RouteHandlerCandidate() { exists(string request, string response | (request = "request" or request = "req") and @@ -840,7 +840,7 @@ module NodeJSLib { * A function that flows to a route setup. */ private class TrackedRouteHandlerCandidateWithSetup extends RouteHandler, - HTTP::Servers::StandardRouteHandler, DataFlow::FunctionNode { + Http::Servers::StandardRouteHandler, DataFlow::FunctionNode { TrackedRouteHandlerCandidateWithSetup() { this = any(RouteSetup s).getARouteHandler() } } @@ -871,7 +871,7 @@ module NodeJSLib { * For example, this could be the call `server.on("request", handler)` * where it is unknown if `server` is a Node.js server. */ - class RouteSetupCandidate extends HTTP::RouteSetupCandidate, DataFlow::MethodCallNode { + class RouteSetupCandidate extends Http::RouteSetupCandidate, DataFlow::MethodCallNode { DataFlow::ValueNode arg; RouteSetupCandidate() { @@ -912,7 +912,7 @@ module NodeJSLib { exists(string moduleName, DataFlow::SourceNode callee | this = callee.getACall() | (moduleName = "http" or moduleName = "https") and ( - callee = DataFlow::moduleMember(moduleName, any(HTTP::RequestMethodName m).toLowerCase()) + callee = DataFlow::moduleMember(moduleName, any(Http::RequestMethodName m).toLowerCase()) or callee = DataFlow::moduleMember(moduleName, "request") ) and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Request.qll b/javascript/ql/lib/semmle/javascript/frameworks/Request.qll index 392a84c51a4..3551da6f0c1 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Request.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Request.qll @@ -17,7 +17,7 @@ module Request { action = mod.getAnInvocation() or // specialized form: `request.get(...)` - action = mod.getAMemberCall(any(HTTP::RequestMethodName n).toLowerCase()) + action = mod.getAMemberCall(any(Http::RequestMethodName n).toLowerCase()) ) | exists(DataFlow::MethodCallNode auth, int argIndex | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll index 492416171da..889369c6ea4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Restify.qll @@ -9,7 +9,7 @@ module Restify { /** * An expression that creates a new Restify server. */ - class ServerDefinition extends HTTP::Servers::StandardServerDefinition, DataFlow::CallNode { + class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::CallNode { ServerDefinition() { // `server = restify.createServer()` this = DataFlow::moduleMember("restify", "createServer").getACall() @@ -19,7 +19,7 @@ module Restify { /** * A Restify route handler. */ - class RouteHandler extends HTTP::Servers::StandardRouteHandler, DataFlow::ValueNode { + class RouteHandler extends Http::Servers::StandardRouteHandler, DataFlow::ValueNode { Function function; RouteHandler() { @@ -42,7 +42,7 @@ module Restify { * A Restify response source, that is, the response parameter of a * route handler. */ - private class ResponseSource extends HTTP::Servers::ResponseSource { + private class ResponseSource extends Http::Servers::ResponseSource { RouteHandler rh; ResponseSource() { this = DataFlow::parameterNode(rh.getResponseParameter()) } @@ -57,7 +57,7 @@ module Restify { * A Restify request source, that is, the request parameter of a * route handler. */ - private class RequestSource extends HTTP::Servers::RequestSource { + private class RequestSource extends Http::Servers::RequestSource { RouteHandler rh; RequestSource() { this = DataFlow::parameterNode(rh.getRequestParameter()) } @@ -101,7 +101,7 @@ module Restify { /** * An access to a user-controlled Restify request input. */ - private class RequestInputAccess extends HTTP::RequestInputAccess { + private class RequestInputAccess extends Http::RequestInputAccess { RequestNode request; string kind; @@ -140,7 +140,7 @@ module Restify { /** * An HTTP header defined in a Restify server. */ - private class HeaderDefinition extends HTTP::Servers::StandardHeaderDefinition { + private class HeaderDefinition extends Http::Servers::StandardHeaderDefinition { HeaderDefinition() { // response.header('Cache-Control', 'no-cache') this.getReceiver() instanceof ResponseNode and @@ -153,13 +153,13 @@ module Restify { /** * A call to a Restify method that sets up a route. */ - class RouteSetup extends DataFlow::MethodCallNode, HTTP::Servers::StandardRouteSetup { + class RouteSetup extends DataFlow::MethodCallNode, Http::Servers::StandardRouteSetup { ServerDefinition server; RouteSetup() { // server.get('/', fun) // server.head('/', fun) - server.ref().getAMethodCall(any(HTTP::RequestMethodName m).toLowerCase()) = this + server.ref().getAMethodCall(any(Http::RequestMethodName m).toLowerCase()) = this } override DataFlow::SourceNode getARouteHandler() { result.flowsTo(this.getArgument(1)) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Templating.qll b/javascript/ql/lib/semmle/javascript/frameworks/Templating.qll index 90adf7d7de6..d66ca3baab2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Templating.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Templating.qll @@ -151,7 +151,7 @@ module Templating { /** Gets the data flow node representing the initialization of the given variable in this scope. */ DataFlow::Node getVariableInit(string name) { - result = DataFlow::ssaDefinitionNode(SSA::implicitInit(this.getScope().getVariable(name))) + result = DataFlow::ssaDefinitionNode(Ssa::implicitInit(this.getScope().getVariable(name))) } /** Gets a data flow node corresponding to a use of the given template variable within this top-level. */ diff --git a/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll b/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll index 16e5187081e..a02da6c9f86 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/WebSocket.qll @@ -226,21 +226,21 @@ module ServerWebSocket { * A `socket.on("connection", (msg, req) => {})` call seen as a HTTP route handler. * `req` is a `HTTP::IncomingMessage` instance. */ - class ConnectionCallAsRouteHandler extends HTTP::RouteHandler, DataFlow::CallNode { + class ConnectionCallAsRouteHandler extends Http::RouteHandler, DataFlow::CallNode { ConnectionCallAsRouteHandler() { this = getAConnectionCall(_) } - override HTTP::HeaderDefinition getAResponseHeader(string name) { none() } + override Http::HeaderDefinition getAResponseHeader(string name) { none() } } /** * The `req` parameter of a `socket.on("connection", (msg, req) => {})` call. */ - class ServerHttpRequest extends HTTP::Servers::RequestSource { + class ServerHttpRequest extends Http::Servers::RequestSource { ConnectionCallAsRouteHandler handler; ServerHttpRequest() { this = handler.getCallback(1).getParameter(1) } - override HTTP::RouteHandler getRouteHandler() { result = handler } + override Http::RouteHandler getRouteHandler() { result = handler } } /** DEPRECATED: Alias for ServerHttpRequest */ @@ -249,7 +249,7 @@ module ServerWebSocket { /** * An access user-controlled HTTP request input in a request to a WebSocket server. */ - class WebSocketRequestInput extends HTTP::RequestInputAccess { + class WebSocketRequestInput extends Http::RequestInputAccess { ServerHttpRequest request; string kind; @@ -267,7 +267,7 @@ module ServerWebSocket { override string getKind() { result = kind } - override HTTP::RouteHandler getRouteHandler() { result = request.getRouteHandler() } + override Http::RouteHandler getRouteHandler() { result = request.getRouteHandler() } } /** diff --git a/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll b/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll index 1d873a3f2a9..76a8aff557b 100644 --- a/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll +++ b/javascript/ql/lib/semmle/javascript/heuristics/AdditionalRouteHandlers.qll @@ -11,14 +11,14 @@ private import semmle.javascript.frameworks.ConnectExpressShared * Add `NodeJSLib::RouteHandlerCandidate` to the extent of `NodeJSLib::RouteHandler`. */ private class PromotedNodeJSLibCandidate extends NodeJSLib::RouteHandler, - HTTP::Servers::StandardRouteHandler { + Http::Servers::StandardRouteHandler { PromotedNodeJSLibCandidate() { this instanceof NodeJSLib::RouteHandlerCandidate } } /** * Add `Hapi::RouteHandlerCandidate` to the extent of `Hapi::RouteHandler`. */ -private class PromotedHapiCandidate extends Hapi::RouteHandler, HTTP::Servers::StandardRouteHandler { +private class PromotedHapiCandidate extends Hapi::RouteHandler, Http::Servers::StandardRouteHandler { PromotedHapiCandidate() { this instanceof Hapi::RouteHandlerCandidate } } @@ -26,7 +26,7 @@ private class PromotedHapiCandidate extends Hapi::RouteHandler, HTTP::Servers::S * Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Express::RouteHandler`. */ private class PromotedExpressCandidate extends Express::RouteHandler, - HTTP::Servers::StandardRouteHandler { + Http::Servers::StandardRouteHandler { PromotedExpressCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate } override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { @@ -38,7 +38,7 @@ private class PromotedExpressCandidate extends Express::RouteHandler, * Add `ConnectExpressShared::RouteHandlerCandidate` to the extent of `Connect::RouteHandler`. */ private class PromotedConnectCandidate extends Connect::RouteHandler, - HTTP::Servers::StandardRouteHandler { + Http::Servers::StandardRouteHandler { PromotedConnectCandidate() { this instanceof ConnectExpressShared::RouteHandlerCandidate } override DataFlow::ParameterNode getRouteHandlerParameter(string kind) { diff --git a/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll b/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll index 504ebad9e35..aad1e3fddd6 100644 --- a/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll +++ b/javascript/ql/lib/semmle/javascript/security/SensitiveActions.qll @@ -96,7 +96,7 @@ private predicate writesProperty(DataFlow::Node node, string name) { exists(VarDef v | v.getAVariable().getName() = name | if exists(v.getSource()) then v.getSource() = node.asExpr() - else node = DataFlow::ssaDefinitionNode(SSA::definition(v)) + else node = DataFlow::ssaDefinitionNode(Ssa::definition(v)) ) } diff --git a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll index 6c5c0f21057..eac7dd4e762 100644 --- a/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll +++ b/javascript/ql/lib/semmle/javascript/security/TaintedObject.qll @@ -75,7 +75,7 @@ module TaintedObject { /** Request input accesses as a JSON source. */ private class RequestInputAsSource extends Source { - RequestInputAsSource() { this.(HTTP::RequestInputAccess).isUserControlledObject() } + RequestInputAsSource() { this.(Http::RequestInputAccess).isUserControlledObject() } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll index c2244de9d7e..5428e14abee 100644 --- a/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll +++ b/javascript/ql/lib/semmle/javascript/security/UselessUseOfCat.qll @@ -127,7 +127,7 @@ class UselessCat extends CommandCall { or // `exec` can use 3 parameters, `readFile` can only use two, so it is OK to have a third parameter if it is unused, func.getNumParameter() = 3 and - not exists(SSA::definition(func.getParameter(2).getParameter())) + not exists(Ssa::definition(func.getParameter(2).getParameter())) ) ) and // The process returned by an async call is unused. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll index ef2090b3dea..d158e4b0cac 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CleartextStorageCustomizations.qll @@ -49,7 +49,7 @@ module CleartextStorage { */ class CookieStorageSink extends Sink { CookieStorageSink() { - exists(HTTP::CookieDefinition cookieDef | + exists(Http::CookieDefinition cookieDef | this = cookieDef.getValueArgument() or this = cookieDef.getHeaderArgument() ) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll index 24c9a707bd0..79868ea9989 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentialsCustomizations.qll @@ -19,7 +19,7 @@ module CorsMisconfigurationForCredentials { /** * Gets the "Access-Control-Allow-Credentials" header definition. */ - abstract HTTP::HeaderDefinition getCredentialsHeader(); + abstract Http::HeaderDefinition getCredentialsHeader(); } /** @@ -41,11 +41,11 @@ module CorsMisconfigurationForCredentials { * HTTP header with a truthy value. */ class CorsOriginHeaderWithAssociatedCredentialHeader extends Sink, DataFlow::ValueNode { - HTTP::ExplicitHeaderDefinition credentials; + Http::ExplicitHeaderDefinition credentials; CorsOriginHeaderWithAssociatedCredentialHeader() { exists( - HTTP::RouteHandler routeHandler, HTTP::ExplicitHeaderDefinition origin, + Http::RouteHandler routeHandler, Http::ExplicitHeaderDefinition origin, DataFlow::Node credentialsValue | routeHandler.getAResponseHeader(_) = origin and @@ -58,7 +58,7 @@ module CorsMisconfigurationForCredentials { ) } - override HTTP::HeaderDefinition getCredentialsHeader() { result = credentials } + override Http::HeaderDefinition getCredentialsHeader() { result = credentials } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassCustomizations.qll index bfb30cc2c99..956fe352854 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DifferentKindsComparisonBypassCustomizations.qll @@ -31,7 +31,7 @@ module DifferentKindsComparisonBypass { * A HTTP request input that is suspicious to compare with another HTTP request input of a different kind. */ class RequestInputComparisonSource extends Source { - HTTP::RequestInputAccess input; + Http::RequestInputAccess input; RequestInputComparisonSource() { input = this } @@ -42,7 +42,7 @@ module DifferentKindsComparisonBypass { /** * Gets the HTTP request input of this source. */ - private HTTP::RequestInputAccess getInput() { result = input } + private Http::RequestInputAccess getInput() { result = input } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll index 2a41b76dc80..f87938dfb71 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HostHeaderPoisoningInEmailGenerationQuery.qll @@ -12,7 +12,7 @@ class Configuration extends TaintTracking::Configuration { Configuration() { this = "TaintedHostHeader" } override predicate isSource(DataFlow::Node node) { - exists(HTTP::RequestHeaderAccess input | node = input | + exists(Http::RequestHeaderAccess input | node = input | input.getKind() = "header" and input.getAHeaderName() = "host" ) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessSpecific.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessSpecific.qll index a7b6cca1360..7ed38fdf3f2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessSpecific.qll @@ -9,7 +9,7 @@ private import HttpToFileAccessCustomizations::HttpToFileAccess * An access to a user-controlled HTTP request input, considered as a flow source for writing user-controlled data to files */ private class RequestInputAccessAsSource extends Source { - RequestInputAccessAsSource() { this instanceof HTTP::RequestInputAccess } + RequestInputAccessAsSource() { this instanceof Http::RequestInputAccess } } /** A response from a server, considered as a flow source for writing user-controlled data to files. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll index 2969d118c60..2b8f9112dd2 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ReflectedXssCustomizations.qll @@ -24,15 +24,15 @@ module ReflectedXss { * a content type that does not (case-insensitively) contain the string "html". This * is to prevent us from flagging plain-text or JSON responses as vulnerable. */ - class HttpResponseSink extends Sink instanceof HTTP::ResponseSendArgument { + class HttpResponseSink extends Sink instanceof Http::ResponseSendArgument { HttpResponseSink() { not exists(getANonHtmlHeaderDefinition(this)) } } /** * Gets a HeaderDefinition that defines a non-html content-type for `send`. */ - HTTP::HeaderDefinition getANonHtmlHeaderDefinition(HTTP::ResponseSendArgument send) { - exists(HTTP::RouteHandler h | + Http::HeaderDefinition getANonHtmlHeaderDefinition(Http::ResponseSendArgument send) { + exists(Http::RouteHandler h | send.getRouteHandler() = h and result = nonHtmlContentTypeHeader(h) | @@ -44,7 +44,7 @@ module ReflectedXss { /** * Holds if `h` may send a response with a content type other than HTML. */ - HTTP::HeaderDefinition nonHtmlContentTypeHeader(HTTP::RouteHandler h) { + Http::HeaderDefinition nonHtmlContentTypeHeader(Http::RouteHandler h) { result = h.getAResponseHeader("content-type") and not exists(string tp | result.defines("content-type", tp) | tp.regexpMatch("(?i).*html.*")) } @@ -52,7 +52,7 @@ module ReflectedXss { /** * Holds if a header set in `header` is likely to affect a response sent at `sender`. */ - predicate headerAffects(HTTP::HeaderDefinition header, HTTP::ResponseSendArgument sender) { + predicate headerAffects(Http::HeaderDefinition header, Http::ResponseSendArgument sender) { sender.getRouteHandler() = header.getRouteHandler() and ( // `sender` is affected by a dominating `header`. @@ -60,7 +60,7 @@ module ReflectedXss { or // There is no dominating header, and `header` is non-local. not isLocalHeaderDefinition(header) and - not exists(HTTP::HeaderDefinition dominatingHeader | + not exists(Http::HeaderDefinition dominatingHeader | dominatingHeader.getBasicBlock().(ReachableBasicBlock).dominates(sender.getBasicBlock()) ) ) @@ -77,10 +77,10 @@ module ReflectedXss { * return; * ``` */ - predicate isLocalHeaderDefinition(HTTP::HeaderDefinition header) { + predicate isLocalHeaderDefinition(Http::HeaderDefinition header) { exists(ReachableBasicBlock headerBlock | headerBlock = header.getBasicBlock() | 1 = - strictcount(HTTP::ResponseSendArgument sender | + strictcount(Http::ResponseSendArgument sender | sender.getRouteHandler() = header.getRouteHandler() and header.getBasicBlock().(ReachableBasicBlock).dominates(sender.getBasicBlock()) ) and @@ -108,9 +108,9 @@ module ReflectedXss { /** A third-party controllable request input, considered as a flow source for reflected XSS. */ class ThirdPartyRequestInputAccessAsSource extends Source { ThirdPartyRequestInputAccessAsSource() { - this.(HTTP::RequestInputAccess).isThirdPartyControllable() + this.(Http::RequestInputAccess).isThirdPartyControllable() or - this.(HTTP::RequestHeaderAccess).getAHeaderName() = "referer" + this.(Http::RequestHeaderAccess).getAHeaderName() = "referer" } } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll index d060f91b371..c4605f655d8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/RemotePropertyInjectionCustomizations.qll @@ -59,7 +59,7 @@ module RemotePropertyInjection { */ class HeaderNameSink extends Sink { HeaderNameSink() { - exists(HTTP::ExplicitHeaderDefinition hd | + exists(Http::ExplicitHeaderDefinition hd | not hd instanceof Express::SetMultipleHeaders and this = hd.getNameNode() ) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll index db62f29c8dd..c15dbc2ecf8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ServerSideUrlRedirectCustomizations.qll @@ -26,7 +26,7 @@ module ServerSideUrlRedirect { /** A source of third-party user input, considered as a flow source for URL redirects. */ class ThirdPartyRequestInputAccessAsSource extends Source { ThirdPartyRequestInputAccessAsSource() { - this.(HTTP::RequestInputAccess).isThirdPartyControllable() + this.(Http::RequestInputAccess).isThirdPartyControllable() } } @@ -34,7 +34,7 @@ module ServerSideUrlRedirect { * An HTTP redirect, considered as a sink for `Configuration`. */ class RedirectSink extends Sink { - RedirectSink() { this = any(HTTP::RedirectInvocation redir).getUrlArgument() } + RedirectSink() { this = any(Http::RedirectInvocation redir).getUrlArgument() } } /** @@ -43,7 +43,7 @@ module ServerSideUrlRedirect { */ class LocationHeaderSink extends Sink { LocationHeaderSink() { - any(HTTP::ExplicitHeaderDefinition def).definesHeaderValue("location", this) + any(Http::ExplicitHeaderDefinition def).definesHeaderValue("location", this) } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll index 1ee969205fd..205c00f8f79 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/StackTraceExposureCustomizations.qll @@ -32,5 +32,5 @@ module StackTraceExposure { * An expression that can become part of an HTTP response body, viewed * as a data flow sink for stack trace exposure vulnerabilities. */ - class DefaultSink extends Sink instanceof HTTP::ResponseBody { } + class DefaultSink extends Sink instanceof Http::ResponseBody { } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll index 3cdc81c66ee..ad608017115 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/TypeConfusionThroughParameterTamperingCustomizations.qll @@ -29,7 +29,7 @@ module TypeConfusionThroughParameterTampering { * Node.js-based HTTP servers turn request parameters into arrays if their names are repeated. */ private class TypeTamperableRequestParameter extends Source { - TypeTamperableRequestParameter() { this.(HTTP::RequestInputAccess).isUserControlledObject() } + TypeTamperableRequestParameter() { this.(Http::RequestInputAccess).isUserControlledObject() } } /** diff --git a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll index ad464f8f24c..87f9437196f 100644 --- a/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/regexp/PolynomialReDoSCustomizations.qll @@ -48,8 +48,8 @@ module PolynomialReDoS { * A remote input to a server, seen as a source for polynomial * regular expression denial-of-service vulnerabilities. */ - class RequestInputAccessAsSource extends Source instanceof HTTP::RequestInputAccess { - override string getKind() { result = HTTP::RequestInputAccess.super.getKind() } + class RequestInputAccessAsSource extends Source instanceof Http::RequestInputAccess { + override string getKind() { result = Http::RequestInputAccess.super.getKind() } } /** diff --git a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql index 6240615a6e7..508bdad18b2 100644 --- a/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql +++ b/javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql @@ -35,7 +35,7 @@ predicate isRouteHandlerUsingCookies(Routing::RouteHandler handler) { * A router handler following after cookie parsing is assumed to depend on * cookies, and thus require CSRF protection. */ -predicate hasCookieMiddleware(Routing::Node route, HTTP::CookieMiddlewareInstance cookie) { +predicate hasCookieMiddleware(Routing::Node route, Http::CookieMiddlewareInstance cookie) { route.isGuardedBy(cookie) } @@ -112,7 +112,7 @@ private DataFlow::SourceNode nodeLeadingToCsrfWriteOrCheck(DataFlow::TypeBackTra * Gets a route handler that sets an CSRF related cookie. */ private Routing::RouteHandler getAHandlerSettingCsrfCookie() { - exists(HTTP::CookieDefinition setCookie | + exists(Http::CookieDefinition setCookie | setCookie.getNameArgument().getStringValue().regexpMatch("(?i).*(csrf|xsrf).*") and result = Routing::getRouteHandler(setCookie.getRouteHandler()) ) @@ -180,7 +180,7 @@ predicate hasCsrfMiddleware(Routing::RouteHandler handler) { from Routing::RouteSetup setup, Routing::Node setupArg, Routing::RouteHandler handler, - HTTP::CookieMiddlewareInstance cookie + Http::CookieMiddlewareInstance cookie where // Require that the handler uses cookies and has cookie middleware. // diff --git a/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.ql b/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.ql index 316af8d4a36..6228d1539ea 100644 --- a/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.ql +++ b/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.ql @@ -15,6 +15,6 @@ import javascript import semmle.javascript.frameworks.HTTP -from HTTP::ServerDefinition server +from Http::ServerDefinition server where not exists(server.getARouteHandler().getAResponseHeader("x-frame-options")) select server, "This server never sets the 'X-Frame-Options' HTTP header." diff --git a/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql b/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql index 89aeb49b6f4..1dade2a88ca 100644 --- a/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql +++ b/javascript/ql/src/Security/CWE-598/SensitiveGetQuery.ql @@ -14,7 +14,7 @@ import javascript from - Routing::RouteSetup setup, Routing::RouteHandler handler, HTTP::RequestInputAccess input, + Routing::RouteSetup setup, Routing::RouteHandler handler, Http::RequestInputAccess input, SensitiveNode sensitive where setup.getOwnHttpMethod() = "GET" and diff --git a/javascript/ql/src/Security/CWE-730/ServerCrash.ql b/javascript/ql/src/Security/CWE-730/ServerCrash.ql index f5de58d4516..c3cd7dcc842 100644 --- a/javascript/ql/src/Security/CWE-730/ServerCrash.ql +++ b/javascript/ql/src/Security/CWE-730/ServerCrash.ql @@ -88,7 +88,7 @@ Function reachableFromAsyncCallback() { * The main predicate of this query: used for both result display and path computation. */ predicate main( - HTTP::RouteHandler rh, AsyncSentinelCall async, AsyncCallback cb, LikelyExceptionThrower thrower + Http::RouteHandler rh, AsyncSentinelCall async, AsyncCallback cb, LikelyExceptionThrower thrower ) { async.getAsyncCallee() = cb and rh.getAstNode() = invokesCallbackThatThrowsUncaughtException(async, thrower) @@ -180,7 +180,7 @@ query predicate nodes(AstNode node) { } from - HTTP::RouteHandler rh, AsyncSentinelCall async, DataFlow::Node callbackArg, AsyncCallback cb, + Http::RouteHandler rh, AsyncSentinelCall async, DataFlow::Node callbackArg, AsyncCallback cb, ExprOrStmt crasher where main(rh, async, cb, crasher) and diff --git a/javascript/ql/src/experimental/poi/PoI.qll b/javascript/ql/src/experimental/poi/PoI.qll index 68143be6bdd..84134600406 100644 --- a/javascript/ql/src/experimental/poi/PoI.qll +++ b/javascript/ql/src/experimental/poi/PoI.qll @@ -77,7 +77,7 @@ private module StandardPoIs { UnpromotedRouteSetupPoI() { this = "UnpromotedRouteSetupPoI" } override predicate is(Node l0) { - l0 instanceof HTTP::RouteSetupCandidate and not l0 instanceof HTTP::RouteSetup + l0 instanceof Http::RouteSetupCandidate and not l0 instanceof Http::RouteSetup } } @@ -88,7 +88,7 @@ private module StandardPoIs { UnpromotedRouteHandlerPoI() { this = "UnpromotedRouteHandlerPoI" } override predicate is(Node l0) { - l0 instanceof HTTP::RouteHandlerCandidate and not l0 instanceof HTTP::RouteHandler + l0 instanceof Http::RouteHandlerCandidate and not l0 instanceof Http::RouteHandler } } @@ -98,7 +98,7 @@ private module StandardPoIs { class UnpromotedRouteHandlerWithFlowPoI extends PoI { UnpromotedRouteHandlerWithFlowPoI() { this = "UnpromotedRouteHandlerWithFlowPoI" } - private DataFlow::SourceNode track(HTTP::RouteHandlerCandidate cand, DataFlow::TypeTracker t) { + private DataFlow::SourceNode track(Http::RouteHandlerCandidate cand, DataFlow::TypeTracker t) { t.start() and result = cand or @@ -106,8 +106,8 @@ private module StandardPoIs { } override predicate is(Node l0, Node l1, string t1) { - l0 instanceof HTTP::RouteHandlerCandidate and - not l0 instanceof HTTP::RouteHandler and + l0 instanceof Http::RouteHandlerCandidate and + not l0 instanceof Http::RouteHandler and l1 = track(l0, TypeTracker::end()) and (if l1 = l0 then t1 = "ends here" else t1 = "starts/ends here") } diff --git a/javascript/ql/src/meta/analysis-quality/CandidateTracking.qll b/javascript/ql/src/meta/analysis-quality/CandidateTracking.qll index 509d5f2a482..72046169219 100644 --- a/javascript/ql/src/meta/analysis-quality/CandidateTracking.qll +++ b/javascript/ql/src/meta/analysis-quality/CandidateTracking.qll @@ -8,7 +8,7 @@ import javascript * Gets a source node to which `cand` may flow inter-procedurally, with `t` tracking * the state of flow. */ -DataFlow::SourceNode track(HTTP::RouteHandlerCandidate cand, DataFlow::TypeTracker t) { +DataFlow::SourceNode track(Http::RouteHandlerCandidate cand, DataFlow::TypeTracker t) { t.start() and result = cand or diff --git a/javascript/ql/src/meta/analysis-quality/RouteHandlers.ql b/javascript/ql/src/meta/analysis-quality/RouteHandlers.ql index 5da34036b18..fe09e0ea866 100644 --- a/javascript/ql/src/meta/analysis-quality/RouteHandlers.ql +++ b/javascript/ql/src/meta/analysis-quality/RouteHandlers.ql @@ -11,6 +11,6 @@ import javascript import CallGraphQuality -HTTP::RouteHandler relevantRouteHandler() { not result.getFile() instanceof IgnoredFile } +Http::RouteHandler relevantRouteHandler() { not result.getFile() instanceof IgnoredFile } select projectRoot(), count(relevantRouteHandler()) diff --git a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql index 89b26d734c5..c59d05932af 100644 --- a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql +++ b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteHandlerCandidate.ql @@ -11,10 +11,10 @@ import javascript import CandidateTracking -from HTTP::RouteHandlerCandidate rh +from Http::RouteHandlerCandidate rh where - not rh instanceof HTTP::RouteHandler and - not exists(HTTP::RouteSetupCandidate setup | + not rh instanceof Http::RouteHandler and + not exists(Http::RouteSetupCandidate setup | track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg()) ) select rh, diff --git a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql index 428f6b4e4b0..1fee417c396 100644 --- a/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql +++ b/javascript/ql/src/meta/analysis-quality/UnpromotedRouteSetupCandidate.ql @@ -11,10 +11,10 @@ import javascript import CandidateTracking -from HTTP::RouteSetupCandidate setup +from Http::RouteSetupCandidate setup where - not setup instanceof HTTP::RouteSetup and - exists(HTTP::RouteHandlerCandidate rh | + not setup instanceof Http::RouteSetup and + exists(Http::RouteHandlerCandidate rh | track(rh, DataFlow::TypeTracker::end()).flowsTo(setup.getARouteHandlerArg()) ) select setup, diff --git a/javascript/ql/test/library-tests/frameworks/Express/CookieMiddlewareInstance.qll b/javascript/ql/test/library-tests/frameworks/Express/CookieMiddlewareInstance.qll index 2f69ec905ae..025aaf04d00 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/CookieMiddlewareInstance.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/CookieMiddlewareInstance.qll @@ -1,7 +1,7 @@ import javascript query predicate test_CookieMiddlewareInstance( - HTTP::CookieMiddlewareInstance instance, DataFlow::Node res + Http::CookieMiddlewareInstance instance, DataFlow::Node res ) { res = instance.getASecretKey() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderAccess.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderAccess.qll index 22d1d6aee53..69d34318ae1 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderAccess(HTTP::RequestHeaderAccess access, string res) { +query predicate test_HeaderAccess(Http::RequestHeaderAccess access, string res) { res = access.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition.qll index 45ec0af926a..115aefb0e80 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Express::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Express::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_defines.qll index 2a82f238c29..eb8e7800cdd 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Express::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getAHeaderName.qll index f618f71ca34..dc534c8cfce 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll index 2a7da38aee2..717d96cbba3 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/HeaderDefinition_getNameExpr.qll @@ -1,7 +1,7 @@ import javascript query predicate test_HeaderDefinition_getNameExpr( - HTTP::ExplicitHeaderDefinition hd, DataFlow::Node res + Http::ExplicitHeaderDefinition hd, DataFlow::Node res ) { hd.getRouteHandler() instanceof Express::RouteHandler and res = hd.getNameNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RedirectInvocation.qll b/javascript/ql/test/library-tests/frameworks/Express/RedirectInvocation.qll index 909c3779416..3f1b8710454 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RedirectInvocation.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RedirectInvocation.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RedirectInvocation(HTTP::RedirectInvocation red, Express::RouteHandler rh) { +query predicate test_RedirectInvocation(Http::RedirectInvocation red, Express::RouteHandler rh) { rh = red.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll index 87c0bf32b0f..07ff4f22e0a 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RequestExpr.qll @@ -1,6 +1,6 @@ import javascript -query predicate test_RequestExpr(Express::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Express::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/Express/RequestInputAccess.qll index c27020e2aa1..8a7f2f046e2 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res0, Express::RouteHandler rh + Http::RequestInputAccess ria, string res0, Express::RouteHandler rh ) { ria.getRouteHandler() = rh and res0 = ria.getKind() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/ResponseBody.qll b/javascript/ql/test/library-tests/frameworks/Express/ResponseBody.qll index db571874490..8091681dfd7 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/ResponseBody.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/ResponseBody.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseBody(HTTP::ResponseBody rb, Express::RouteHandler rh) { +query predicate test_ResponseBody(Http::ResponseBody rb, Express::RouteHandler rh) { rb.getRouteHandler() = rh } diff --git a/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll index ad96e943511..5e911c96993 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Express::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Express::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/ResponseSendArgument.qll b/javascript/ql/test/library-tests/frameworks/Express/ResponseSendArgument.qll index fec7829f284..5fe3699e89c 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/ResponseSendArgument.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/ResponseSendArgument.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseSendArgument(HTTP::ResponseSendArgument send, Express::RouteHandler rh) { +query predicate test_ResponseSendArgument(Http::ResponseSendArgument send, Express::RouteHandler rh) { rh = send.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerContainer.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerContainer.qll index af341dc3028..994e8a318e2 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerContainer.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandlerContainer.qll @@ -1,7 +1,7 @@ import javascript query predicate getRouteHandlerContainerStep( - HTTP::RouteHandlerCandidateContainer container, DataFlow::SourceNode handler, + Http::RouteHandlerCandidateContainer container, DataFlow::SourceNode handler, DataFlow::SourceNode access ) { handler = container.getRouteHandler(access) diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll index 652b0a1bbde..04b657d87c3 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getARequestExpr(Express::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Express::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll index 6f9fece338d..70fead62bd5 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getAResponseExpr(Express::RouteHandler rh, HTTP::ResponseNode res) { +query predicate test_RouteHandler_getAResponseExpr(Express::RouteHandler rh, Http::ResponseNode res) { res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseHeader.qll index 24f59d9b604..490205a9881 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandler_getAResponseHeader( - Express::RouteHandler rh, string name, HTTP::HeaderDefinition res + Express::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRequestMethod.qll b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRequestMethod.qll index 48b0477a710..22d02c637ea 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRequestMethod.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouteSetup_getRequestMethod.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteSetup_getRequestMethod(Express::RouteSetup rs, HTTP::RequestMethodName res) { +query predicate test_RouteSetup_getRequestMethod(Express::RouteSetup rs, Http::RequestMethodName res) { res = rs.getRequestMethod() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getARouteHandler.qll b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getARouteHandler.qll index d9a5314002b..0117cbc3e1e 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getARouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/RouterDefinition_getARouteHandler.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouterDefinition_getARouteHandler( - Express::RouterDefinition r, HTTP::RouteHandler res + Express::RouterDefinition r, Http::RouteHandler res ) { res = r.getARouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Express/SetCookie.qll b/javascript/ql/test/library-tests/frameworks/Express/SetCookie.qll index adaa6cd3959..5e6c10d9ce4 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/SetCookie.qll +++ b/javascript/ql/test/library-tests/frameworks/Express/SetCookie.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_SetCookie(HTTP::CookieDefinition cookiedef, Express::RouteHandler rh) { +query predicate test_SetCookie(Http::CookieDefinition cookiedef, Express::RouteHandler rh) { rh = cookiedef.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Firebase/tests.ql b/javascript/ql/test/library-tests/frameworks/Firebase/tests.ql index 5cc891ec78c..13f4a097102 100644 --- a/javascript/ql/test/library-tests/frameworks/Firebase/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/Firebase/tests.ql @@ -6,8 +6,8 @@ query predicate firebaseSnapshot(DataFlow::SourceNode snap) { snap = Firebase::s query predicate firebaseVal(Firebase::FirebaseVal val) { any() } -query predicate requestInputAccess(HTTP::RequestInputAccess acc) { any() } +query predicate requestInputAccess(Http::RequestInputAccess acc) { any() } -query predicate responseSendArgument(HTTP::ResponseSendArgument send) { any() } +query predicate responseSendArgument(Http::ResponseSendArgument send) { any() } -query predicate routeHandler(HTTP::RouteHandler handler) { any() } +query predicate routeHandler(Http::RouteHandler handler) { any() } diff --git a/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/AdditionalRouteHandlers.ql b/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/AdditionalRouteHandlers.ql index 6f35b3854d3..d91d43b7cde 100644 --- a/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/AdditionalRouteHandlers.ql +++ b/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/AdditionalRouteHandlers.ql @@ -1,5 +1,5 @@ import javascript private import semmle.javascript.heuristics.AdditionalRouteHandlers -from HTTP::RouteHandler rh +from Http::RouteHandler rh select rh diff --git a/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/tests.ql b/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/tests.ql index ce0066ac8df..c85948e7552 100644 --- a/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/HTTP-heuristics/tests.ql @@ -1,9 +1,9 @@ import javascript -query predicate routeHandler(HTTP::RouteHandler rh) { any() } +query predicate routeHandler(Http::RouteHandler rh) { any() } -query predicate routeHandlerCandidate(HTTP::RouteHandlerCandidate rh) { any() } +query predicate routeHandlerCandidate(Http::RouteHandlerCandidate rh) { any() } -query predicate routeSetup(HTTP::RouteSetup rh) { any() } +query predicate routeSetup(Http::RouteSetup rh) { any() } -query predicate routeSetupCandidate(HTTP::RouteSetupCandidate rh) { any() } +query predicate routeSetupCandidate(Http::RouteSetupCandidate rh) { any() } diff --git a/javascript/ql/test/library-tests/frameworks/HTTP/RemoteRequestInput.ql b/javascript/ql/test/library-tests/frameworks/HTTP/RemoteRequestInput.ql index 8d8e4ab0362..03699197e14 100644 --- a/javascript/ql/test/library-tests/frameworks/HTTP/RemoteRequestInput.ql +++ b/javascript/ql/test/library-tests/frameworks/HTTP/RemoteRequestInput.ql @@ -1,4 +1,4 @@ import javascript -from HTTP::RequestInputAccess input +from Http::RequestInputAccess input select input, input.getKind() diff --git a/javascript/ql/test/library-tests/frameworks/HTTP/ResponseBody.ql b/javascript/ql/test/library-tests/frameworks/HTTP/ResponseBody.ql index 7723b4e284b..ab7aa08ea08 100644 --- a/javascript/ql/test/library-tests/frameworks/HTTP/ResponseBody.ql +++ b/javascript/ql/test/library-tests/frameworks/HTTP/ResponseBody.ql @@ -1,4 +1,4 @@ import javascript -from HTTP::ResponseBody rb +from Http::ResponseBody rb select rb diff --git a/javascript/ql/test/library-tests/frameworks/Micro/TestMicro.ql b/javascript/ql/test/library-tests/frameworks/Micro/TestMicro.ql index 97f4d7caf1e..56bf865f138 100644 --- a/javascript/ql/test/library-tests/frameworks/Micro/TestMicro.ql +++ b/javascript/ql/test/library-tests/frameworks/Micro/TestMicro.ql @@ -1,17 +1,17 @@ import javascript -query HTTP::RouteHandler routeHandler() { any() } +query Http::RouteHandler routeHandler() { any() } -query HTTP::Servers::RequestSource requestSource() { any() } +query Http::Servers::RequestSource requestSource() { any() } -query HTTP::Servers::ResponseSource responseSource() { any() } +query Http::Servers::ResponseSource responseSource() { any() } -query HTTP::RequestInputAccess requestInputAccess(string kind) { kind = result.getKind() } +query Http::RequestInputAccess requestInputAccess(string kind) { kind = result.getKind() } -query HTTP::RequestInputAccess userControlledObject() { result.isUserControlledObject() } +query Http::RequestInputAccess userControlledObject() { result.isUserControlledObject() } -query HTTP::ResponseSendArgument responseSendArgument() { any() } +query Http::ResponseSendArgument responseSendArgument() { any() } -query HTTP::ResponseSendArgument responseSendArgumentHandler(HTTP::RouteHandler h) { +query Http::ResponseSendArgument responseSendArgumentHandler(Http::RouteHandler h) { h = result.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/Nest/test.ql b/javascript/ql/test/library-tests/frameworks/Nest/test.ql index 120727d2548..898d244bed2 100644 --- a/javascript/ql/test/library-tests/frameworks/Nest/test.ql +++ b/javascript/ql/test/library-tests/frameworks/Nest/test.ql @@ -1,19 +1,19 @@ import javascript private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations -query HTTP::RouteHandler routeHandler() { any() } +query Http::RouteHandler routeHandler() { any() } -query HTTP::Servers::RequestSource requestSource() { any() } +query Http::Servers::RequestSource requestSource() { any() } -query HTTP::Servers::ResponseSource responseSource() { any() } +query Http::Servers::ResponseSource responseSource() { any() } query RemoteFlowSource requestInputAccess(string kind) { - kind = result.(HTTP::RequestInputAccess).getKind() + kind = result.(Http::RequestInputAccess).getKind() or - not result instanceof HTTP::RequestInputAccess and + not result instanceof Http::RequestInputAccess and kind = "RemoteFlowSource" } -query HTTP::ResponseSendArgument responseSendArgument() { any() } +query Http::ResponseSendArgument responseSendArgument() { any() } query ServerSideUrlRedirect::Sink redirectSink() { any() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderAccess.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderAccess.qll index 22d1d6aee53..69d34318ae1 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderAccess(HTTP::RequestHeaderAccess access, string res) { +query predicate test_HeaderAccess(Http::RequestHeaderAccess access, string res) { res = access.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition.qll index c1255a117c0..ec753397e68 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, NodeJSLib::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, NodeJSLib::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_defines.qll index a07c98b46be..1bc5d691f70 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof NodeJSLib::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getAHeaderName.qll index 7fcda812700..69b5623bd08 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof NodeJSLib::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll index b62e44bf947..4e1c2c5364d 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/HeaderDefinition_getNameExpr.qll @@ -1,7 +1,7 @@ import javascript query predicate test_HeaderDefinition_getNameExpr( - HTTP::ExplicitHeaderDefinition hd, DataFlow::Node res + Http::ExplicitHeaderDefinition hd, DataFlow::Node res ) { hd.getRouteHandler() instanceof NodeJSLib::RouteHandler and res = hd.getNameNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll index 282c04ce314..b9f4176406d 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(NodeJSLib::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(NodeJSLib::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestInputAccess.qll index 7134c96d028..2234da53435 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, NodeJSLib::RouteHandler rh + Http::RequestInputAccess ria, string res, NodeJSLib::RouteHandler rh ) { ria.getRouteHandler() = rh and res = ria.getKind() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll index b509b70c884..b8884efa167 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(NodeJSLib::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(NodeJSLib::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseSendArgument.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseSendArgument.qll index 7d859f4d569..890cc9f92fe 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseSendArgument.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ResponseSendArgument.qll @@ -1,7 +1,7 @@ import javascript query predicate test_ResponseSendArgument( - HTTP::ResponseSendArgument send, NodeJSLib::RouteHandler rh + Http::ResponseSendArgument send, NodeJSLib::RouteHandler rh ) { rh = send.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll index 147e788d642..b1080b85811 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RouteHandler_getARequestExpr(NodeJSLib::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(NodeJSLib::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll index f2871754551..05d27f18222 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseExpr.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RouteHandler_getAResponseExpr( - NodeJSLib::RouteHandler rh, HTTP::ResponseNode res + NodeJSLib::RouteHandler rh, Http::ResponseNode res ) { res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseHeader.qll index 6733b1bd917..1c14fc6ac11 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import semmle.javascript.frameworks.Express query predicate test_RouteHandler_getAResponseHeader( - NodeJSLib::RouteHandler rh, string name, HTTP::HeaderDefinition res + NodeJSLib::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ServerDefinition_getARouteHandler.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ServerDefinition_getARouteHandler.qll index 1902689a53e..900b632faed 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/ServerDefinition_getARouteHandler.qll +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/ServerDefinition_getARouteHandler.qll @@ -1,7 +1,7 @@ import javascript query predicate test_ServerDefinition_getARouteHandler( - NodeJSLib::ServerDefinition s, HTTP::RouteHandler res + NodeJSLib::ServerDefinition s, Http::RouteHandler res ) { res = s.getARouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/connect/tests.ql b/javascript/ql/test/library-tests/frameworks/connect/tests.ql index 17211377fbf..6c11c8ffd6b 100644 --- a/javascript/ql/test/library-tests/frameworks/connect/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/connect/tests.ql @@ -3,26 +3,26 @@ import javascript query predicate test_RouteSetup(Connect::RouteSetup rs) { any() } query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, Connect::RouteHandler rh + Http::RequestInputAccess ria, string res, Connect::RouteHandler rh ) { ria.getRouteHandler() = rh and res = ria.getKind() } query predicate test_RouteHandler_getAResponseHeader( - Connect::RouteHandler rh, string name, HTTP::HeaderDefinition res + Connect::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Connect::RouteHandler } -query predicate test_ResponseExpr(HTTP::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Http::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Connect::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Connect::RouteHandler rh) { rh = hd.getRouteHandler() } @@ -30,13 +30,13 @@ query predicate test_RouteSetup_getServer(Connect::RouteSetup rs, DataFlow::Node res = rs.getServer() } -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Connect::RouteHandler and res = hd.getAHeaderName() } query predicate test_ServerDefinition(Connect::ServerDefinition s) { any() } -query predicate test_RouteHandler_getAResponseExpr(Connect::RouteHandler rh, HTTP::ResponseNode res) { +query predicate test_RouteHandler_getAResponseExpr(Connect::RouteHandler rh, Http::ResponseNode res) { res = rh.getAResponseNode() } @@ -48,7 +48,7 @@ query predicate test_RouteHandler(Connect::RouteHandler rh, DataFlow::Node res) res = rh.getServer() } -query predicate test_RequestExpr(HTTP::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Http::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } @@ -56,6 +56,6 @@ query predicate test_Credentials(Connect::Credentials cr, string res) { res = cr.getCredentialsKind() } -query predicate test_RouteHandler_getARequestExpr(Connect::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Connect::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/HeaderAccess.qll b/javascript/ql/test/library-tests/frameworks/fastify/HeaderAccess.qll index 22d1d6aee53..69d34318ae1 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/HeaderAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/HeaderAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderAccess(HTTP::RequestHeaderAccess access, string res) { +query predicate test_HeaderAccess(Http::RequestHeaderAccess access, string res) { res = access.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition.qll index bf3ef7fb7fc..f3cef14be34 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Fastify::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Fastify::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_defines.qll index 43413a4dc4b..3bfab852a0c 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Fastify::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_getAHeaderName.qll index 62e1d62c06f..41ae7de8a97 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Fastify::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RedirectInvocation.qll b/javascript/ql/test/library-tests/frameworks/fastify/RedirectInvocation.qll index fffbf35a79e..e0044bcbee1 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RedirectInvocation.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RedirectInvocation.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RedirectInvocation(HTTP::RedirectInvocation invk, Fastify::RouteHandler rh) { +query predicate test_RedirectInvocation(Http::RedirectInvocation invk, Fastify::RouteHandler rh) { invk.getRouteHandler() = rh } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/fastify/RequestInputAccess.qll index d8cdc2a4ccb..bb649d75b4c 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, Fastify::RouteHandler rh, boolean isUserControlledObject + Http::RequestInputAccess ria, string res, Fastify::RouteHandler rh, boolean isUserControlledObject ) { ria.getRouteHandler() = rh and res = ria.getKind() and diff --git a/javascript/ql/test/library-tests/frameworks/fastify/ResponseSendArgument.qll b/javascript/ql/test/library-tests/frameworks/fastify/ResponseSendArgument.qll index 8f221b18bd7..de79ce0cd5b 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/ResponseSendArgument.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/ResponseSendArgument.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseSendArgument(HTTP::ResponseSendArgument arg, Fastify::RouteHandler rh) { +query predicate test_ResponseSendArgument(Http::ResponseSendArgument arg, Fastify::RouteHandler rh) { arg.getRouteHandler() = rh } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll index c709d84e745..b3e0fc1b098 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Fastify::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Fastify::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getAResponseHeader.qll index a5394519940..fd2f356be13 100644 --- a/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/fastify/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import semmle.javascript.frameworks.Express query predicate test_RouteHandler_getAResponseHeader( - Fastify::RouteHandler rh, string name, HTTP::HeaderDefinition res + Fastify::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/HeaderAccess.qll b/javascript/ql/test/library-tests/frameworks/hapi/HeaderAccess.qll index 22d1d6aee53..69d34318ae1 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/HeaderAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/HeaderAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderAccess(HTTP::RequestHeaderAccess access, string res) { +query predicate test_HeaderAccess(Http::RequestHeaderAccess access, string res) { res = access.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition.qll index 5ed82a5f591..612a1fa082b 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Hapi::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Hapi::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_defines.qll index 56ccb45dcfb..836b4e686f6 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Hapi::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_getAHeaderName.qll index 7bc108da973..06f3fe3f220 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Hapi::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll index 6e3118f1345..166b20ce8ed 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Hapi::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Hapi::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/hapi/RequestInputAccess.qll index 4146cb91cb6..5ce1fe4b5f6 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, Hapi::RouteHandler rh + Http::RequestInputAccess ria, string res, Hapi::RouteHandler rh ) { ria.getRouteHandler() = rh and res = ria.getKind() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll index 93a356284fe..3e2c2bca5c6 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Hapi::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Hapi::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll index 668ded20aea..06bbbe11fde 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Hapi::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Hapi::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getAResponseHeader.qll index 84aa08d92e1..4eb30875385 100644 --- a/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/hapi/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import semmle.javascript.frameworks.Express query predicate test_RouteHandler_getAResponseHeader( - Hapi::RouteHandler rh, string name, HTTP::HeaderDefinition res + Hapi::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/javascript/ql/test/library-tests/frameworks/koa/HeaderAccess.qll b/javascript/ql/test/library-tests/frameworks/koa/HeaderAccess.qll index 22d1d6aee53..69d34318ae1 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/HeaderAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/HeaderAccess.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderAccess(HTTP::RequestHeaderAccess access, string res) { +query predicate test_HeaderAccess(Http::RequestHeaderAccess access, string res) { res = access.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition.qll index 972b3999b41..338717d1d28 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Koa::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Koa::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_defines.qll index 1fd1f5550b8..d33943b9b57 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Koa::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_getAHeaderName.qll index faec0fac04d..20d6e34bb42 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Koa::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll b/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll index c6d46ef8a02..802fc6a5c18 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RedirectInvocation.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RedirectInvocation( - HTTP::RedirectInvocation redirect, DataFlow::Node url, HTTP::RouteHandler rh + Http::RedirectInvocation redirect, DataFlow::Node url, Http::RouteHandler rh ) { redirect.getUrlArgument() = url and redirect.getRouteHandler() = rh diff --git a/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll index bcb3177b053..94e18fa6477 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Koa::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Koa::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/koa/RequestInputAccess.qll index 2e4e226fd3e..2c1601520f1 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, Koa::RouteHandler rh + Http::RequestInputAccess ria, string res, Koa::RouteHandler rh ) { ria.getRouteHandler() = rh and res = ria.getKind() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll index 908dcdc745f..a6d1108ebec 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Koa::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Koa::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/ResponseSendArgument.qll b/javascript/ql/test/library-tests/frameworks/koa/ResponseSendArgument.qll index f0c3e9d2ea2..ccec2620e4f 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/ResponseSendArgument.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/ResponseSendArgument.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseSendArgument(HTTP::ResponseSendArgument send, Koa::RouteHandler rh) { +query predicate test_ResponseSendArgument(Http::ResponseSendArgument send, Koa::RouteHandler rh) { rh = send.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll index 3c844c953e4..7e251ad1ea8 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Koa::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Koa::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll index 492386d4053..045a8b5fae4 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getAResponseExpr(Koa::RouteHandler rh, HTTP::ResponseNode res) { +query predicate test_RouteHandler_getAResponseExpr(Koa::RouteHandler rh, Http::ResponseNode res) { res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseHeader.qll index 98c613dc5c8..f1b8b481d36 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/koa/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import semmle.javascript.frameworks.Express query predicate test_RouteHandler_getAResponseHeader( - Koa::RouteHandler rh, string name, HTTP::HeaderDefinition res + Koa::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition.qll b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition.qll index 9e101f7ea37..d5661ccaa94 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition(HTTP::HeaderDefinition hd, Restify::RouteHandler rh) { +query predicate test_HeaderDefinition(Http::HeaderDefinition hd, Restify::RouteHandler rh) { rh = hd.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_defines.qll b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_defines.qll index 3f6694173ca..8851bc55c77 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_defines.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_defines.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_defines(HTTP::HeaderDefinition hd, string name, string value) { +query predicate test_HeaderDefinition_defines(Http::HeaderDefinition hd, string name, string value) { hd.defines(name, value) and hd.getRouteHandler() instanceof Restify::RouteHandler } diff --git a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_getAHeaderName.qll b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_getAHeaderName.qll index f546a156991..9881464b56b 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_getAHeaderName.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/HeaderDefinition_getAHeaderName.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_HeaderDefinition_getAHeaderName(HTTP::HeaderDefinition hd, string res) { +query predicate test_HeaderDefinition_getAHeaderName(Http::HeaderDefinition hd, string res) { hd.getRouteHandler() instanceof Restify::RouteHandler and res = hd.getAHeaderName() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll index c4759c6892f..2c4f75d365a 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RequestExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_RequestExpr(Restify::RequestNode e, HTTP::RouteHandler res) { +query predicate test_RequestExpr(Restify::RequestNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RequestInputAccess.qll b/javascript/ql/test/library-tests/frameworks/restify/RequestInputAccess.qll index 0c9f028f443..64cb1d74293 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RequestInputAccess.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RequestInputAccess.qll @@ -1,7 +1,7 @@ import javascript query predicate test_RequestInputAccess( - HTTP::RequestInputAccess ria, string res, Restify::RouteHandler rh + Http::RequestInputAccess ria, string res, Restify::RouteHandler rh ) { ria.getRouteHandler() = rh and res = ria.getKind() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll index 1384ad6c850..b4fd9368a1d 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/ResponseExpr.qll @@ -1,5 +1,5 @@ import javascript -query predicate test_ResponseExpr(Restify::ResponseNode e, HTTP::RouteHandler res) { +query predicate test_ResponseExpr(Restify::ResponseNode e, Http::RouteHandler res) { res = e.getRouteHandler() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll index d02c6f82ad3..4f76b514b2f 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getARequestExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getARequestExpr(Restify::RouteHandler rh, HTTP::RequestNode res) { +query predicate test_RouteHandler_getARequestExpr(Restify::RouteHandler rh, Http::RequestNode res) { res = rh.getARequestNode() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll index e09d139d651..22d5d612a41 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseExpr.qll @@ -1,5 +1,5 @@ import semmle.javascript.frameworks.Express -query predicate test_RouteHandler_getAResponseExpr(Restify::RouteHandler rh, HTTP::ResponseNode res) { +query predicate test_RouteHandler_getAResponseExpr(Restify::RouteHandler rh, Http::ResponseNode res) { res = rh.getAResponseNode() } diff --git a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseHeader.qll b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseHeader.qll index d807f4879ab..f072f0146e6 100644 --- a/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseHeader.qll +++ b/javascript/ql/test/library-tests/frameworks/restify/RouteHandler_getAResponseHeader.qll @@ -1,7 +1,7 @@ import semmle.javascript.frameworks.Express query predicate test_RouteHandler_getAResponseHeader( - Restify::RouteHandler rh, string name, HTTP::HeaderDefinition res + Restify::RouteHandler rh, string name, Http::HeaderDefinition res ) { res = rh.getAResponseHeader(name) } diff --git a/python/ql/lib/semmle/python/Concepts.qll b/python/ql/lib/semmle/python/Concepts.qll index b3d1cb6fe84..b4f1c73e633 100644 --- a/python/ql/lib/semmle/python/Concepts.qll +++ b/python/ql/lib/semmle/python/Concepts.qll @@ -565,7 +565,7 @@ module XML { } /** Provides classes for modeling LDAP-related APIs. */ -module LDAP { +module Ldap { /** * A data-flow node that executes an LDAP query. * @@ -598,6 +598,9 @@ module LDAP { } } +/** DEPRECATED: Alias for Ldap */ +deprecated module LDAP = Ldap; + /** * A data-flow node that escapes meta-characters, which could be used to prevent * injection attacks. @@ -706,7 +709,7 @@ class LdapFilterEscaping extends Escaping { } /** Provides classes for modeling HTTP-related APIs. */ -module HTTP { +module Http { /** Gets an HTTP verb, in upper case */ string httpVerb() { result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] } @@ -917,7 +920,7 @@ module HTTP { * Extend this class to model new APIs. If you want to refine existing API models, * extend `HttpResponse` instead. */ - abstract class Range extends HTTP::Server::HttpResponse::Range { + abstract class Range extends Http::Server::HttpResponse::Range { /** Gets the data-flow node that specifies the location of this HTTP redirect response. */ abstract DataFlow::Node getRedirectLocation(); } @@ -1051,6 +1054,9 @@ module HTTP { // remote-flow-sources in general. } +/** DEPRECATED: Alias for Http */ +deprecated module HTTP = Http; + /** * Provides models for cryptographic things. * diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll index 5f687a01b49..f067ecf6eee 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll @@ -59,7 +59,7 @@ module AiohttpWebModel { * Extend this class to refine existing API models. If you want to model new APIs, * extend `AiohttpRouteSetup::Range` instead. */ - class AiohttpRouteSetup extends HTTP::Server::RouteSetup::Range { + class AiohttpRouteSetup extends Http::Server::RouteSetup::Range { AiohttpRouteSetup::Range range; AiohttpRouteSetup() { this = range } @@ -161,7 +161,7 @@ module AiohttpWebModel { AiohttpAddRouteCall() { exists(string funcName | - funcName = HTTP::httpVerbLower() and + funcName = Http::httpVerbLower() and routeArgsStart = 0 or funcName = "view" and @@ -192,7 +192,7 @@ module AiohttpWebModel { AiohttpDecoratorRouteSetup() { exists(string decoratorName | - decoratorName = HTTP::httpVerbLower() and + decoratorName = Http::httpVerbLower() and routeArgsStart = 0 or decoratorName = "view" and @@ -237,7 +237,7 @@ module AiohttpWebModel { // TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with // points-to and `.lookup`, which would handle `post = my_post_handler` inside class def result = this.getAMethod() and - result.getName() = HTTP::httpVerbLower() + result.getName() = Http::httpVerbLower() } } @@ -252,7 +252,7 @@ module AiohttpWebModel { } /** A request handler defined in an `aiohttp.web` view class, that has no known route. */ - private class AiohttpViewClassRequestHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range { + private class AiohttpViewClassRequestHandlerWithoutKnownRoute extends Http::Server::RequestHandler::Range { AiohttpViewClassRequestHandlerWithoutKnownRoute() { exists(AiohttpViewClass vc | vc.getARequestHandler() = this) and not exists(AiohttpRouteSetup setup | setup.getARequestHandler() = this) @@ -319,7 +319,7 @@ module AiohttpWebModel { } /** An attribute read on an `aiohttp.web.Request` that is a `MultiDictProxy` instance. */ - class AiohttpRequestMultiDictProxyInstances extends Multidict::MultiDictProxy::InstanceSource { + class AiohttpRequestMultiDictProxyInstances extends MultiDict::MultiDictProxy::InstanceSource { AiohttpRequestMultiDictProxyInstances() { this.(DataFlow::AttrRead).getObject() = Request::instance() and this.(DataFlow::AttrRead).getAttributeName() in ["query", "headers"] @@ -493,7 +493,7 @@ module AiohttpWebModel { * - https://docs.aiohttp.org/en/stable/web_reference.html#aiohttp.web.Response * - https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-exceptions */ - class AiohttpWebResponseInstantiation extends HTTP::Server::HttpResponse::Range, + class AiohttpWebResponseInstantiation extends Http::Server::HttpResponse::Range, Response::InstanceSource, DataFlow::CallCfgNode { API::Node apiNode; @@ -562,7 +562,7 @@ module AiohttpWebModel { * See the part about redirects at https://docs.aiohttp.org/en/stable/web_quickstart.html#aiohttp-web-exceptions */ class AiohttpRedirectExceptionInstantiation extends AiohttpWebResponseInstantiation, - HTTP::Server::HttpRedirectResponse::Range { + Http::Server::HttpRedirectResponse::Range { AiohttpRedirectExceptionInstantiation() { exists(string httpRedirectExceptionClassName | httpRedirectExceptionClassName in [ @@ -585,7 +585,7 @@ module AiohttpWebModel { /** * A call to `set_cookie` on a HTTP Response. */ - class AiohttpResponseSetCookieCall extends HTTP::Server::CookieWrite::Range, DataFlow::CallCfgNode { + class AiohttpResponseSetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::CallCfgNode { AiohttpResponseSetCookieCall() { this = aiohttpResponseInstance().getMember("set_cookie").getACall() } @@ -600,7 +600,7 @@ module AiohttpWebModel { /** * A call to `del_cookie` on a HTTP Response. */ - class AiohttpResponseDelCookieCall extends HTTP::Server::CookieWrite::Range, DataFlow::CallCfgNode { + class AiohttpResponseDelCookieCall extends Http::Server::CookieWrite::Range, DataFlow::CallCfgNode { AiohttpResponseDelCookieCall() { this = aiohttpResponseInstance().getMember("del_cookie").getACall() } @@ -616,7 +616,7 @@ module AiohttpWebModel { * A dict-like write to an item of the `cookies` attribute on a HTTP response, such as * `response.cookies[name] = value`. */ - class AiohttpResponseCookieSubscriptWrite extends HTTP::Server::CookieWrite::Range { + class AiohttpResponseCookieSubscriptWrite extends Http::Server::CookieWrite::Range { DataFlow::Node index; DataFlow::Node value; @@ -661,11 +661,11 @@ private module AiohttpClientModel { private API::Node instance() { result = classRef().getReturn() } /** A method call on a ClientSession that sends off a request */ - private class OutgoingRequestCall extends HTTP::Client::Request::Range, API::CallNode { + private class OutgoingRequestCall extends Http::Client::Request::Range, API::CallNode { string methodName; OutgoingRequestCall() { - methodName in [HTTP::httpVerbLower(), "request"] and + methodName in [Http::httpVerbLower(), "request"] and this = instance().getMember(methodName).getACall() } diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index a430513cb62..03d34e8548e 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -1155,11 +1155,11 @@ module PrivateDjango { /** Gets a reference to the `django.http` module. */ API::Node http() { result = django().getMember("http") } - /** DEPRECATED: Alias for `Http` */ - deprecated module http = Http; + /** DEPRECATED: Alias for `DjangoHttp` */ + deprecated module http = DjangoHttp; /** Provides models for the `django.http` module */ - module Http { + module DjangoHttp { // --------------------------------------------------------------------------- // django.http.request // --------------------------------------------------------------------------- @@ -1251,7 +1251,7 @@ module PrivateDjango { // special handling of the `build_absolute_uri` method, see // https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.build_absolute_uri exists(DataFlow::AttrRead attr, DataFlow::CallCfgNode call, DataFlow::Node instance | - instance = DjangoImpl::Http::Request::HttpRequest::instance() and + instance = DjangoImpl::DjangoHttp::Request::HttpRequest::instance() and attr.getObject() = instance | attr.getAttributeName() = "build_absolute_uri" and @@ -1359,7 +1359,7 @@ module PrivateDjango { * * Use the predicate `HttpResponse::instance()` to get references to instances of `django.http.response.HttpResponse`. */ - abstract class InstanceSource extends HTTP::Server::HttpResponse::Range, DataFlow::Node { + abstract class InstanceSource extends Http::Server::HttpResponse::Range, DataFlow::Node { } /** A direct instantiation of `django.http.response.HttpResponse`. */ @@ -1421,7 +1421,7 @@ module PrivateDjango { * Use the predicate `HttpResponseRedirect::instance()` to get references to instances of `django.http.response.HttpResponseRedirect`. */ abstract class InstanceSource extends HttpResponse::InstanceSource, - HTTP::Server::HttpRedirectResponse::Range, DataFlow::Node { } + Http::Server::HttpRedirectResponse::Range, DataFlow::Node { } /** A direct instantiation of `django.http.response.HttpResponseRedirect`. */ private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { @@ -1483,7 +1483,7 @@ module PrivateDjango { * Use the predicate `HttpResponsePermanentRedirect::instance()` to get references to instances of `django.http.response.HttpResponsePermanentRedirect`. */ abstract class InstanceSource extends HttpResponse::InstanceSource, - HTTP::Server::HttpRedirectResponse::Range, DataFlow::Node { } + Http::Server::HttpRedirectResponse::Range, DataFlow::Node { } /** A direct instantiation of `django.http.response.HttpResponsePermanentRedirect`. */ private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { @@ -2066,17 +2066,17 @@ module PrivateDjango { /** Gets a reference to the `django.http.response.HttpResponse.write` function. */ private DataFlow::TypeTrackingNode write( - DjangoImpl::Http::Response::HttpResponse::InstanceSource instance, DataFlow::TypeTracker t + DjangoImpl::DjangoHttp::Response::HttpResponse::InstanceSource instance, DataFlow::TypeTracker t ) { t.startInAttr("write") and - instance = DjangoImpl::Http::Response::HttpResponse::instance() and + instance = DjangoImpl::DjangoHttp::Response::HttpResponse::instance() and result = instance or exists(DataFlow::TypeTracker t2 | result = write(instance, t2).track(t2, t)) } /** Gets a reference to the `django.http.response.HttpResponse.write` function. */ - DataFlow::Node write(DjangoImpl::Http::Response::HttpResponse::InstanceSource instance) { + DataFlow::Node write(DjangoImpl::DjangoHttp::Response::HttpResponse::InstanceSource instance) { write(instance, DataFlow::TypeTracker::end()).flowsTo(result) } @@ -2085,8 +2085,8 @@ module PrivateDjango { * * See https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpResponse.write */ - class HttpResponseWriteCall extends HTTP::Server::HttpResponse::Range, DataFlow::CallCfgNode { - DjangoImpl::Http::Response::HttpResponse::InstanceSource instance; + class HttpResponseWriteCall extends Http::Server::HttpResponse::Range, DataFlow::CallCfgNode { + DjangoImpl::DjangoHttp::Response::HttpResponse::InstanceSource instance; HttpResponseWriteCall() { this.getFunction() = write(instance) } @@ -2104,10 +2104,10 @@ module PrivateDjango { /** * A call to `set_cookie` on a HTTP Response. */ - class DjangoResponseSetCookieCall extends HTTP::Server::CookieWrite::Range, + class DjangoResponseSetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { DjangoResponseSetCookieCall() { - this.calls(DjangoImpl::Http::Response::HttpResponse::instance(), "set_cookie") + this.calls(DjangoImpl::DjangoHttp::Response::HttpResponse::instance(), "set_cookie") } override DataFlow::Node getHeaderArg() { none() } @@ -2124,10 +2124,10 @@ module PrivateDjango { /** * A call to `delete_cookie` on a HTTP Response. */ - class DjangoResponseDeleteCookieCall extends HTTP::Server::CookieWrite::Range, + class DjangoResponseDeleteCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { DjangoResponseDeleteCookieCall() { - this.calls(DjangoImpl::Http::Response::HttpResponse::instance(), "delete_cookie") + this.calls(DjangoImpl::DjangoHttp::Response::HttpResponse::instance(), "delete_cookie") } override DataFlow::Node getHeaderArg() { none() } @@ -2143,7 +2143,7 @@ module PrivateDjango { * A dict-like write to an item of the `cookies` attribute on a HTTP response, such as * `response.cookies[name] = value`. */ - class DjangoResponseCookieSubscriptWrite extends HTTP::Server::CookieWrite::Range { + class DjangoResponseCookieSubscriptWrite extends Http::Server::CookieWrite::Range { DataFlow::Node index; DataFlow::Node value; @@ -2154,7 +2154,7 @@ module PrivateDjango { this.asCfgNode() = subscript | cookieLookup.getAttributeName() = "cookies" and - cookieLookup.getObject() = DjangoImpl::Http::Response::HttpResponse::instance() and + cookieLookup.getObject() = DjangoImpl::DjangoHttp::Response::HttpResponse::instance() and exists(DataFlow::Node subscriptObj | subscriptObj.asCfgNode() = subscript.getObject() | @@ -2315,7 +2315,7 @@ module PrivateDjango { // points-to and `.lookup`, which would handle `post = my_post_handler` inside class def result = this.getAMethod() and ( - result.getName() = HTTP::httpVerbLower() + result.getName() = Http::httpVerbLower() or result.getName() = "get_redirect_url" ) @@ -2410,7 +2410,7 @@ module PrivateDjango { } /** A data-flow node that sets up a route on a server, using the django framework. */ - abstract class DjangoRouteSetup extends HTTP::Server::RouteSetup::Range, DataFlow::CfgNode { + abstract class DjangoRouteSetup extends Http::Server::RouteSetup::Range, DataFlow::CfgNode { /** Gets the data-flow node that is used as the argument for the view handler. */ abstract DataFlow::Node getViewArg(); @@ -2427,7 +2427,7 @@ module PrivateDjango { } /** A request handler defined in a django view class, that has no known route. */ - private class DjangoViewClassHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range, + private class DjangoViewClassHandlerWithoutKnownRoute extends Http::Server::RequestHandler::Range, DjangoRouteHandler { DjangoViewClassHandlerWithoutKnownRoute() { exists(DjangoViewClass vc | vc.getARequestHandler() = this) and @@ -2586,7 +2586,7 @@ module PrivateDjango { // HttpRequest taint modeling // --------------------------------------------------------------------------- /** A parameter that will receive the django `HttpRequest` instance when a request handler is invoked. */ - private class DjangoRequestHandlerRequestParam extends DjangoImpl::Http::Request::HttpRequest::InstanceSource, + private class DjangoRequestHandlerRequestParam extends DjangoImpl::DjangoHttp::Request::HttpRequest::InstanceSource, RemoteFlowSource::Range, DataFlow::ParameterNode { DjangoRequestHandlerRequestParam() { this.getParameter() = any(DjangoRouteSetup setup).getARequestHandler().getRequestParam() @@ -2603,7 +2603,7 @@ module PrivateDjango { * * See https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/#dynamic-filtering */ - private class DjangoViewClassRequestAttributeRead extends DjangoImpl::Http::Request::HttpRequest::InstanceSource, + private class DjangoViewClassRequestAttributeRead extends DjangoImpl::DjangoHttp::Request::HttpRequest::InstanceSource, RemoteFlowSource::Range, DataFlow::Node { DjangoViewClassRequestAttributeRead() { exists(DataFlow::AttrRead read | this = read | @@ -2678,7 +2678,7 @@ module PrivateDjango { * * See https://docs.djangoproject.com/en/3.1/topics/http/shortcuts/#redirect */ - private class DjangoShortcutsRedirectCall extends HTTP::Server::HttpRedirectResponse::Range, + private class DjangoShortcutsRedirectCall extends Http::Server::HttpRedirectResponse::Range, DataFlow::CallCfgNode { DjangoShortcutsRedirectCall() { this = DjangoImpl::Shortcuts::redirect().getACall() } @@ -2712,7 +2712,7 @@ module PrivateDjango { * * See https://docs.djangoproject.com/en/3.1/ref/class-based-views/base/#redirectview */ - private class DjangoRedirectViewGetRedirectUrlReturn extends HTTP::Server::HttpRedirectResponse::Range, + private class DjangoRedirectViewGetRedirectUrlReturn extends Http::Server::HttpRedirectResponse::Range, DataFlow::CfgNode { DjangoRedirectViewGetRedirectUrlReturn() { node = any(GetRedirectUrlFunction f).getAReturnValueFlowNode() @@ -2751,7 +2751,7 @@ module PrivateDjango { /** * A custom middleware stack */ - private class DjangoSettingsMiddlewareStack extends HTTP::Server::CsrfProtectionSetting::Range { + private class DjangoSettingsMiddlewareStack extends Http::Server::CsrfProtectionSetting::Range { List list; DjangoSettingsMiddlewareStack() { @@ -2787,7 +2787,7 @@ module PrivateDjango { } } - private class DjangoCsrfDecorator extends HTTP::Server::CsrfLocalProtectionSetting::Range { + private class DjangoCsrfDecorator extends Http::Server::CsrfLocalProtectionSetting::Range { string decoratorName; Function function; diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll index f042dafea59..b45ef81f88a 100644 --- a/python/ql/lib/semmle/python/frameworks/FastApi.qll +++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll @@ -48,10 +48,10 @@ private module FastApi { * * See https://fastapi.tiangolo.com/tutorial/first-steps/#define-a-path-operation-decorator */ - private class FastApiRouteSetup extends HTTP::Server::RouteSetup::Range, DataFlow::CallCfgNode { + private class FastApiRouteSetup extends Http::Server::RouteSetup::Range, DataFlow::CallCfgNode { FastApiRouteSetup() { exists(string routeAddingMethod | - routeAddingMethod = HTTP::httpVerbLower() + routeAddingMethod = Http::httpVerbLower() or routeAddingMethod in ["api_route", "websocket"] | @@ -195,7 +195,7 @@ private module FastApi { abstract class InstanceSource extends DataFlow::LocalSourceNode { } /** A direct instantiation of a response class. */ - private class ResponseInstantiation extends InstanceSource, HTTP::Server::HttpResponse::Range, + private class ResponseInstantiation extends InstanceSource, Http::Server::HttpResponse::Range, DataFlow::CallCfgNode { API::Node baseApiNode; API::Node responseClass; @@ -223,7 +223,7 @@ private module FastApi { * A direct instantiation of a redirect response. */ private class RedirectResponseInstantiation extends ResponseInstantiation, - HTTP::Server::HttpRedirectResponse::Range { + Http::Server::HttpRedirectResponse::Range { RedirectResponseInstantiation() { baseApiNode = getModeledResponseClass("RedirectResponse") } override DataFlow::Node getRedirectLocation() { @@ -245,7 +245,7 @@ private module FastApi { /** * An implicit response from a return of FastAPI request handler. */ - private class FastApiRequestHandlerReturn extends HTTP::Server::HttpResponse::Range, + private class FastApiRequestHandlerReturn extends Http::Server::HttpResponse::Range, DataFlow::CfgNode { FastApiRouteSetup routeSetup; @@ -291,7 +291,7 @@ private module FastApi { * `response_class` set to a `RedirectResponse`. */ private class FastApiRequestHandlerRedirectReturn extends FastApiRequestHandlerReturn, - HTTP::Server::HttpRedirectResponse::Range { + Http::Server::HttpRedirectResponse::Range { FastApiRequestHandlerRedirectReturn() { exists(API::Node responseClass | responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and @@ -332,7 +332,7 @@ private module FastApi { /** * A call to `set_cookie` on a FastAPI Response. */ - private class SetCookieCall extends HTTP::Server::CookieWrite::Range, DataFlow::MethodCallNode { + private class SetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { SetCookieCall() { this.calls(instance(), "set_cookie") } override DataFlow::Node getHeaderArg() { none() } @@ -348,7 +348,7 @@ private module FastApi { * A call to `append` on a `headers` of a FastAPI Response, with the `Set-Cookie` * header-key. */ - private class HeadersAppendCookie extends HTTP::Server::CookieWrite::Range, + private class HeadersAppendCookie extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { HeadersAppendCookie() { exists(DataFlow::AttrRead headers, DataFlow::Node keyArg | diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 8ee93fcec52..890e45a2ab5 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -116,7 +116,7 @@ module Flask { * * Use the predicate `Response::instance()` to get references to instances of `flask.Response`. */ - abstract class InstanceSource extends HTTP::Server::HttpResponse::Range, DataFlow::Node { } + abstract class InstanceSource extends Http::Server::HttpResponse::Range, DataFlow::Node { } /** A direct instantiation of `flask.Response`. */ private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { @@ -229,7 +229,7 @@ module Flask { // TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with // points-to and `.lookup`, which would handle `post = my_post_handler` inside class def result = this.getAMethod() and - result.getName() = HTTP::httpVerbLower() + result.getName() = Http::httpVerbLower() } } @@ -241,7 +241,7 @@ module Flask { } /** A route setup made by flask (sharing handling of URL patterns). */ - abstract class FlaskRouteSetup extends HTTP::Server::RouteSetup::Range { + abstract class FlaskRouteSetup extends Http::Server::RouteSetup::Range { override Parameter getARoutedParameter() { // If we don't know the URL pattern, we simply mark all parameters as a routed // parameter. This should give us more RemoteFlowSources but could also lead to @@ -312,7 +312,7 @@ module Flask { } /** A request handler defined in a django view class, that has no known route. */ - private class FlaskViewClassHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range { + private class FlaskViewClassHandlerWithoutKnownRoute extends Http::Server::RequestHandler::Range { FlaskViewClassHandlerWithoutKnownRoute() { exists(FlaskViewClass vc | vc.getARequestHandler() = this) and not exists(FlaskRouteSetup setup | setup.getARequestHandler() = this) @@ -439,7 +439,7 @@ module Flask { // --------------------------------------------------------------------------- // Implicit response from returns of flask request handlers // --------------------------------------------------------------------------- - private class FlaskRouteHandlerReturn extends HTTP::Server::HttpResponse::Range, DataFlow::CfgNode { + private class FlaskRouteHandlerReturn extends Http::Server::HttpResponse::Range, DataFlow::CfgNode { FlaskRouteHandlerReturn() { exists(Function routeHandler | routeHandler = any(FlaskRouteSetup rs).getARequestHandler() and @@ -462,7 +462,7 @@ module Flask { * * See https://flask.palletsprojects.com/en/1.1.x/api/#flask.redirect */ - private class FlaskRedirectCall extends HTTP::Server::HttpRedirectResponse::Range, + private class FlaskRedirectCall extends Http::Server::HttpRedirectResponse::Range, DataFlow::CallCfgNode { FlaskRedirectCall() { this = API::moduleImport("flask").getMember("redirect").getACall() } @@ -490,7 +490,7 @@ module Flask { * * See https://flask.palletsprojects.com/en/2.0.x/api/#flask.Response.set_cookie */ - class FlaskResponseSetCookieCall extends HTTP::Server::CookieWrite::Range, + class FlaskResponseSetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { FlaskResponseSetCookieCall() { this.calls(Flask::Response::instance(), "set_cookie") } @@ -506,7 +506,7 @@ module Flask { * * See https://flask.palletsprojects.com/en/2.0.x/api/#flask.Response.delete_cookie */ - class FlaskResponseDeleteCookieCall extends HTTP::Server::CookieWrite::Range, + class FlaskResponseDeleteCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { FlaskResponseDeleteCookieCall() { this.calls(Flask::Response::instance(), "delete_cookie") } diff --git a/python/ql/lib/semmle/python/frameworks/Httpx.qll b/python/ql/lib/semmle/python/frameworks/Httpx.qll index b746de6ee5e..ec6a446db2e 100644 --- a/python/ql/lib/semmle/python/frameworks/Httpx.qll +++ b/python/ql/lib/semmle/python/frameworks/Httpx.qll @@ -23,11 +23,11 @@ private module HttpxModel { * * See https://www.python-httpx.org/api/ */ - private class RequestCall extends HTTP::Client::Request::Range, API::CallNode { + private class RequestCall extends Http::Client::Request::Range, API::CallNode { string methodName; RequestCall() { - methodName in [HTTP::httpVerbLower(), "request", "stream"] and + methodName in [Http::httpVerbLower(), "request", "stream"] and this = API::moduleImport("httpx").getMember(methodName).getACall() } @@ -64,11 +64,11 @@ private module HttpxModel { } /** A method call on a Client that sends off a request */ - private class OutgoingRequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class OutgoingRequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { string methodName; OutgoingRequestCall() { - methodName in [HTTP::httpVerbLower(), "request", "stream"] and + methodName in [Http::httpVerbLower(), "request", "stream"] and this = classRef().getReturn().getMember(methodName).getACall() } diff --git a/python/ql/lib/semmle/python/frameworks/Ldap.qll b/python/ql/lib/semmle/python/frameworks/Ldap.qll index 2f78c20cbe5..fddebba24f9 100644 --- a/python/ql/lib/semmle/python/frameworks/Ldap.qll +++ b/python/ql/lib/semmle/python/frameworks/Ldap.qll @@ -13,13 +13,13 @@ private import semmle.python.ApiGraphs * * See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html */ -private module Ldap { +private module PythonLdap { /** * The execution of an `ldap` query. * * See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#functions */ - private class LdapQueryExecution extends DataFlow::CallCfgNode, LDAP::LdapExecution::Range { + private class LdapQueryExecution extends DataFlow::CallCfgNode, Ldap::LdapExecution::Range { LdapQueryExecution() { this = API::moduleImport("ldap") diff --git a/python/ql/lib/semmle/python/frameworks/Ldap3.qll b/python/ql/lib/semmle/python/frameworks/Ldap3.qll index 6bf3d58cf99..860df4a3b84 100644 --- a/python/ql/lib/semmle/python/frameworks/Ldap3.qll +++ b/python/ql/lib/semmle/python/frameworks/Ldap3.qll @@ -15,7 +15,7 @@ private import semmle.python.ApiGraphs */ private module Ldap3 { /** The execution of an `ldap` query. */ - private class LdapQueryExecution extends DataFlow::CallCfgNode, LDAP::LdapExecution::Range { + private class LdapQueryExecution extends DataFlow::CallCfgNode, Ldap::LdapExecution::Range { LdapQueryExecution() { this = API::moduleImport("ldap3") diff --git a/python/ql/lib/semmle/python/frameworks/Libtaxii.qll b/python/ql/lib/semmle/python/frameworks/Libtaxii.qll index 44298b7c08f..5df0e7127ec 100644 --- a/python/ql/lib/semmle/python/frameworks/Libtaxii.qll +++ b/python/ql/lib/semmle/python/frameworks/Libtaxii.qll @@ -22,7 +22,7 @@ private module Libtaxii { * A call to `libtaxii.common.parse`. * When the `allow_url` parameter value is set to `True`, there is an SSRF vulnerability.. */ - private class ParseCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class ParseCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { ParseCall() { this = API::moduleImport("libtaxii").getMember("common").getMember("parse").getACall() and this.getArgByName("allow_url").getALocalSource().asExpr() = any(True t) diff --git a/python/ql/lib/semmle/python/frameworks/Multidict.qll b/python/ql/lib/semmle/python/frameworks/Multidict.qll index 06700e28347..71c1a9cd995 100644 --- a/python/ql/lib/semmle/python/frameworks/Multidict.qll +++ b/python/ql/lib/semmle/python/frameworks/Multidict.qll @@ -16,7 +16,7 @@ private import semmle.python.frameworks.internal.InstanceTaintStepsHelper * Provides models for the `multidict` PyPI package. * See https://multidict.readthedocs.io/en/stable/. */ -module Multidict { +module MultiDict { /** * Provides models for a `MultiDictProxy` class: * - `multidict.MultiDictProxy` @@ -88,3 +88,6 @@ module Multidict { } } } + +/** DEPRECATED: Alias for MultiDict */ +deprecated module Multidict = MultiDict; diff --git a/python/ql/lib/semmle/python/frameworks/Pycurl.qll b/python/ql/lib/semmle/python/frameworks/Pycurl.qll index 6a5fbcbcfeb..4317cfb7eca 100644 --- a/python/ql/lib/semmle/python/frameworks/Pycurl.qll +++ b/python/ql/lib/semmle/python/frameworks/Pycurl.qll @@ -36,7 +36,7 @@ private module Pycurl { * * See http://pycurl.io/docs/latest/curlobject.html#pycurl.Curl.setopt. */ - private class OutgoingRequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class OutgoingRequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { OutgoingRequestCall() { this = instance().getMember("setopt").getACall() and this.getArg(0).asCfgNode().(AttrNode).getName() = "URL" diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll index 0c944d889d2..d32860b177e 100644 --- a/python/ql/lib/semmle/python/frameworks/Requests.qll +++ b/python/ql/lib/semmle/python/frameworks/Requests.qll @@ -28,11 +28,11 @@ private module Requests { * * See https://requests.readthedocs.io/en/latest/api/#requests.request */ - private class OutgoingRequestCall extends HTTP::Client::Request::Range, API::CallNode { + private class OutgoingRequestCall extends Http::Client::Request::Range, API::CallNode { string methodName; OutgoingRequestCall() { - methodName in [HTTP::httpVerbLower(), "request"] and + methodName in [Http::httpVerbLower(), "request"] and ( this = API::moduleImport("requests").getMember(methodName).getACall() or diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll index c8f73f909c2..8406ee51e27 100644 --- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll +++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll @@ -158,7 +158,7 @@ private module RestFramework { * `HTTP::Server::RequestHandler`. We only need this for the ones that doesn't have a * known route setup. */ - class RestFrameworkFunctionBasedViewWithoutKnownRoute extends HTTP::Server::RequestHandler::Range, + class RestFrameworkFunctionBasedViewWithoutKnownRoute extends Http::Server::RequestHandler::Range, PrivateDjango::DjangoRouteHandler instanceof RestFrameworkFunctionBasedView { RestFrameworkFunctionBasedViewWithoutKnownRoute() { not exists(PrivateDjango::DjangoRouteSetup setup | setup.getARequestHandler() = this) @@ -220,7 +220,7 @@ private module RestFramework { * * Use the predicate `Request::instance()` to get references to instances of `rest_framework.request.Request`. */ - abstract class InstanceSource extends PrivateDjango::DjangoImpl::Http::Request::HttpRequest::InstanceSource { + abstract class InstanceSource extends PrivateDjango::DjangoImpl::DjangoHttp::Request::HttpRequest::InstanceSource { } /** A direct instantiation of `rest_framework.request.Request`. */ @@ -296,7 +296,7 @@ private module RestFramework { } /** A direct instantiation of `rest_framework.response.Response`. */ - private class ClassInstantiation extends PrivateDjango::DjangoImpl::Http::Response::HttpResponse::InstanceSource, + private class ClassInstantiation extends PrivateDjango::DjangoImpl::DjangoHttp::Response::HttpResponse::InstanceSource, DataFlow::CallCfgNode { ClassInstantiation() { this = classRef().getACall() } @@ -320,7 +320,7 @@ private module RestFramework { */ module ApiException { /** A direct instantiation of `rest_framework.exceptions.ApiException` or subclass. */ - private class ClassInstantiation extends HTTP::Server::HttpResponse::Range, + private class ClassInstantiation extends Http::Server::HttpResponse::Range, DataFlow::CallCfgNode { string className; diff --git a/python/ql/lib/semmle/python/frameworks/Starlette.qll b/python/ql/lib/semmle/python/frameworks/Starlette.qll index e22259d560c..a105d62c5b7 100644 --- a/python/ql/lib/semmle/python/frameworks/Starlette.qll +++ b/python/ql/lib/semmle/python/frameworks/Starlette.qll @@ -85,7 +85,7 @@ module Starlette { } /** An attribute read on a `starlette.websockets.WebSocket` instance that is a `starlette.requests.URL` instance. */ - private class UrlInstances extends URL::InstanceSource { + private class UrlInstances extends Url::InstanceSource { UrlInstances() { this.(DataFlow::AttrRead).getObject() = instance() and this.(DataFlow::AttrRead).getAttributeName() = "url" @@ -98,7 +98,7 @@ module Starlette { * * See the URL part of https://www.starlette.io/websockets/. */ - module URL { + module Url { /** Gets a reference to the `starlette.requests.URL` class. */ private API::Node classRef() { result = API::moduleImport("starlette").getMember("requests").getMember("URL") @@ -159,4 +159,7 @@ module Starlette { } } } + + /** DEPRECATED: Alias for Url */ + deprecated module URL = Url; } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 9b5ff4c291e..a6f476abecd 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -1877,7 +1877,7 @@ private module StdlibPrivate { API::Node http() { result = API::moduleImport("http") } /** Provides models for the `http` module. */ - module Http { + module StdHttp { // ------------------------------------------------------------------------- // http.server // ------------------------------------------------------------------------- @@ -1944,9 +1944,9 @@ private module StdlibPrivate { SimpleHttpServer::SimpleHttpRequestHandler::classRef(), CgiHttpServer::CgiHttpRequestHandler::classRef(), // Python 3 - Http::Server::BaseHttpRequestHandler::classRef(), - Http::Server::SimpleHttpRequestHandler::classRef(), - Http::Server::CgiHttpRequestHandler::classRef() + StdHttp::Server::BaseHttpRequestHandler::classRef(), + StdHttp::Server::SimpleHttpRequestHandler::classRef(), + StdHttp::Server::CgiHttpRequestHandler::classRef() ].getASubclass*() } @@ -2026,10 +2026,10 @@ private module StdlibPrivate { * * Not essential for any functionality, but provides a consistent modeling. */ - private class RequestHandlerFunc extends HTTP::Server::RequestHandler::Range { + private class RequestHandlerFunc extends Http::Server::RequestHandler::Range { RequestHandlerFunc() { this = any(HttpRequestHandlerClassDef cls).getAMethod() and - this.getName() = "do_" + HTTP::httpVerb() + this.getName() = "do_" + Http::httpVerb() } override Parameter getARoutedParameter() { none() } @@ -2064,7 +2064,7 @@ private module StdlibPrivate { * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L137 * for how a request is processed and given to an application. */ - class WsgirefSimpleServerApplication extends HTTP::Server::RequestHandler::Range { + class WsgirefSimpleServerApplication extends Http::Server::RequestHandler::Range { WsgirefSimpleServerApplication() { exists(DataFlow::Node appArg, DataFlow::CallCfgNode setAppCall | ( @@ -2166,7 +2166,7 @@ private module StdlibPrivate { * * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L276 */ - class WsgirefSimpleServerApplicationWriteCall extends HTTP::Server::HttpResponse::Range, + class WsgirefSimpleServerApplicationWriteCall extends Http::Server::HttpResponse::Range, DataFlow::CallCfgNode { WsgirefSimpleServerApplicationWriteCall() { this.getFunction() = writeFunction() } @@ -2180,7 +2180,7 @@ private module StdlibPrivate { /** * A return from a `WsgirefSimpleServerApplication`, which is included in the response body. */ - class WsgirefSimpleServerApplicationReturn extends HTTP::Server::HttpResponse::Range, + class WsgirefSimpleServerApplicationReturn extends Http::Server::HttpResponse::Range, DataFlow::CfgNode { WsgirefSimpleServerApplicationReturn() { exists(WsgirefSimpleServerApplication requestHandler | @@ -2267,7 +2267,7 @@ private module StdlibPrivate { } /** A method call on a HttpConnection that sends off a request */ - private class RequestCall extends HTTP::Client::Request::Range, DataFlow::MethodCallNode { + private class RequestCall extends Http::Client::Request::Range, DataFlow::MethodCallNode { RequestCall() { this.calls(instance(_), ["request", "_send_request", "putrequest"]) } DataFlow::Node getUrlArg() { result in [this.getArg(1), this.getArgByName("url")] } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib.qll index fa932af2673..3e0177f8a14 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib.qll @@ -30,7 +30,7 @@ private module Urllib { * See * - https://docs.python.org/3.9/library/urllib.request.html#urllib.request.Request */ - private class RequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class RequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { RequestCall() { this = API::moduleImport("urllib").getMember("request").getMember("Request").getACall() } @@ -52,7 +52,7 @@ private module Urllib { * See * - https://docs.python.org/3.9/library/urllib.request.html#urllib.request.urlopen */ - private class UrlOpenCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class UrlOpenCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { UrlOpenCall() { this = API::moduleImport("urllib").getMember("request").getMember("urlopen").getACall() } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib2.qll b/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib2.qll index e7e119d98c1..7fc9e5ea468 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib2.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib/Urllib2.qll @@ -20,7 +20,7 @@ private module Urllib2 { * See * - https://docs.python.org/2/library/urllib2.html#urllib2.Request */ - private class RequestCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class RequestCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { RequestCall() { this = API::moduleImport("urllib2").getMember("Request").getACall() } override DataFlow::Node getAUrlPart() { result in [this.getArg(0), this.getArgByName("url")] } @@ -40,7 +40,7 @@ private module Urllib2 { * See * - https://docs.python.org/2/library/urllib2.html#urllib2.urlopen */ - private class UrlOpenCall extends HTTP::Client::Request::Range, DataFlow::CallCfgNode { + private class UrlOpenCall extends Http::Client::Request::Range, DataFlow::CallCfgNode { UrlOpenCall() { this = API::moduleImport("urllib2").getMember("urlopen").getACall() } override DataFlow::Node getAUrlPart() { result in [this.getArg(0), this.getArgByName("url")] } diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index d66da17aa5d..77c60097cb5 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -99,7 +99,7 @@ private module Tornado { // TODO: This doesn't handle attribute assignment. Should be OK, but analysis is not as complete as with // points-to and `.lookup`, which would handle `post = my_post_handler` inside class def result = this.getAMethod() and - result.getName() = HTTP::httpVerbLower() + result.getName() = Http::httpVerbLower() } /** Gets a reference to this class. */ @@ -375,7 +375,7 @@ private module Tornado { } /** A tornado route setup. */ - abstract class TornadoRouteSetup extends HTTP::Server::RouteSetup::Range { + abstract class TornadoRouteSetup extends Http::Server::RouteSetup::Range { override string getFramework() { result = "Tornado" } } @@ -437,7 +437,7 @@ private module Tornado { } /** A request handler defined in a tornado RequestHandler class, that has no known route. */ - private class TornadoRequestHandlerWithoutKnownRoute extends HTTP::Server::RequestHandler::Range { + private class TornadoRequestHandlerWithoutKnownRoute extends Http::Server::RequestHandler::Range { TornadoRequestHandlerWithoutKnownRoute() { exists(TornadoModule::Web::RequestHandler::RequestHandlerClass cls | cls.getARequestHandler() = this @@ -464,7 +464,7 @@ private module Tornado { * * See https://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.redirect */ - private class TornadoRequestHandlerRedirectCall extends HTTP::Server::HttpRedirectResponse::Range, + private class TornadoRequestHandlerRedirectCall extends Http::Server::HttpRedirectResponse::Range, DataFlow::CallCfgNode { TornadoRequestHandlerRedirectCall() { this.getFunction() = TornadoModule::Web::RequestHandler::redirectMethod() @@ -486,7 +486,7 @@ private module Tornado { * * See https://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.write */ - private class TornadoRequestHandlerWriteCall extends HTTP::Server::HttpResponse::Range, + private class TornadoRequestHandlerWriteCall extends Http::Server::HttpResponse::Range, DataFlow::CallCfgNode { TornadoRequestHandlerWriteCall() { this.getFunction() = TornadoModule::Web::RequestHandler::writeMethod() @@ -504,7 +504,7 @@ private module Tornado { * * See https://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.set_cookie */ - class TornadoRequestHandlerSetCookieCall extends HTTP::Server::CookieWrite::Range, + class TornadoRequestHandlerSetCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { TornadoRequestHandlerSetCookieCall() { this.calls(TornadoModule::Web::RequestHandler::instance(), "set_cookie") diff --git a/python/ql/lib/semmle/python/frameworks/Twisted.qll b/python/ql/lib/semmle/python/frameworks/Twisted.qll index c316321555e..34218c7543f 100644 --- a/python/ql/lib/semmle/python/frameworks/Twisted.qll +++ b/python/ql/lib/semmle/python/frameworks/Twisted.qll @@ -60,7 +60,7 @@ private module Twisted { } /** A method that handles incoming requests, on a `twisted.web.resource.Resource` subclass. */ - class TwistedResourceRequestHandler extends HTTP::Server::RequestHandler::Range { + class TwistedResourceRequestHandler extends Http::Server::RequestHandler::Range { TwistedResourceRequestHandler() { this = any(TwistedResourceSubclass cls).getARequestHandler() } Parameter getRequestParameter() { result = this.getArg(getRequestParamIndex(this.getName())) } @@ -176,7 +176,7 @@ private module Twisted { /** * Implicit response from returns of render methods. */ - private class TwistedResourceRenderMethodReturn extends HTTP::Server::HttpResponse::Range, + private class TwistedResourceRenderMethodReturn extends Http::Server::HttpResponse::Range, DataFlow::CfgNode { TwistedResourceRenderMethodReturn() { this.asCfgNode() = any(TwistedResourceRenderMethod meth).getAReturnValueFlowNode() @@ -194,7 +194,7 @@ private module Twisted { * * See https://twistedmatrix.com/documents/21.2.0/api/twisted.web.server.Request.html#write */ - class TwistedRequestWriteCall extends HTTP::Server::HttpResponse::Range, DataFlow::MethodCallNode { + class TwistedRequestWriteCall extends Http::Server::HttpResponse::Range, DataFlow::MethodCallNode { TwistedRequestWriteCall() { this.calls(Request::instance(), "write") } override DataFlow::Node getBody() { @@ -211,7 +211,7 @@ private module Twisted { * * See https://twistedmatrix.com/documents/21.2.0/api/twisted.web.http.Request.html#redirect */ - class TwistedRequestRedirectCall extends HTTP::Server::HttpRedirectResponse::Range, + class TwistedRequestRedirectCall extends Http::Server::HttpRedirectResponse::Range, DataFlow::MethodCallNode { TwistedRequestRedirectCall() { this.calls(Request::instance(), "redirect") } @@ -231,7 +231,7 @@ private module Twisted { * * See https://twistedmatrix.com/documents/21.2.0/api/twisted.web.http.Request.html#addCookie */ - class TwistedRequestAddCookieCall extends HTTP::Server::CookieWrite::Range, + class TwistedRequestAddCookieCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { TwistedRequestAddCookieCall() { this.calls(Twisted::Request::instance(), "addCookie") } @@ -247,7 +247,7 @@ private module Twisted { * * See https://twistedmatrix.com/documents/21.2.0/api/twisted.web.http.Request.html#cookies */ - class TwistedRequestCookiesAppendCall extends HTTP::Server::CookieWrite::Range, + class TwistedRequestCookiesAppendCall extends Http::Server::CookieWrite::Range, DataFlow::MethodCallNode { TwistedRequestCookiesAppendCall() { exists(DataFlow::AttrRead cookiesLookup | diff --git a/python/ql/lib/semmle/python/frameworks/Urllib3.qll b/python/ql/lib/semmle/python/frameworks/Urllib3.qll index 418a135fbfc..0214dadfc10 100644 --- a/python/ql/lib/semmle/python/frameworks/Urllib3.qll +++ b/python/ql/lib/semmle/python/frameworks/Urllib3.qll @@ -49,7 +49,7 @@ private module Urllib3 { * - https://urllib3.readthedocs.io/en/stable/reference/urllib3.request.html#urllib3.request.RequestMethods * - https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html#urllib3.HTTPConnectionPool.urlopen */ - private class RequestCall extends HTTP::Client::Request::Range, API::CallNode { + private class RequestCall extends Http::Client::Request::Range, API::CallNode { RequestCall() { this = classRef() diff --git a/python/ql/lib/semmle/python/frameworks/Yarl.qll b/python/ql/lib/semmle/python/frameworks/Yarl.qll index 5ea78c1ac8e..4a352431001 100644 --- a/python/ql/lib/semmle/python/frameworks/Yarl.qll +++ b/python/ql/lib/semmle/python/frameworks/Yarl.qll @@ -102,7 +102,7 @@ module Yarl { } /** An attribute read on a `yarl.URL` that is a `MultiDictProxy` instance. */ - class YarlUrlMultiDictProxyInstance extends Multidict::MultiDictProxy::InstanceSource { + class YarlUrlMultiDictProxyInstance extends MultiDict::MultiDictProxy::InstanceSource { YarlUrlMultiDictProxyInstance() { this.(DataFlow::AttrRead).getObject() = Yarl::Url::instance() and this.(DataFlow::AttrRead).getAttributeName() = "query" diff --git a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll index 3c7bc43ffa2..0ff32823d68 100644 --- a/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/CleartextStorageCustomizations.qll @@ -56,7 +56,7 @@ module CleartextStorage { /** The data written to a cookie on a HTTP response, considered as a flow sink. */ class CookieWriteAsSink extends Sink { CookieWriteAsSink() { - exists(HTTP::Server::CookieWrite write | + exists(Http::Server::CookieWrite write | this = write.getValueArg() or this = write.getHeaderArg() diff --git a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionCustomizations.qll index dc038ad25b0..fbab127511b 100644 --- a/python/ql/lib/semmle/python/security/dataflow/LdapInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/LdapInjectionCustomizations.qll @@ -64,14 +64,14 @@ module LdapInjection { * A logging operation, considered as a flow sink. */ class LdapExecutionAsDnSink extends DnSink { - LdapExecutionAsDnSink() { this = any(LDAP::LdapExecution ldap).getBaseDn() } + LdapExecutionAsDnSink() { this = any(Ldap::LdapExecution ldap).getBaseDn() } } /** * A logging operation, considered as a flow sink. */ class LdapExecutionAsFilterSink extends FilterSink { - LdapExecutionAsFilterSink() { this = any(LDAP::LdapExecution ldap).getFilter() } + LdapExecutionAsFilterSink() { this = any(Ldap::LdapExecution ldap).getFilter() } } /** diff --git a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll index e2a9fab37a3..ea826c3b0c5 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll @@ -48,7 +48,7 @@ module ReflectedXss { */ class ServerHttpResponseBodyAsSink extends Sink { ServerHttpResponseBodyAsSink() { - exists(HTTP::Server::HttpResponse response | + exists(Http::Server::HttpResponse response | response.getMimetype().toLowerCase() = "text/html" and this = response.getBody() ) diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryCustomizations.qll index b6df75addf0..e5a0be727cf 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryCustomizations.qll @@ -28,7 +28,7 @@ module ServerSideRequestForgery { /** * Gets the request this sink belongs to. */ - abstract HTTP::Client::Request getRequest(); + abstract Http::Client::Request getRequest(); } /** @@ -57,7 +57,7 @@ module ServerSideRequestForgery { /** The URL of an HTTP request, considered as a sink. */ class HttpRequestUrlAsSink extends Sink { - HTTP::Client::Request req; + Http::Client::Request req; HttpRequestUrlAsSink() { req.getAUrlPart() = this and @@ -74,7 +74,7 @@ module ServerSideRequestForgery { not req.getScope().getEnclosingModule().getName() in ["http.client", "httplib"] } - override HTTP::Client::Request getRequest() { result = req } + override Http::Client::Request getRequest() { result = req } } /** diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll index 2872ca5192f..36ec416cca2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll @@ -42,7 +42,7 @@ class FullServerSideRequestForgeryConfiguration extends TaintTracking::Configura /** * Holds if all URL parts of `request` is fully user controlled. */ -predicate fullyControlledRequest(HTTP::Client::Request request) { +predicate fullyControlledRequest(Http::Client::Request request) { exists(FullServerSideRequestForgeryConfiguration fullConfig | forall(DataFlow::Node urlPart | urlPart = request.getAUrlPart() | fullConfig.hasFlow(_, urlPart) diff --git a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureCustomizations.qll index 3596fa80f72..09f84327a63 100644 --- a/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/StackTraceExposureCustomizations.qll @@ -49,6 +49,6 @@ module StackTraceExposure { * The body of a HTTP response that will be returned from a server, considered as a flow sink. */ class ServerHttpResponseBodyAsSink extends Sink { - ServerHttpResponseBodyAsSink() { this = any(HTTP::Server::HttpResponse response).getBody() } + ServerHttpResponseBodyAsSink() { this = any(Http::Server::HttpResponse response).getBody() } } } diff --git a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll index 0da2f779c8a..b4843f1a8eb 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll @@ -48,7 +48,7 @@ module UrlRedirect { */ class RedirectLocationAsSink extends Sink { RedirectLocationAsSink() { - this = any(HTTP::Server::HttpRedirectResponse e).getRedirectLocation() + this = any(Http::Server::HttpRedirectResponse e).getRedirectLocation() } } diff --git a/python/ql/src/Security/CWE-295/RequestWithoutValidation.ql b/python/ql/src/Security/CWE-295/RequestWithoutValidation.ql index 8cf3bd78037..125957e59b6 100644 --- a/python/ql/src/Security/CWE-295/RequestWithoutValidation.ql +++ b/python/ql/src/Security/CWE-295/RequestWithoutValidation.ql @@ -15,7 +15,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.Concepts from - HTTP::Client::Request request, DataFlow::Node disablingNode, DataFlow::Node origin, string ending + Http::Client::Request request, DataFlow::Node disablingNode, DataFlow::Node origin, string ending where request.disablesCertificateValidation(disablingNode, origin) and // Showing the origin is only useful when it's a different node than the one disabling diff --git a/python/ql/src/Security/CWE-352/CSRFProtectionDisabled.ql b/python/ql/src/Security/CWE-352/CSRFProtectionDisabled.ql index 36a4e315ffc..75b161b9e5b 100644 --- a/python/ql/src/Security/CWE-352/CSRFProtectionDisabled.ql +++ b/python/ql/src/Security/CWE-352/CSRFProtectionDisabled.ql @@ -14,24 +14,24 @@ import python import semmle.python.Concepts -predicate relevantSetting(HTTP::Server::CsrfProtectionSetting s) { +predicate relevantSetting(Http::Server::CsrfProtectionSetting s) { // rule out test code as this is a common place to turn off CSRF protection. // We don't use normal `TestScope` to find test files, since we also want to match // a settings file such as `.../integration-tests/settings.py` not s.getLocation().getFile().getAbsolutePath().matches("%test%") } -predicate vulnerableSetting(HTTP::Server::CsrfProtectionSetting s) { +predicate vulnerableSetting(Http::Server::CsrfProtectionSetting s) { s.getVerificationSetting() = false and - not exists(HTTP::Server::CsrfLocalProtectionSetting p | p.csrfEnabled()) and + not exists(Http::Server::CsrfLocalProtectionSetting p | p.csrfEnabled()) and relevantSetting(s) } -from HTTP::Server::CsrfProtectionSetting setting +from Http::Server::CsrfProtectionSetting setting where vulnerableSetting(setting) and // We have seen examples of dummy projects with vulnerable settings alongside a main // project with a protecting settings file. We want to rule out this scenario, so we // require all non-test settings to be vulnerable. - forall(HTTP::Server::CsrfProtectionSetting s | relevantSetting(s) | vulnerableSetting(s)) + forall(Http::Server::CsrfProtectionSetting s | relevantSetting(s) | vulnerableSetting(s)) select setting, "Potential CSRF vulnerability due to forgery protection being disabled or weakened." diff --git a/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql b/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql index d7ad6465f77..37334fea87c 100644 --- a/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql +++ b/python/ql/src/Security/CWE-918/FullServerSideRequestForgery.ql @@ -16,7 +16,7 @@ import DataFlow::PathGraph from FullServerSideRequestForgeryConfiguration fullConfig, DataFlow::PathNode source, - DataFlow::PathNode sink, HTTP::Client::Request request + DataFlow::PathNode sink, Http::Client::Request request where request = sink.getNode().(Sink).getRequest() and fullConfig.hasFlowPath(source, sink) and diff --git a/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql b/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql index 6c28f921020..8f8d72c7d65 100644 --- a/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql +++ b/python/ql/src/Security/CWE-918/PartialServerSideRequestForgery.ql @@ -16,7 +16,7 @@ import DataFlow::PathGraph from PartialServerSideRequestForgeryConfiguration partialConfig, DataFlow::PathNode source, - DataFlow::PathNode sink, HTTP::Client::Request request + DataFlow::PathNode sink, Http::Client::Request request where request = sink.getNode().(Sink).getRequest() and partialConfig.hasFlowPath(source, sink) and diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 6729bed0097..16aa54ccea5 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -416,7 +416,7 @@ class CsvWriter extends DataFlow::Node { * Extend this class to refine existing API models. If you want to model new APIs, * extend `Cookie::Range` instead. */ -class Cookie extends HTTP::Server::CookieWrite instanceof Cookie::Range { +class Cookie extends Http::Server::CookieWrite instanceof Cookie::Range { /** * Holds if this cookie is secure. */ @@ -441,7 +441,7 @@ module Cookie { * Extend this class to model new APIs. If you want to refine existing API models, * extend `Cookie` instead. */ - abstract class Range extends HTTP::Server::CookieWrite::Range { + abstract class Range extends Http::Server::CookieWrite::Range { /** * Holds if this cookie is secure. */ diff --git a/python/ql/src/experimental/semmle/python/frameworks/Django.qll b/python/ql/src/experimental/semmle/python/frameworks/Django.qll index 58d1c6a4abe..d9822014466 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Django.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Django.qll @@ -15,7 +15,7 @@ private module ExperimentalPrivateDjango { private module DjangoMod { API::Node http() { result = API::moduleImport("django").getMember("http") } - module Http { + module DjangoHttp { API::Node response() { result = http().getMember("response") } API::Node request() { result = http().getMember("request") } @@ -54,7 +54,7 @@ private module ExperimentalPrivateDjango { * * Use the predicate `HttpResponse::instance()` to get references to instances of `django.http.response.HttpResponse`. */ - abstract class InstanceSource extends HTTP::Server::HttpResponse::Range, DataFlow::Node { + abstract class InstanceSource extends Http::Server::HttpResponse::Range, DataFlow::Node { } /** A direct instantiation of `django.http.response.HttpResponse`. */ @@ -156,7 +156,7 @@ private module ExperimentalPrivateDjango { */ class DjangoResponseSetCookieCall extends DataFlow::MethodCallNode, Cookie::Range { DjangoResponseSetCookieCall() { - this.calls(PrivateDjango::DjangoImpl::Http::Response::HttpResponse::instance(), + this.calls(PrivateDjango::DjangoImpl::DjangoHttp::Response::HttpResponse::instance(), "set_cookie") } diff --git a/python/ql/src/meta/alerts/RequestHandlers.ql b/python/ql/src/meta/alerts/RequestHandlers.ql index 2f79a3f1b35..3f2eae0d06b 100644 --- a/python/ql/src/meta/alerts/RequestHandlers.ql +++ b/python/ql/src/meta/alerts/RequestHandlers.ql @@ -13,7 +13,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.Concepts private import meta.MetaMetrics -from HTTP::Server::RequestHandler requestHandler, string title +from Http::Server::RequestHandler requestHandler, string title where not requestHandler.getLocation().getFile() instanceof IgnoredFile and if requestHandler.isMethod() diff --git a/python/ql/test/experimental/meta/ConceptsTest.qll b/python/ql/test/experimental/meta/ConceptsTest.qll index c792a7005b4..9690b7b1497 100644 --- a/python/ql/test/experimental/meta/ConceptsTest.qll +++ b/python/ql/test/experimental/meta/ConceptsTest.qll @@ -239,7 +239,7 @@ class HttpServerRouteSetupTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and - exists(HTTP::Server::RouteSetup setup | + exists(Http::Server::RouteSetup setup | location = setup.getLocation() and element = setup.toString() and ( @@ -261,14 +261,14 @@ class HttpServerRequestHandlerTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and ( - exists(HTTP::Server::RequestHandler handler | + exists(Http::Server::RequestHandler handler | location = handler.getLocation() and element = handler.toString() and value = "" and tag = "requestHandler" ) or - exists(HTTP::Server::RequestHandler handler, Parameter param | + exists(Http::Server::RequestHandler handler, Parameter param | param = handler.getARoutedParameter() and location = param.getLocation() and element = param.toString() and @@ -299,21 +299,21 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest { // we need to do this step since we expect subclasses could override getARelevantTag tag = getARelevantTag() and ( - exists(HTTP::Server::HttpResponse response | + exists(Http::Server::HttpResponse response | location = response.getLocation() and element = response.toString() and value = "" and tag = "HttpResponse" ) or - exists(HTTP::Server::HttpResponse response | + exists(Http::Server::HttpResponse response | location = response.getLocation() and element = response.toString() and value = prettyNodeForInlineTest(response.getBody()) and tag = "responseBody" ) or - exists(HTTP::Server::HttpResponse response | + exists(Http::Server::HttpResponse response | location = response.getLocation() and element = response.toString() and // Ensure that an expectation value such as "mimetype=text/html; charset=utf-8" is parsed as a @@ -338,14 +338,14 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and ( - exists(HTTP::Server::HttpRedirectResponse redirect | + exists(Http::Server::HttpRedirectResponse redirect | location = redirect.getLocation() and element = redirect.toString() and value = "" and tag = "HttpRedirectResponse" ) or - exists(HTTP::Server::HttpRedirectResponse redirect | + exists(Http::Server::HttpRedirectResponse redirect | location = redirect.getLocation() and element = redirect.toString() and value = prettyNodeForInlineTest(redirect.getRedirectLocation()) and @@ -364,7 +364,7 @@ class HttpServerCookieWriteTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and - exists(HTTP::Server::CookieWrite cookieWrite | + exists(Http::Server::CookieWrite cookieWrite | location = cookieWrite.getLocation() and ( element = cookieWrite.toString() and @@ -519,7 +519,7 @@ class HttpClientRequestTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and - exists(HTTP::Client::Request req, DataFlow::Node url | + exists(Http::Client::Request req, DataFlow::Node url | url = req.getAUrlPart() and location = url.getLocation() and element = url.toString() and @@ -528,7 +528,7 @@ class HttpClientRequestTest extends InlineExpectationsTest { ) or exists(location.getFile().getRelativePath()) and - exists(HTTP::Client::Request req | + exists(Http::Client::Request req | req.disablesCertificateValidation(_, _) and location = req.getLocation() and element = req.toString() and @@ -545,7 +545,7 @@ class CsrfProtectionSettingTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and - exists(HTTP::Server::CsrfProtectionSetting setting | + exists(Http::Server::CsrfProtectionSetting setting | location = setting.getLocation() and element = setting.toString() and value = setting.getVerificationSetting().toString() and @@ -561,7 +561,7 @@ class CsrfLocalProtectionSettingTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and - exists(HTTP::Server::CsrfLocalProtectionSetting p | + exists(Http::Server::CsrfLocalProtectionSetting p | location = p.getLocation() and element = p.toString() and value = p.getRequestHandler().getName().toString() and diff --git a/ruby/ql/lib/codeql/ruby/Concepts.qll b/ruby/ql/lib/codeql/ruby/Concepts.qll index 214f6734473..2098191952e 100644 --- a/ruby/ql/lib/codeql/ruby/Concepts.qll +++ b/ruby/ql/lib/codeql/ruby/Concepts.qll @@ -222,7 +222,7 @@ class HtmlEscaping extends Escaping { } /** Provides classes for modeling HTTP-related APIs. */ -module HTTP { +module Http { /** Provides classes for modeling HTTP servers. */ module Server { /** @@ -465,7 +465,7 @@ module HTTP { * Extend this class to model new APIs. If you want to refine existing API models, * extend `HttpResponse` instead. */ - abstract class Range extends HTTP::Server::HttpResponse::Range { + abstract class Range extends Http::Server::HttpResponse::Range { /** Gets the data-flow node that specifies the location of this HTTP redirect response. */ abstract DataFlow::Node getRedirectLocation(); } @@ -550,6 +550,9 @@ module HTTP { } } +/** DEPRECATED: Alias for Http */ +deprecated module HTTP = Http; + /** * A data flow node that executes an operating system command, * for instance by spawning a new process. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index d607612364f..bda04932cb1 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -46,7 +46,7 @@ class ActionControllerControllerClass extends ClassDeclaration { * A public instance method defined within an `ActionController` controller class. * This may be the target of a route handler, if such a route is defined. */ -class ActionControllerActionMethod extends Method, HTTP::Server::RequestHandler::Range { +class ActionControllerActionMethod extends Method, Http::Server::RequestHandler::Range { private ActionControllerControllerClass controllerClass; ActionControllerActionMethod() { this = controllerClass.getAMethod() and not this.isPrivate() } @@ -126,7 +126,7 @@ abstract class ParamsCall extends MethodCall { * A `RemoteFlowSource::Range` to represent accessing the * ActionController parameters available via the `params` method. */ -class ParamsSource extends HTTP::Server::RequestInputAccess::Range { +class ParamsSource extends Http::Server::RequestInputAccess::Range { ParamsSource() { this.asExpr().getExpr() instanceof ParamsCall } override string getSourceType() { result = "ActionController::Metal#params" } @@ -143,7 +143,7 @@ abstract class CookiesCall extends MethodCall { * A `RemoteFlowSource::Range` to represent accessing the * ActionController parameters available via the `cookies` method. */ -class CookiesSource extends HTTP::Server::RequestInputAccess::Range { +class CookiesSource extends Http::Server::RequestInputAccess::Range { CookiesSource() { this.asExpr().getExpr() instanceof CookiesCall } override string getSourceType() { result = "ActionController::Metal#cookies" } @@ -211,7 +211,7 @@ class RedirectToCall extends ActionControllerContextCall { /** * A call to the `redirect_to` method, as an `HttpRedirectResponse`. */ -class ActionControllerRedirectResponse extends HTTP::Server::HttpRedirectResponse::Range { +class ActionControllerRedirectResponse extends Http::Server::HttpRedirectResponse::Range { RedirectToCall redirectToCall; ActionControllerRedirectResponse() { this.asExpr().getExpr() = redirectToCall } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionView.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionView.qll index fade252ce84..b1e3e07d2d0 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionView.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionView.qll @@ -127,7 +127,7 @@ abstract class RenderCall extends MethodCall { * A call to `render`, `render_to_body` or `render_to_string`, seen as an * `HttpResponse`. */ -private class RenderCallAsHttpResponse extends DataFlow::CallNode, HTTP::Server::HttpResponse::Range { +private class RenderCallAsHttpResponse extends DataFlow::CallNode, Http::Server::HttpResponse::Range { RenderCallAsHttpResponse() { this.asExpr().getExpr() instanceof RenderCall or this.asExpr().getExpr() instanceof RenderToCall diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveResource.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveResource.qll index 901552d637f..b212f420fc6 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveResource.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveResource.qll @@ -215,7 +215,7 @@ module ActiveResource { Collection getCollection() { result = this.getReceiver() } } - private class ModelClassMethodCallAsHttpRequest extends HTTP::Client::Request::Range, + private class ModelClassMethodCallAsHttpRequest extends Http::Client::Request::Range, ModelClassMethodCall { ModelClass cls; @@ -239,7 +239,7 @@ module ActiveResource { override DataFlow::Node getResponseBody() { result = this } } - private class ModelInstanceMethodCallAsHttpRequest extends HTTP::Client::Request::Range, + private class ModelInstanceMethodCallAsHttpRequest extends Http::Client::Request::Range, ModelInstanceMethodCall { ModelClass cls; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/GraphQL.qll b/ruby/ql/lib/codeql/ruby/frameworks/GraphQL.qll index ede99069213..8815242a723 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/GraphQL.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/GraphQL.qll @@ -164,7 +164,7 @@ private class GraphqlResolvableClass extends ClassDeclaration { * end * ``` */ -class GraphqlResolveMethod extends Method, HTTP::Server::RequestHandler::Range { +class GraphqlResolveMethod extends Method, Http::Server::RequestHandler::Range { private GraphqlResolvableClass resolvableClass; GraphqlResolveMethod() { this = resolvableClass.getMethod("resolve") } @@ -208,7 +208,7 @@ class GraphqlResolveMethod extends Method, HTTP::Server::RequestHandler::Range { * end * ``` */ -class GraphqlLoadMethod extends Method, HTTP::Server::RequestHandler::Range { +class GraphqlLoadMethod extends Method, Http::Server::RequestHandler::Range { private GraphqlResolvableClass resolvableClass; GraphqlLoadMethod() { @@ -340,7 +340,7 @@ private class GraphqlFieldArgumentDefinitionMethodCall extends GraphqlSchemaObje * end * ``` */ -class GraphqlFieldResolutionMethod extends Method, HTTP::Server::RequestHandler::Range { +class GraphqlFieldResolutionMethod extends Method, Http::Server::RequestHandler::Range { private GraphqlSchemaObjectClass schemaObjectClass; GraphqlFieldResolutionMethod() { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll index c74958be716..0cca7e268dc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Excon.qll @@ -24,7 +24,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * TODO: pipelining, streaming responses * https://github.com/excon/excon/blob/master/README.md */ -class ExconHttpRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class ExconHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; API::Node connectionNode; DataFlow::Node connectionUse; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll index 548e85e7696..049998ce8f3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Faraday.qll @@ -23,7 +23,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * connection.get("/").body * ``` */ -class FaradayHttpRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class FaradayHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; API::Node connectionNode; DataFlow::Node connectionUse; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll index 0196d4c4d3c..255ff0277bc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/HttpClient.qll @@ -15,7 +15,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * HTTPClient.get_content("http://example.com") * ``` */ -class HttpClientRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class HttpClientRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; API::Node connectionNode; string method; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll index 696a008e86c..99fd9e00f18 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Httparty.qll @@ -24,7 +24,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * MyClass.new("http://example.com") * ``` */ -class HttpartyRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class HttpartyRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; HttpartyRequest() { diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll index 6848f247b3f..f12f6fa8e30 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll @@ -19,7 +19,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * response = req.get("/") * ``` */ -class NetHttpRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class NetHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { private DataFlow::CallNode request; private DataFlow::Node responseBody; private API::Node requestNode; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll index 8a519d56bf4..557c75f77ec 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/OpenURI.qll @@ -19,7 +19,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * URI.parse("http://example.com").open.read * ``` */ -class OpenUriRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class OpenUriRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; OpenUriRequest() { @@ -61,7 +61,7 @@ class OpenUriRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { * Kernel.open("http://example.com").read * ``` */ -class OpenUriKernelOpenRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class OpenUriKernelOpenRequest extends Http::Client::Request::Range, DataFlow::CallNode { OpenUriKernelOpenRequest() { this instanceof KernelMethodCall and this.getMethodName() = "open" diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll index 15ed7b49f48..6693f94585a 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/RestClient.qll @@ -17,7 +17,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * RestClient::Request.execute(url: "http://example.com").body * ``` */ -class RestClientHttpRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class RestClientHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; API::Node connectionNode; diff --git a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll index 01d10d67293..f9dcc29a266 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/http_clients/Typhoeus.qll @@ -15,7 +15,7 @@ private import codeql.ruby.dataflow.internal.DataFlowImplForHttpClientLibraries * Typhoeus.get("http://example.com").body * ``` */ -class TyphoeusHttpRequest extends HTTP::Client::Request::Range, DataFlow::CallNode { +class TyphoeusHttpRequest extends Http::Client::Request::Range, DataFlow::CallNode { API::Node requestNode; TyphoeusHttpRequest() { diff --git a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessSpecific.qll b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessSpecific.qll index 1c1ce3437b9..3cbf144d398 100644 --- a/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/security/HttpToFileAccessSpecific.qll @@ -12,10 +12,10 @@ private import HttpToFileAccessCustomizations::HttpToFileAccess /** * An access to a user-controlled HTTP request input, considered as a flow source for writing user-controlled data to files */ -private class RequestInputAccessAsSource extends Source instanceof HTTP::Server::RequestInputAccess { +private class RequestInputAccessAsSource extends Source instanceof Http::Server::RequestInputAccess { } /** A response from an outgoing HTTP request, considered as a flow source for writing user-controlled data to files. */ private class HttpResponseAsSource extends Source { - HttpResponseAsSource() { this = any(HTTP::Client::Request r).getResponseBody() } + HttpResponseAsSource() { this = any(Http::Client::Request r).getResponseBody() } } diff --git a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll index e9850445ef5..3c718655722 100644 --- a/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/InsecureDownloadCustomizations.qll @@ -135,7 +135,7 @@ module InsecureDownload { * In other words, if the URL is HTTP and the extension is in `unsafeExtension()`. */ private class HttpResponseAsSink extends Sink { - private HTTP::Client::Request req; + private Http::Client::Request req; HttpResponseAsSink() { this = req.getAUrlPart() and @@ -155,7 +155,7 @@ module InsecureDownload { /** * Gets a node for the response from `request`, type-tracked using `t`. */ - DataFlow::LocalSourceNode clientRequestResponse(TypeTracker t, HTTP::Client::Request request) { + DataFlow::LocalSourceNode clientRequestResponse(TypeTracker t, Http::Client::Request request) { t.start() and result = request.getResponseBody() or @@ -166,7 +166,7 @@ module InsecureDownload { * A url that is downloaded through an insecure connection, where the result ends up being saved to a sensitive location. */ class FileWriteSink extends Sink { - HTTP::Client::Request request; + Http::Client::Request request; FileWriteSink() { // For example, in: diff --git a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryCustomizations.qll index 840ced98fc5..30ccee6d986 100644 --- a/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/ServerSideRequestForgeryCustomizations.qll @@ -45,7 +45,7 @@ module ServerSideRequestForgery { /** The URL of an HTTP request, considered as a sink. */ class HttpRequestAsSink extends Sink { - HttpRequestAsSink() { exists(HTTP::Client::Request req | req.getAUrlPart() = this) } + HttpRequestAsSink() { exists(Http::Client::Request req | req.getAUrlPart() = this) } } /** A string interpolation with a fixed prefix, considered as a flow sanitizer. */ diff --git a/ruby/ql/lib/codeql/ruby/security/UrlRedirectCustomizations.qll b/ruby/ql/lib/codeql/ruby/security/UrlRedirectCustomizations.qll index 8fb8ada584e..998bb0ff110 100644 --- a/ruby/ql/lib/codeql/ruby/security/UrlRedirectCustomizations.qll +++ b/ruby/ql/lib/codeql/ruby/security/UrlRedirectCustomizations.qll @@ -57,7 +57,7 @@ module UrlRedirect { */ class RedirectLocationAsSink extends Sink { RedirectLocationAsSink() { - exists(HTTP::Server::HttpRedirectResponse e, MethodBase method | + exists(Http::Server::HttpRedirectResponse e, MethodBase method | this = e.getRedirectLocation() and // We only want handlers for GET requests. // Handlers for other HTTP methods are not as vulnerable to URL diff --git a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql index cf470213584..137bfc94163 100644 --- a/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql +++ b/ruby/ql/src/queries/security/cwe-295/RequestWithoutValidation.ql @@ -16,7 +16,7 @@ import codeql.ruby.Concepts import codeql.ruby.DataFlow from - HTTP::Client::Request request, DataFlow::Node disablingNode, DataFlow::Node origin, string ending + Http::Client::Request request, DataFlow::Node disablingNode, DataFlow::Node origin, string ending where request.disablesCertificateValidation(disablingNode, origin) and // Showing the origin is only useful when it's a different node than the one disabling diff --git a/ruby/ql/test/library-tests/frameworks/ActionView.ql b/ruby/ql/test/library-tests/frameworks/ActionView.ql index da9381087fd..da5f03467a1 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionView.ql +++ b/ruby/ql/test/library-tests/frameworks/ActionView.ql @@ -13,6 +13,6 @@ query predicate renderToCalls(RenderToCall c) { any() } query predicate linkToCalls(LinkToCall c) { any() } -query predicate httpResponses(HTTP::Server::HttpResponse r, DataFlow::Node body, string mimeType) { +query predicate httpResponses(Http::Server::HttpResponse r, DataFlow::Node body, string mimeType) { r.getBody() = body and r.getMimetype() = mimeType } diff --git a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql index 17f328ad2ed..0bcc883c364 100644 --- a/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql +++ b/ruby/ql/test/library-tests/frameworks/http_clients/HttpClients.ql @@ -2,7 +2,7 @@ import codeql.ruby.Concepts import codeql.ruby.DataFlow query predicate httpRequests( - HTTP::Client::Request r, string framework, DataFlow::Node urlPart, DataFlow::Node responseBody + Http::Client::Request r, string framework, DataFlow::Node urlPart, DataFlow::Node responseBody ) { r.getFramework() = framework and r.getAUrlPart() = urlPart and diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql index d3ce257b753..2cc66dd02b6 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql @@ -42,8 +42,8 @@ class NWConnectionSend extends Transmitted { * An `Expr` that is used to form a `URL`. Such expressions are very likely to * be transmitted over a network, because that's what URLs are for. */ -class URL extends Transmitted { - URL() { +class Url extends Transmitted { + Url() { // `string` arg in `URL.init` is a sink // (we assume here that the URL goes on to be used in a network operation) exists(ClassDecl c, AbstractFunctionDecl f, CallExpr call | From c739bbb0515f4346074f9323fd76e57cd364d630 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 9 Sep 2022 11:00:02 +0200 Subject: [PATCH 074/203] Swift: bake in `isProbablySafe` in `SensitiveExpr` Also restructured the code a bit in the weak hashing query. --- .../codeql/swift/security/SensitiveExprs.qll | 39 +++++++++---------- .../CWE-311/CleartextStorageDatabase.ql | 7 +--- .../Security/CWE-311/CleartextTransmission.ql | 7 +--- .../CWE-328/WeakSensitiveDataHashing.ql | 30 ++++++++------ .../Security/CWE-311/SensitiveExprs.expected | 11 ------ .../Security/CWE-311/SensitiveExprs.ql | 2 - .../CWE-328/WeakSensitiveDataHashing.expected | 24 ++++++------ 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll index 1dbcada4127..3019c919219 100644 --- a/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll +++ b/swift/ql/lib/codeql/swift/security/SensitiveExprs.qll @@ -121,20 +121,24 @@ class SensitiveExpr extends Expr { SensitiveDataType sensitiveType; SensitiveExpr() { - // variable reference - this.(DeclRefExpr).getDecl().(SensitiveVarDecl).hasInfo(label, sensitiveType) - or - // member variable reference - this.(MemberRefExpr).getMember().(SensitiveVarDecl).hasInfo(label, sensitiveType) - or - // function call - this.(ApplyExpr).getStaticTarget().(SensitiveFunctionDecl).hasInfo(label, sensitiveType) - or - // sensitive argument - exists(SensitiveArgument a | - a.hasInfo(label, sensitiveType) and - a.getExpr() = this - ) + ( + // variable reference + this.(DeclRefExpr).getDecl().(SensitiveVarDecl).hasInfo(label, sensitiveType) + or + // member variable reference + this.(MemberRefExpr).getMember().(SensitiveVarDecl).hasInfo(label, sensitiveType) + or + // function call + this.(ApplyExpr).getStaticTarget().(SensitiveFunctionDecl).hasInfo(label, sensitiveType) + or + // sensitive argument + exists(SensitiveArgument a | + a.hasInfo(label, sensitiveType) and + a.getExpr() = this + ) + ) and + // do not mark as sensitive it if it is probably safe + not label.toLowerCase().regexpMatch(regexpProbablySafe()) } /** @@ -146,11 +150,4 @@ class SensitiveExpr extends Expr { * Gets the type of sensitive expression this is. */ SensitiveDataType getSensitiveType() { result = sensitiveType } - - /** - * Holds if this sensitive expression might be safe because it contains - * hashed or encrypted data, or is only a reference to data that is stored - * elsewhere. - */ - predicate isProbablySafe() { label.toLowerCase().regexpMatch(regexpProbablySafe()) } } diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql index 6ee90e87a84..2ef86b1609b 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql @@ -70,12 +70,7 @@ class RealmStore extends Stored { class CleartextStorageConfig extends TaintTracking::Configuration { CleartextStorageConfig() { this = "CleartextStorageConfig" } - override predicate isSource(DataFlow::Node node) { - exists(SensitiveExpr e | - node.asExpr() = e and - not e.isProbablySafe() - ) - } + override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof Stored } diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql index bbb71bb2587..21a14454504 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextTransmission.ql @@ -63,12 +63,7 @@ class URL extends Transmitted { class CleartextTransmissionConfig extends TaintTracking::Configuration { CleartextTransmissionConfig() { this = "CleartextTransmissionConfig" } - override predicate isSource(DataFlow::Node node) { - exists(SensitiveExpr e | - node.asExpr() = e and - not e.isProbablySafe() - ) - } + override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SensitiveExpr } override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof Transmitted } diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql index 5eb711434fa..b697a9a01dd 100755 --- a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql @@ -20,21 +20,24 @@ import DataFlow::PathGraph class WeakHashingConfig extends TaintTracking::Configuration { WeakHashingConfig() { this = "WeakHashingConfig" } - override predicate isSource(DataFlow::Node node) { - exists(SensitiveExpr e | - node.asExpr() = e and - not e.isProbablySafe() - ) - } + override predicate isSource(DataFlow::Node node) { node instanceof WeakHashingConfig::Source } override predicate isSink(DataFlow::Node node) { node instanceof WeakHashingConfig::Sink } } module WeakHashingConfig { - class Sink extends DataFlow::Node { + class Source extends DataFlow::Node { + Source() { this.asExpr() instanceof SensitiveExpr } + } + + abstract class Sink extends DataFlow::Node { + abstract string getAlgorithm(); + } + + class CryptoHash extends Sink { string algorithm; - Sink() { + CryptoHash() { exists(ApplyExpr call, FuncDecl func | call.getAnArgument().getExpr() = this.asExpr() and call.getStaticTarget() = func and @@ -44,14 +47,17 @@ module WeakHashingConfig { ) } - string getAlgorithm() { result = algorithm } + override string getAlgorithm() { result = algorithm } } } -from WeakHashingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, string algorithm +from + WeakHashingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, string algorithm, + SensitiveExpr expr where config.hasFlowPath(source, sink) and - algorithm = sink.getNode().(WeakHashingConfig::Sink).getAlgorithm() + algorithm = sink.getNode().(WeakHashingConfig::Sink).getAlgorithm() and + expr = source.getNode().asExpr() select sink.getNode(), source, sink, "Insecure hashing algorithm (" + algorithm + ") depends on $@.", source.getNode(), - "sensitive data" + "sensitive data (" + expr.getSensitiveType() + " " + expr.getLabel() + ")" diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected index a46d45c0821..3b5f0b58f26 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -1,13 +1,8 @@ | testCoreData.swift:48:15:48:15 | password | label:password, type:credential | -| testCoreData.swift:49:15:49:15 | password_hash | isProbablySafe, label:password_hash, type:credential | | testCoreData.swift:51:24:51:24 | password | label:password, type:credential | -| testCoreData.swift:52:24:52:24 | password_hash | isProbablySafe, label:password_hash, type:credential | | testCoreData.swift:58:15:58:15 | password | label:password, type:credential | -| testCoreData.swift:59:15:59:15 | password_file | isProbablySafe, label:password_file, type:credential | | testCoreData.swift:61:25:61:25 | password | label:password, type:credential | -| testCoreData.swift:62:25:62:25 | password_file | isProbablySafe, label:password_file, type:credential | | testCoreData.swift:64:16:64:16 | password | label:password, type:credential | -| testCoreData.swift:65:16:65:16 | password_file | isProbablySafe, label:password_file, type:credential | | testCoreData.swift:77:2:77:25 | call to doSomething(password:) | label:doSomething(password:), type:credential | | testCoreData.swift:77:24:77:24 | x | label:password, type:credential | | testCoreData.swift:80:10:80:22 | call to getPassword() | label:getPassword(), type:credential | @@ -16,16 +11,10 @@ | testCoreData.swift:92:10:92:10 | passwd | label:passwd, type:credential | | testCoreData.swift:93:10:93:10 | passwd | label:passwd, type:credential | | testRealm.swift:34:11:34:11 | myPassword | label:myPassword, type:credential | -| testRealm.swift:38:11:38:11 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential | | testRealm.swift:42:11:42:11 | myPassword | label:myPassword, type:credential | -| testRealm.swift:46:11:46:11 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential | | testRealm.swift:52:12:52:12 | myPassword | label:myPassword, type:credential | -| testRealm.swift:55:12:55:12 | myHashedPassword | isProbablySafe, label:myHashedPassword, type:credential | | testSend.swift:29:19:29:19 | passwordPlain | label:passwordPlain, type:credential | -| testSend.swift:30:19:30:19 | passwordHash | isProbablySafe, label:passwordHash, type:credential | | testSend.swift:33:19:33:19 | passwordPlain | label:passwordPlain, type:credential | -| testSend.swift:34:19:34:19 | passwordHash | isProbablySafe, label:passwordHash, type:credential | | testURL.swift:13:54:13:54 | passwd | label:passwd, type:credential | -| testURL.swift:14:54:14:54 | encrypted_passwd | isProbablySafe, label:encrypted_passwd, type:credential | | testURL.swift:16:55:16:55 | credit_card_no | label:credit_card_no, type:private information | | testURL.swift:20:22:20:22 | passwd | label:passwd, type:credential | diff --git a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.ql b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.ql index 5caa85c948f..3694468b130 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.ql +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.ql @@ -5,8 +5,6 @@ string describe(SensitiveExpr e) { result = "label:" + e.getLabel() or result = "type:" + e.getSensitiveType().toString() - or - e.isProbablySafe() and result = "isProbablySafe" } from SensitiveExpr e diff --git a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected index 0422d561ca8..81d4f184569 100644 --- a/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected +++ b/swift/ql/test/query-tests/Security/CWE-328/WeakSensitiveDataHashing.expected @@ -14,15 +14,15 @@ nodes | testCrypto.swift:67:32:67:32 | credit_card_no | semmle.label | credit_card_no | subpaths #select -| testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:25:47:25:47 | passwd | sensitive data | -| testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:28:43:28:43 | credit_card_no | sensitive data | -| testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:32:48:32:48 | passwd | sensitive data | -| testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:35:44:35:44 | credit_card_no | sensitive data | -| testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:40:23:40:23 | passwd | sensitive data | -| testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:43:23:43:23 | credit_card_no | sensitive data | -| testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:48:23:48:23 | passwd | sensitive data | -| testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:51:23:51:23 | credit_card_no | sensitive data | -| testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:56:32:56:32 | passwd | sensitive data | -| testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:59:32:59:32 | credit_card_no | sensitive data | -| testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:64:32:64:32 | passwd | sensitive data | -| testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:67:32:67:32 | credit_card_no | sensitive data | +| testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | testCrypto.swift:25:47:25:47 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:25:47:25:47 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | testCrypto.swift:28:43:28:43 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:28:43:28:43 | credit_card_no | sensitive data (private information credit_card_no) | +| testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | testCrypto.swift:32:48:32:48 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:32:48:32:48 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | testCrypto.swift:35:44:35:44 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:35:44:35:44 | credit_card_no | sensitive data (private information credit_card_no) | +| testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | testCrypto.swift:40:23:40:23 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:40:23:40:23 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | testCrypto.swift:43:23:43:23 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:43:23:43:23 | credit_card_no | sensitive data (private information credit_card_no) | +| testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | testCrypto.swift:48:23:48:23 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:48:23:48:23 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | testCrypto.swift:51:23:51:23 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:51:23:51:23 | credit_card_no | sensitive data (private information credit_card_no) | +| testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | testCrypto.swift:56:32:56:32 | passwd | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:56:32:56:32 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | testCrypto.swift:59:32:59:32 | credit_card_no | Insecure hashing algorithm (MD5) depends on $@. | testCrypto.swift:59:32:59:32 | credit_card_no | sensitive data (private information credit_card_no) | +| testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | testCrypto.swift:64:32:64:32 | passwd | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:64:32:64:32 | passwd | sensitive data (credential passwd) | +| testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | testCrypto.swift:67:32:67:32 | credit_card_no | Insecure hashing algorithm (SHA1) depends on $@. | testCrypto.swift:67:32:67:32 | credit_card_no | sensitive data (private information credit_card_no) | From fccf07c5bc44e2a67561c051e0bd6d51451be155 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 9 Sep 2022 11:01:24 +0200 Subject: [PATCH 075/203] Swift: tweak qhelp file for WeakSensitiveDataHashing --- .../queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp index 0fc07271f8e..a3a161298de 100755 --- a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.qhelp @@ -49,7 +49,8 @@