Code Monkey home page Code Monkey logo

php-rule-parser's Introduction

PHP Rule Engine

Latest Stable Version Build status Code Quality StyleCI

Total Downloads Latest Stable Version

You're looking at a standalone PHP library to parse and evaluate text based rules with a Javascript-like syntax. This project was born out of the necessity to evaluate hundreds of rules that were originally written and evaluated in JavaScript, and now needed to be evaluated on the server-side, using PHP.

This library has initially been used to change and configure the behavior of certain "Workflows" (without changing actual code) in an intranet application, but it may serve a purpose elsewhere.

Find me on Twitter: @nicoSWD

(If you're using PHP 5, you might want to take a look at version 0.4.0)

SensioLabsInsight

Install

Via Composer

$ composer require nicoswd/php-rule-parser

Bundles

This library works best with one of these bundles below, but they're not required

Bundle Framework Packagist
nicoSWD/rule-engine-bundle Symfony Latest Stable Version

Usage Examples

Test if a value is in a given array

$variables = ['foo' => 6];

$rule = new Rule('foo in [4, 6, 7]', $variables);
var_dump($rule->isTrue()); // bool(true)

Simple array manipulation

$rule = new Rule('[1, 4, 3].join(".") === "1.4.3"');
var_dump($rule->isTrue()); // bool(true)

Test if a value is between a given range

$variables = ['threshold' => 80];

$rule = new Rule('threshold >= 50 && threshold <= 100', $variables);
var_dump($rule->isTrue()); // bool(true)

Call methods on objects from within rules

class User
{
    // ...

    public function points(): int
    {
        return 1337;    
    }
}

$variables = [
    'user' => new User(),
];

$rule = new Rule('user.points() > 300', $variables);
var_dump($rule->isTrue()); // bool(true)

For security reasons, PHP's magic methods like __construct and __destruct cannot be called from within rules. However, __call will be invoked automatically if available, unless the called method is defined.

Built-in Methods

Name Example
charAt "foo".charAt(2) === "o"
concat "foo".concat("bar", "baz") === "foobarbaz"
endsWith "foo".endsWith("oo") === true
startsWith "foo".startsWith("fo") === true
indexOf "foo".indexOf("oo") === 1
join ["foo", "bar"].join(",") === "foo,bar"
replace "foo".replace("oo", "aa") === "faa"
split "foo-bar".split("-") === ["foo", "bar"]
substr "foo".substr(1) === "oo"
test "foo".test(/oo$/) === true
toLowerCase "FOO".toLowerCase() === "foo"
toUpperCase "foo".toUpperCase() === "FOO"

Built-in Functions

Name Example
parseInt parseInt("22aa") === 22
parseFloat parseFloat("3.1") === 3.1

Supported Operators

Type Description Operator
Comparison greater than >
Comparison greater than or equal to >=
Comparison less than <
Comparison less or equal to <=
Comparison equal to ==
Comparison not equal to !=
Comparison identical ===
Comparison not identical !==
Containment contains in
Containment does not contain not in
Logical and &&
Logical or ||

Error Handling

Both, $rule->isTrue() and $rule->isFalse() will throw an exception if the syntax is invalid. These calls can either be placed inside a try / catch block, or it can be checked prior using $rule->isValid().

$ruleStr = '
    (2 == 2) && (
        1 < 3 && 3 == 2 ( // Missing and/or before parentheses
            1 == 1
        )
    )';

$rule = new Rule($ruleStr);

try {
    $rule->isTrue();
} catch (\Exception $e) {
    echo $e->getMessage();
}

Or alternatively:

if (!$rule->isValid()) {
    echo $rule->getError();
}

Both will output: Unexpected token "(" at position 25 on line 3

Syntax Highlighting

A custom syntax highlighter is also provided.

use nicoSWD\Rule;

$ruleStr = '
    // This is true
    2 < 3 && (
        // This is false
        foo in [4, 6, 7] ||
        // True
        [1, 4, 3].join("") === "143"
    ) && (
        // True
        "foo|bar|baz".split("|" /* uh oh */) === ["foo", /* what */ "bar", "baz"] &&
        // True
        bar > 6
    )';

$highlighter = new Rule\Highlighter\Highlighter(new Rule\Tokenizer());

// Optional custom styles
$highlighter->setStyle(
    Rule\Constants::GROUP_VARIABLE,
    'color: #007694; font-weight: 900;'
);

echo $highlighter->highlightString($ruleStr);

Outputs:

Syntax preview

Notes

  • Parentheses can be nested, and will be evaluated from right to left.
  • Only value/variable comparison expressions with optional logical ANDs/ORs, are supported.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Testing

$ composer test

Contributing

Pull requests are very welcome! If they include tests, even better. This project follows PSR-2 coding standards, please make sure your pull requests do too.

To Do

  • Support for object properties (foo.length)
  • Support for returning actual results, other than true or false
  • Support for array / string dereferencing: "foo"[1]
  • Don't force boolean comparison for tokens that are already booleans. my_func() && 2 > 1 should work
  • Change regex and implementation for method calls. ".split(" should not be the token
  • Add / implement missing methods
  • Add "typeof" construct
  • Do math (?)
  • Allow string concatenating with "+"
  • Invalid regex modifiers should not result in an unknown token
  • Duplicate regex modifiers should throw an error
  • Add support for function calls
  • Support for regular expressions
  • Fix build on PHP 7 / Nightly
  • Allow variables in arrays
  • Verify function and method name spelling (.tOuPpErCAse() is currently valid)
  • ...

License

License

php-rule-parser's People

Contributors

altesack avatar mend-bolt-for-github[bot] avatar nicoswd avatar scrutinizer-auto-fixer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-rule-parser's Issues

CVE-2020-11022 (Medium) detected in phpunit/php-code-coverage-7.0.10, jquery-3.4.1.min.js

CVE-2020-11022 - Medium Severity Vulnerability

Vulnerable Libraries - phpunit/php-code-coverage-7.0.10, jquery-3.4.1.min.js

phpunit/php-code-coverage-7.0.10

Library that provides collection, processing, and rendering functionality for PHP code coverage information.

Library home page: https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf

Dependency Hierarchy:

  • phpunit/phpunit-8.5.8 (Root Library)
    • phpunit/php-code-coverage-7.0.10 (Vulnerable Library)
jquery-3.4.1.min.js

JavaScript library for DOM operations

Library home page: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js

Dependency Hierarchy:

  • jquery-3.4.1.min.js (Vulnerable Library)

Found in HEAD commit: 23bb2982bb26d1c85d175d7aac61babd770d0964

Vulnerability Details

In jQuery versions greater than or equal to 1.2 and before 3.5.0, passing HTML from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

Publish Date: 2020-04-29

URL: CVE-2020-11022

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/

Release Date: 2020-04-29

Fix Resolution: jQuery - 3.5.0


Step up your Open Source Security Game with WhiteSource here

CVE-2018-14040 (Medium) detected in bootstrap-3.3.7-3.3.13.min.js

CVE-2018-14040 - Medium Severity Vulnerability

Vulnerable Library - bootstrap-3.3.7-3.3.13.min.js

Google-styled theme for Bootstrap.

Library home page: https://cdnjs.cloudflare.com/ajax/libs/todc-bootstrap/3.3.7-3.3.13/js/bootstrap.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js

Dependency Hierarchy:

  • bootstrap-3.3.7-3.3.13.min.js (Vulnerable Library)

Found in HEAD commit: bb0ee0725f2362333a5d83f12ae078c759af4cfb

Vulnerability Details

In Bootstrap before 4.1.2, XSS is possible in the collapse data-parent attribute.

Publish Date: 2018-07-13

URL: CVE-2018-14040

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: twbs/bootstrap#26630

Release Date: 2018-07-13

Fix Resolution: org.webjars.npm:bootstrap:4.1.2.org.webjars:bootstrap:4.1.2


Step up your Open Source Security Game with WhiteSource here

Cannot use variables where one of the keys has a dash in it.

See the following test (which fails currently) for an example. Not sure if it's work-as-design or not.

Btw, awesome project!

public function testArrayWithDashInKeyDoesParseCorrectly()
    {
        $this->assertTrue($this->evaluate(
            'foo-bar === [
                "foo", // This is foo
                "bar"  // And this is bar
            ]',
            ['foo-bar' => ['foo', 'bar']]
        ));
    }

CVE-2019-11358 (Medium) detected in jquery-3.1.1.min.js

CVE-2019-11358 - Medium Severity Vulnerability

Vulnerable Library - jquery-3.1.1.min.js

JavaScript library for DOM operations

Library home page: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js

Dependency Hierarchy:

  • jquery-3.1.1.min.js (Vulnerable Library)

Found in HEAD commit: bb0ee0725f2362333a5d83f12ae078c759af4cfb

Vulnerability Details

jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable proto property, it could extend the native Object.prototype.

Publish Date: 2019-04-20

URL: CVE-2019-11358

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Change files

Origin: jquery/jquery@753d591

Release Date: 2019-03-25

Fix Resolution: Replace or update the following files: core.js, core.js


Step up your Open Source Security Game with WhiteSource here

CVE-2019-8331 (Medium) detected in bootstrap-4.1.3.min.js

CVE-2019-8331 - Medium Severity Vulnerability

Vulnerable Library - bootstrap-4.1.3.min.js

The most popular front-end framework for developing responsive, mobile first projects on the web.

Library home page: https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js

Dependency Hierarchy:

  • bootstrap-4.1.3.min.js (Vulnerable Library)

Found in HEAD commit: 55bcb305d719a98ccd59aa3cc5013a5b82b9f27a

Vulnerability Details

In Bootstrap before 3.4.1 and 4.3.x before 4.3.1, XSS is possible in the tooltip or popover data-template attribute.

Publish Date: 2019-02-20

URL: CVE-2019-8331

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: twbs/bootstrap#28236

Release Date: 2019-02-20

Fix Resolution: bootstrap - 3.4.1,4.3.1;bootstrap-sass - 3.4.1,4.3.1


Step up your Open Source Security Game with WhiteSource here

ReadMe Mis-type?

Hi There,

Just getting to know this package and had a tough time getting up and running with it, PHP throwing exceptions about now being able to find the class itself. Mucked around with composer to no avail, then took a look under the hood and saw that the namespace of this library should be nicoSWD\Rules\.... note the Rules plural, however it's got in the example Read Me, use nicoSWD\Rule\Rule - Might just want to double check the docs!

Cheers :)

CVE-2020-11023 (Medium) detected in phpunit/php-code-coverage-7.0.10, jquery-3.4.1.min.js

CVE-2020-11023 - Medium Severity Vulnerability

Vulnerable Libraries - phpunit/php-code-coverage-7.0.10, jquery-3.4.1.min.js

phpunit/php-code-coverage-7.0.10

Library that provides collection, processing, and rendering functionality for PHP code coverage information.

Library home page: https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf

Dependency Hierarchy:

  • phpunit/phpunit-8.5.8 (Root Library)
    • phpunit/php-code-coverage-7.0.10 (Vulnerable Library)
jquery-3.4.1.min.js

JavaScript library for DOM operations

Library home page: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js

Dependency Hierarchy:

  • jquery-3.4.1.min.js (Vulnerable Library)

Found in HEAD commit: 23bb2982bb26d1c85d175d7aac61babd770d0964

Vulnerability Details

In jQuery versions greater than or equal to 1.0.3 and before 3.5.0, passing HTML containing elements from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

Publish Date: 2020-04-29

URL: CVE-2020-11023

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11023

Release Date: 2020-04-29

Fix Resolution: jquery - 3.5.0


Step up your Open Source Security Game with WhiteSource here

CVE-2018-14042 (Medium) detected in bootstrap-3.3.7-3.3.13.min.js

CVE-2018-14042 - Medium Severity Vulnerability

Vulnerable Library - bootstrap-3.3.7-3.3.13.min.js

Google-styled theme for Bootstrap.

Library home page: https://cdnjs.cloudflare.com/ajax/libs/todc-bootstrap/3.3.7-3.3.13/js/bootstrap.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js

Dependency Hierarchy:

  • bootstrap-3.3.7-3.3.13.min.js (Vulnerable Library)

Found in HEAD commit: bb0ee0725f2362333a5d83f12ae078c759af4cfb

Vulnerability Details

In Bootstrap before 4.1.2, XSS is possible in the data-container property of tooltip.

Publish Date: 2018-07-13

URL: CVE-2018-14042

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: twbs/bootstrap#26630

Release Date: 2018-07-13

Fix Resolution: org.webjars.npm:bootstrap:4.1.2.org.webjars:bootstrap:4.1.2


Step up your Open Source Security Game with WhiteSource here

CVE-2018-20677 (Medium) detected in bootstrap-3.3.7-3.3.13.min.js

CVE-2018-20677 - Medium Severity Vulnerability

Vulnerable Library - bootstrap-3.3.7-3.3.13.min.js

Google-styled theme for Bootstrap.

Library home page: https://cdnjs.cloudflare.com/ajax/libs/todc-bootstrap/3.3.7-3.3.13/js/bootstrap.min.js

Path to vulnerable library: /php-rule-parser/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js

Dependency Hierarchy:

  • bootstrap-3.3.7-3.3.13.min.js (Vulnerable Library)

Found in HEAD commit: bb0ee0725f2362333a5d83f12ae078c759af4cfb

Vulnerability Details

In Bootstrap before 3.4.0, XSS is possible in the affix configuration target property.

Publish Date: 2019-01-09

URL: CVE-2018-20677

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-20677

Release Date: 2019-01-09

Fix Resolution: Bootstrap - v3.4.0;NorDroN.AngularTemplate - 0.1.6;Dynamic.NET.Express.ProjectTemplates - 0.8.0;dotnetng.template - 1.0.0.4;ZNxtApp.Core.Module.Theme - 1.0.9-Beta;JMeter - 5.0.0


Step up your Open Source Security Game with WhiteSource here

Multiple tests cause parser error

If a function contains more than one instance of the test function, it complains of a parse error

// example bad rule:
/a/.test('a') && /x/.test('x')

Error: "preg_match(): Unknown modifier '.'"
File: nicoswd/php-rule-parser/src/Grammar/JavaScript/Methods/Test.php
Line: 46
Function: preg_match
PHP Version: 7.4.3 (ubuntu)

I have tried reordering them, changing contents of test, and removing "i" modifier. It simply doesn't like it when there are two.

Related side issue: documentation provides use as "foo".test(/oo/i) but actual usage requires the reverse:/oo/i.test("foo")

Thanks for providing this helpful utility.

Fatal error with Bool variables and ||

There is a PHP fatal error when === false/true isn't added after "boolean" functions.

Version: 0.7.1
PHP version: 8.1
How to replicate:

$engine_rule = new Rule('VAR.startsWith("xXx") || VAR.startsWith("xXx") === false', ['VAR' => 'blablabla']);
$engine_rule->isTrue();

Expected result: Validation error like "invalid token || blablabla" until === false/true is added.
Actual result: nicoSWD\Rule\Expression\ExpressionFactory::createFromOperator(): Argument #1 ($operator) must be of type nicoSWD\Rule\TokenStream\Token\BaseToken, null given, called in libs\php-rule-parser\src\Parser\Parser.php on line 61

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.