{"id":21932310,"url":"https://github.com/rindphi/isla","last_synced_at":"2025-06-17T05:37:23.896Z","repository":{"id":37944116,"uuid":"428626626","full_name":"rindPHI/isla","owner":"rindPHI","description":"The ISLa (Input Specification Language) language \u0026 solver.","archived":false,"fork":false,"pushed_at":"2024-07-01T08:24:01.000Z","size":28670,"stargazers_count":61,"open_issues_count":21,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-13T09:14:39.192Z","etag":null,"topics":["constraints","fuzzing","grammars","python","smt","strings"],"latest_commit_sha":null,"homepage":"https://isla.readthedocs.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rindPHI.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-16T11:22:35.000Z","updated_at":"2024-11-11T18:19:23.000Z","dependencies_parsed_at":"2024-06-20T21:57:46.444Z","dependency_job_id":"2c6cad30-fae1-4cbf-98a6-3cb82f02dd66","html_url":"https://github.com/rindPHI/isla","commit_stats":{"total_commits":1144,"total_committers":2,"mean_commits":572.0,"dds":0.002622377622377603,"last_synced_commit":"8cf1eb0bad9395d013f8a99512e19f07c624373f"},"previous_names":[],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rindPHI%2Fisla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rindPHI%2Fisla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rindPHI%2Fisla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rindPHI%2Fisla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rindPHI","download_url":"https://codeload.github.com/rindPHI/isla/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232187404,"owners_count":18485386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["constraints","fuzzing","grammars","python","smt","strings"],"created_at":"2024-11-28T23:18:02.973Z","updated_at":"2025-01-02T11:07:05.889Z","avatar_url":"https://github.com/rindPHI.png","language":"Python","readme":"ISLa: Input Specification Language\n==================================\n\n[![Python](https://img.shields.io/pypi/pyversions/isla-solver.svg)](https://pypi.python.org/pypi/isla-solver/)\n[![Version](http://img.shields.io/pypi/v/isla-solver.svg)](https://pypi.python.org/pypi/isla-solver)\n[![BuildStatus](https://img.shields.io/github/actions/workflow/status/rindPHI/isla/test-isla.yml?branch=main)](https://img.shields.io/github/actions/workflow/status/rindPHI/isla/test-isla.yml?branch=main)\n[![Coverage Status](https://coveralls.io/repos/github/rindPHI/isla/badge.svg?branch=main)](https://coveralls.io/github/rindPHI/isla?branch=main)\n[![Dependencies](https://img.shields.io/librariesio/release/github/rindphi/isla)](https://libraries.io/github/rindPHI/isla)\n[![DOI](https://zenodo.org/badge/428626626.svg)](https://zenodo.org/badge/latestdoi/428626626)\n[![Documentation Status](https://readthedocs.org/projects/isla/badge/?version=latest)](https://isla.readthedocs.io/en/latest/?badge=latest)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n\u003cimg src=\"isla_logo_bright_transparent.png\" alt=\"ISLa Logo\" style=\"margin-left: auto; margin-right: auto; display: block; width: 400px;\"/\u003e \n\n**_Inputs on Demand!_**\n\nISLa is a *grammar-aware string constraint solver* with its own specification language.\nWith ISLa, it is possible to specify *input constraints* like \"a variable has to be\ndefined before it is used,\" \"the `file name' block must be 100 bytes long,\" or \"the\nnumber of columns in all CSV rows must be identical.\"\n\nBuilding on modern constraint solvers, ISLa provides you with a unique\nflexibility to specify\u0026mdash;and generate\u0026mdash;the system inputs you need. ISLa can be\nused for *precise fuzzing:* Keep adding input specifications until you are satisfied\nwith the number of inputs passing the tested system's parser. Furthermore, you can write\nISLa specifications to carve out specific inputs for testing a *particular program\nfunctionality*.\n\n## Example\n\nOur running example is a simple \"assignment language\" consisting of strings such as\n`x := 1 ; y := x`. As a first step towards using ISLa, we formalize this language as\na context-free grammar in [BNF](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form):\n\n```bnf\n\u003cstart\u003e ::= \u003cstmt\u003e \n\u003cstmt\u003e  ::= \u003cassgn\u003e | \u003cassgn\u003e \" ; \" \u003cstmt\u003e \n\u003cassgn\u003e ::= \u003cvar\u003e \" := \" \u003crhs\u003e \n\u003crhs\u003e   ::= \u003cvar\u003e | \u003cdigit\u003e \n\u003cvar\u003e   ::= \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\" | \"g\" | \"h\" | \"i\" | \"j\" | \n            \"k\" | \"l\" | \"m\" | \"n\" | \"o\" | \"p\" | \"q\" | \"r\" | \"s\" | \"t\" |\n            \"u\" | \"v\" | \"w\" | \"x\" | \"y\" | \"z\" \n\u003cdigit\u003e ::= \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\"\n```\n\nAfter saving this grammar to a file, say, `assgn.bnf`, we can already generate inputs\nfrom the assignment grammar using the ISLa command line interface:\n\n```bash\n\u003e isla solve assgn.bnf\ns := t\n```\n\nThe following command creates 10 assignments:\n\n```bash\n\u003e isla solve -n 10 assgn.bnf\na := 6 ; j := x\nq := u\ne := h ; o := l ; g := w\ns := i\nk := v ; d := m ; f := 1\nn := y ; t := 5\nz := 3 ; p := 7 ; b := 0\nc := 2 ; r := 4\nq := 8 ; l := 9\nu := 0\n```\n\nThe setting `-n -1` specifies that we want to generate an infinite number of inputs.\nSince we did not choose an ISLa constraint, we additionally have to choose a value\nfor the `-f` flag. This setting determines the number of times an input element that\nis not subject to any constraint (which is the case here) should be expanded. The final\nline \"UNSAT\" means that after these 10 solutions, no further solution could be found.\nIf \"UNSAT\" is the *first* line output by the solver, it is likely that the given\nconstraint is *unsatisfiable*, i.e., there exists no solution of this constraint with\nrespect to the current grammar.\n\nWith ISLa, we can restrict the assignment language on-demand. For example, the ISLa\nconstraint `\u003cvar\u003e = \"a\"` results in assignment sequences only containing \"a\" variables:\n\n```bash\n\u003e isla solve /tmp/assgn.bnf -n 10 -f 1 --constraint '\u003cvar\u003e = \"a\"' \na := 5 ; a := a ; a := 7\na := 6\na := a\na := 0 ; a := a ; a := a\na := a ; a := 1 ; a := 4\na := a ; a := 3 ; a := a\na := 8 ; a := 2\na := 9 ; a := a\na := a ; a := 9\na := a ; a := a\n```\n\n\u003e :bulb: The setting `-f 1` restricts the number of times that ILSa randomly\n\u003e instantiates unconstrained input elements to one time. Here, this affects the\n\u003e `\u003cdigit\u003e` nonterminals: Without `-f 1`, we would see 10 different variants of the\n\u003e first input with variying numbers in the first and third assignment.\n\nOr do we prefer assignments where all digits can be divided by 2 without remainder? No\nproblem with ISLa:\n\n```bash\n\u003e isla solve assgn.bnf -n 10 -f 1 -s 2 --constraint \"str.to.int(\u003cdigit\u003e) mod 2 = 0\"\ni := a ; x := 0 ; u := s\np := l ; m := 8 ; b := y\nk := c ; t := d ; r := q\nj := z\nh := 0\ne := 4\ng := n ; v := f ; w := 4\no := o ; j := a ; c := 0\nt := r ; k := 0 ; e := 0\nk := t ; f := 8 ; e := 8\n```\n\n\u003e :bulb: The `-s` flag specifies how many results for a single query should be obtained\n\u003e from the SMT solver Z3. We limited this number to 2 (the default is 10\u0026mdash;the same\n\u003e default value is used for the `-f` flag) to obtain a wider diversity of inputs within\n\u003e the first 10 results.\n\nThe constraints above talk over *all* `\u003cvar\u003e` and `\u003cdigit\u003e` grammar nonterminals in\nany derivation tree derived from the assignment language grammar. In addition to such\nsimple constraints, ISLa allows to explicitly *quantify* over grammar elements using\nthe `forall` and `exists` keywords.\n\nAssume that an interpreter for our assignment language rejects inputs where a variable\nis accessed that has not been previously assigned a value. This \"definition-use\"\nproperty, which is a *semantic input property* of the language, is expressed as follows:\n\n```\nforall \u003cassgn\u003e assgn_1:\n  exists \u003cassgn\u003e assgn_2: (\n    before(assgn_2, assgn_1) and \n    assgn_1.\u003crhs\u003e.\u003cvar\u003e = assgn_2.\u003cvar\u003e)\n```\n\nSince this is a more lengthy constraint, let us save it in a file `defuse.isla`. The\nfollowing command line invocation uses this constraint:\n\n```bash\n\u003e isla solve -n 10 -f 1 -s 1 assgn.bnf defuse.isla\nq := 2 ; m := 1 ; c := 4\np := 8 ; o := 3 ; l := p\nz := 7 ; p := 6 ; e := p\nd := 5 ; a := d ; h := 9\ns := 0 ; x := 0\nk := 8\np := 4 ; r := p\np := 6 ; u := p\np := 5 ; v := p\np := 3 ; p := 5 ; w := p\n```\n\nAs we can see, all right-hand side variables occur at the left-hand side of a prior\nassignment.\n\nFor more information on the command line interface, run `isla -h`. Each sub command\ncomes with its own help text; for example, `isla solve -h` provides details on how to\nuse the `solve` command.\n\nYou can also use the ISLa solver via its Python API:\n\n```python\nfrom isla.solver import ISLaSolver\n\ngrammar = '''\n\u003cstart\u003e ::= \u003cstmt\u003e \n\u003cstmt\u003e  ::= \u003cassgn\u003e | \u003cassgn\u003e \" ; \" \u003cstmt\u003e \n\u003cassgn\u003e ::= \u003cvar\u003e \" := \" \u003crhs\u003e \n\u003crhs\u003e   ::= \u003cvar\u003e | \u003cdigit\u003e \n\u003cvar\u003e   ::= \"a\" | \"b\" | \"c\" | \"d\" | \"e\" | \"f\" | \"g\" | \"h\" | \"i\" | \"j\" | \n            \"k\" | \"l\" | \"m\" | \"n\" | \"o\" | \"p\" | \"q\" | \"r\" | \"s\" | \"t\" |\n            \"u\" | \"v\" | \"w\" | \"x\" | \"y\" | \"z\" \n\u003cdigit\u003e ::= \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\"\n'''\n\nconstraint = \"\"\"\nforall \u003cassgn\u003e assgn_1:\n  exists \u003cassgn\u003e assgn_2: (\n    before(assgn_2, assgn_1) and \n    assgn_1.\u003crhs\u003e.\u003cvar\u003e = assgn_2.\u003cvar\u003e)\n\"\"\"\n\nsolver = ISLaSolver(\n    grammar=grammar,\n    formula=constraint,\n    max_number_free_instantiations=1,  # -f\n    max_number_smt_instantiations=1,  # -s\n)\n\nfor _ in range(10):\n    print(solver.solve())\n```\n\nAn example output of the above program snippet is:\n\n```\nq := 7 ; m := 1 ; c := 8\np := 2 ; o := 2 ; l := p\nz := 9 ; p := 4 ; e := p\nd := 8 ; a := d ; h := 5\ns := 0 ; x := 0\nk := 7\np := 8 ; r := p\np := 9 ; u := p\np := 4 ; v := p\np := 2 ; p := 1 ; w := p\n```\n\n## Further Resources\n\n* Our [**interactive ISLa tutorial**](https://www.fuzzingbook.org/beta/html/FuzzingWithConstraints.html),\n  published as a part of the Fuzzing Book, provides an easily accessible introduction\n  to the specification and generation of custom system inputs using ISLa.\n\n* The [**ISLa Documentation**](http://isla.readthedocs.io/) contains\n  + installation and usage instructions;\n  + further examples;\n  + the **ISLa Language Specification,** which precisely specifies the syntax and\n    semantics of ISLa constraints. It also contains a list of supported default\n    predicates;\n  + and a **Developer's Guide** to get started with ISLa's code.\n\n* We published a [**scientific paper on ISLa**](https://publications.cispa.saarland/3596/7/Input%20Invariants.pdf)\n  at ESEC/FSE 2022. The paper describes the ISLa language and solver more formally.\n  \n* In the directory `src/isla_formalizations/`, you find our specifications for the\n  subject languages of our experimental evaluation.\n  \n* The files `run_eval_....fish` are the scripts we used to collect and analyze our\n  evaluation data. To analyze ISLa's current performance yourself, you can run the\n  scripts with the `-h` argument to obtain some guidance on their parameters (the fish\n  shell is required to use these scripts).\n\n## Build, Run, Install\n\nISLa depends on **Python 3.10** and the Python header files. To compile all of ISLa's\ndependencies, you need gcc, g++ make, and cmake. To check out the current ISLa version,\ngit will be needed. Furthermore, python3.10-venv is required to run ISLearn in a virtual\nenvironment.\n\nAdditionally, *for testing ISLa*, clang and the `csvlint` executable are required (for\nthe Scriptsize-C and CSV case studies).\n\nOn *Alpine Linux*, all dependencies (but `csvlint`) can be installed using\n\n```shell\napk add python3.10 python3.10-dev python3.10-venv gcc g++ make cmake git clang\n```\n\nThe `csvlint` executable can be obtained from\nhttps://github.com/Clever/csvlint/releases/download/v0.3.0/csvlint-v0.3.0-linux-amd64.tar.gz.\nYou obtain and unpack `csvlint` by running (in a Unix shell)\n\n```shell\nwget https://github.com/Clever/csvlint/releases/download/v0.3.0/csvlint-v0.3.0-linux-amd64.tar.gz -O /tmp/csvlint.tar.gz\ntar xzf /tmp/csvlint.tar.gz -C /tmp\n```\n\nThen, move the file `/tmp/csvlint-v0.3.0-linux-amd64/csvlint` to some location in your\nPATH (e.g., `/usr/bin`).\n\n### Install\n\nIf all external dependencies are available, a simple `pip install isla-solver` suffices.\nWe recommend installing ISLa inside a virtual environment (virtualenv):\n\n```shell\npython3.10 -m venv venv\nsource venv/bin/activate\npip install --upgrade pip\npip install isla-solver\n```\n\nNow, the `isla` command should be available on the command line within the virtual\nenvironment.\n\n### Docker\n\nFor testing ISLa without having to care about external dependencies like Python, we provide a Docker container,\nwhich already contains all dependencies.\n\nFirst, pull and run the Docker container:\n\n```shell\ndocker pull dsteinhoefel/isla:latest\ndocker run -it --name isla dsteinhoefel/isla\n```\n\nYou should now have entered the container. Next, check out the ISLa repository, and\nupdate the requirements:\n\n```shell\ngit clone https://github.com/rindPHI/isla.git\ncd isla/\n```\n\nNow, you can perform an editable installation of ISLa and run the ISLa tests:\n\n```shell\npip install -e .[dev,test]\npython3.10 -m pytest -n 16 tests\n```\n\n### Build \n\nISLearn is built locally as follows:\n\n```shell\ngit clone https://github.com/rindPHI/isla.git\ncd isla/\n\npython3.10 -m venv venv\nsource venv/bin/activate\n\npip install --upgrade pip\npip install --upgrade build\npython3 -m build\n```\n\nThen, you will find the built wheel (`*.whl`) in the `dist/` directory.\n\n### Testing \u0026 Development\n\nFor development, we recommend using ISLa inside a virtual environment (virtualenv). By thing the following steps in a\nstandard shell (bash), one can run the ISLa tests:\n\n```shell\ngit clone https://github.com/rindPHI/isla.git\ncd isla/\n\npython3.10 -m venv venv\nsource venv/bin/activate\n\npip install --upgrade pip\npip install -r requirements_test.txt\n\n# Run tests\npip install -e .[dev,test]\npython3 -m pytest -n 16 tests\n```\n\nThen you can, for instance, run `python3 tests/xml_demo.py` inside the virtual environment.\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n## Copyright, Authors and License\n\nCopyright © 2022 [CISPA Helmholtz Center for Information Security](https://cispa.de/en).\n\nThe ISLa code and documentation was, unless otherwise indicated, authored by\n[Dominic Steinhöfel](https://www.dominic-steinhoefel.de).\n\nISLa is released under the GNU General Public License v3.0 (see [COPYING](COPYING)).","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frindphi%2Fisla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frindphi%2Fisla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frindphi%2Fisla/lists"}