├── LICENSE ├── README.md ├── code ├── build.gradle.kts ├── core.js └── src │ └── main │ └── kotlin │ ├── Geometry.kt │ ├── Main.kt │ └── SVG.kt ├── diagram ├── config ├── other.svg ├── solving.png ├── solving.svg ├── symbolic-execution.png └── symbolic-execution.svg └── tools └── tools.json /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-ShareAlike 4.0 International Public 58 | License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-ShareAlike 4.0 International Public License ("Public 63 | License"). To the extent this Public License may be interpreted as a 64 | contract, You are granted the Licensed Rights in consideration of Your 65 | acceptance of these terms and conditions, and the Licensor grants You 66 | such rights in consideration of benefits the Licensor receives from 67 | making the Licensed Material available under these terms and 68 | conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. Share means to provide material to the public by any means or 126 | process that requires permission under the Licensed Rights, such 127 | as reproduction, public display, public performance, distribution, 128 | dissemination, communication, or importation, and to make material 129 | available to the public including in ways that members of the 130 | public may access the material from a place and at a time 131 | individually chosen by them. 132 | 133 | l. Sui Generis Database Rights means rights other than copyright 134 | resulting from Directive 96/9/EC of the European Parliament and of 135 | the Council of 11 March 1996 on the legal protection of databases, 136 | as amended and/or succeeded, as well as other essentially 137 | equivalent rights anywhere in the world. 138 | 139 | m. You means the individual or entity exercising the Licensed Rights 140 | under this Public License. Your has a corresponding meaning. 141 | 142 | 143 | Section 2 -- Scope. 144 | 145 | a. License grant. 146 | 147 | 1. Subject to the terms and conditions of this Public License, 148 | the Licensor hereby grants You a worldwide, royalty-free, 149 | non-sublicensable, non-exclusive, irrevocable license to 150 | exercise the Licensed Rights in the Licensed Material to: 151 | 152 | a. reproduce and Share the Licensed Material, in whole or 153 | in part; and 154 | 155 | b. produce, reproduce, and Share Adapted Material. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. Additional offer from the Licensor -- Adapted Material. 186 | Every recipient of Adapted Material from You 187 | automatically receives an offer from the Licensor to 188 | exercise the Licensed Rights in the Adapted Material 189 | under the conditions of the Adapter's License You apply. 190 | 191 | c. No downstream restrictions. You may not offer or impose 192 | any additional or different terms or conditions on, or 193 | apply any Effective Technological Measures to, the 194 | Licensed Material if doing so restricts exercise of the 195 | Licensed Rights by any recipient of the Licensed 196 | Material. 197 | 198 | 6. No endorsement. Nothing in this Public License constitutes or 199 | may be construed as permission to assert or imply that You 200 | are, or that Your use of the Licensed Material is, connected 201 | with, or sponsored, endorsed, or granted official status by, 202 | the Licensor or others designated to receive attribution as 203 | provided in Section 3(a)(1)(A)(i). 204 | 205 | b. Other rights. 206 | 207 | 1. Moral rights, such as the right of integrity, are not 208 | licensed under this Public License, nor are publicity, 209 | privacy, and/or other similar personality rights; however, to 210 | the extent possible, the Licensor waives and/or agrees not to 211 | assert any such rights held by the Licensor to the limited 212 | extent necessary to allow You to exercise the Licensed 213 | Rights, but not otherwise. 214 | 215 | 2. Patent and trademark rights are not licensed under this 216 | Public License. 217 | 218 | 3. To the extent possible, the Licensor waives any right to 219 | collect royalties from You for the exercise of the Licensed 220 | Rights, whether directly or through a collecting society 221 | under any voluntary or waivable statutory or compulsory 222 | licensing scheme. In all other cases the Licensor expressly 223 | reserves any right to collect such royalties. 224 | 225 | 226 | Section 3 -- License Conditions. 227 | 228 | Your exercise of the Licensed Rights is expressly made subject to the 229 | following conditions. 230 | 231 | a. Attribution. 232 | 233 | 1. If You Share the Licensed Material (including in modified 234 | form), You must: 235 | 236 | a. retain the following if it is supplied by the Licensor 237 | with the Licensed Material: 238 | 239 | i. identification of the creator(s) of the Licensed 240 | Material and any others designated to receive 241 | attribution, in any reasonable manner requested by 242 | the Licensor (including by pseudonym if 243 | designated); 244 | 245 | ii. a copyright notice; 246 | 247 | iii. a notice that refers to this Public License; 248 | 249 | iv. a notice that refers to the disclaimer of 250 | warranties; 251 | 252 | v. a URI or hyperlink to the Licensed Material to the 253 | extent reasonably practicable; 254 | 255 | b. indicate if You modified the Licensed Material and 256 | retain an indication of any previous modifications; and 257 | 258 | c. indicate the Licensed Material is licensed under this 259 | Public License, and include the text of, or the URI or 260 | hyperlink to, this Public License. 261 | 262 | 2. You may satisfy the conditions in Section 3(a)(1) in any 263 | reasonable manner based on the medium, means, and context in 264 | which You Share the Licensed Material. For example, it may be 265 | reasonable to satisfy the conditions by providing a URI or 266 | hyperlink to a resource that includes the required 267 | information. 268 | 269 | 3. If requested by the Licensor, You must remove any of the 270 | information required by Section 3(a)(1)(A) to the extent 271 | reasonably practicable. 272 | 273 | b. ShareAlike. 274 | 275 | In addition to the conditions in Section 3(a), if You Share 276 | Adapted Material You produce, the following conditions also apply. 277 | 278 | 1. The Adapter's License You apply must be a Creative Commons 279 | license with the same License Elements, this version or 280 | later, or a BY-SA Compatible License. 281 | 282 | 2. You must include the text of, or the URI or hyperlink to, the 283 | Adapter's License You apply. You may satisfy this condition 284 | in any reasonable manner based on the medium, means, and 285 | context in which You Share Adapted Material. 286 | 287 | 3. You may not offer or impose any additional or different terms 288 | or conditions on, or apply any Effective Technological 289 | Measures to, Adapted Material that restrict exercise of the 290 | rights granted under the Adapter's License You apply. 291 | 292 | 293 | Section 4 -- Sui Generis Database Rights. 294 | 295 | Where the Licensed Rights include Sui Generis Database Rights that 296 | apply to Your use of the Licensed Material: 297 | 298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 299 | to extract, reuse, reproduce, and Share all or a substantial 300 | portion of the contents of the database; 301 | 302 | b. if You include all or a substantial portion of the database 303 | contents in a database in which You have Sui Generis Database 304 | Rights, then the database in which You have Sui Generis Database 305 | Rights (but not its individual contents) is Adapted Material, 306 | 307 | including for purposes of Section 3(b); and 308 | c. You must comply with the conditions in Section 3(a) if You Share 309 | all or a substantial portion of the contents of the database. 310 | 311 | For the avoidance of doubt, this Section 4 supplements and does not 312 | replace Your obligations under this Public License where the Licensed 313 | Rights include other Copyright and Similar Rights. 314 | 315 | 316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 317 | 318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 328 | 329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 338 | 339 | c. The disclaimer of warranties and limitation of liability provided 340 | above shall be interpreted in a manner that, to the extent 341 | possible, most closely approximates an absolute disclaimer and 342 | waiver of all liability. 343 | 344 | 345 | Section 6 -- Term and Termination. 346 | 347 | a. This Public License applies for the term of the Copyright and 348 | Similar Rights licensed here. However, if You fail to comply with 349 | this Public License, then Your rights under this Public License 350 | terminate automatically. 351 | 352 | b. Where Your right to use the Licensed Material has terminated under 353 | Section 6(a), it reinstates: 354 | 355 | 1. automatically as of the date the violation is cured, provided 356 | it is cured within 30 days of Your discovery of the 357 | violation; or 358 | 359 | 2. upon express reinstatement by the Licensor. 360 | 361 | For the avoidance of doubt, this Section 6(b) does not affect any 362 | right the Licensor may have to seek remedies for Your violations 363 | of this Public License. 364 | 365 | c. For the avoidance of doubt, the Licensor may also offer the 366 | Licensed Material under separate terms or conditions or stop 367 | distributing the Licensed Material at any time; however, doing so 368 | will not terminate this Public License. 369 | 370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 371 | License. 372 | 373 | 374 | Section 7 -- Other Terms and Conditions. 375 | 376 | a. The Licensor shall not be bound by any additional or different 377 | terms or conditions communicated by You unless expressly agreed. 378 | 379 | b. Any arrangements, understandings, or agreements regarding the 380 | Licensed Material not stated herein are separate from and 381 | independent of the terms and conditions of this Public License. 382 | 383 | 384 | Section 8 -- Interpretation. 385 | 386 | a. For the avoidance of doubt, this Public License does not, and 387 | shall not be interpreted to, reduce, limit, restrict, or impose 388 | conditions on any use of the Licensed Material that could lawfully 389 | be made without permission under this Public License. 390 | 391 | b. To the extent possible, if any provision of this Public License is 392 | deemed unenforceable, it shall be automatically reformed to the 393 | minimum extent necessary to make it enforceable. If the provision 394 | cannot be reformed, it shall be severed from this Public License 395 | without affecting the enforceability of the remaining terms and 396 | conditions. 397 | 398 | c. No term or condition of this Public License will be waived and no 399 | failure to comply consented to unless expressly agreed to by the 400 | Licensor. 401 | 402 | d. Nothing in this Public License constitutes or may be interpreted 403 | as a limitation upon, or waiver of, any privileges and immunities 404 | that apply to the Licensor or You, including from the legal 405 | processes of any jurisdiction or authority. 406 | 407 | 408 | ======================================================================= 409 | 410 | Creative Commons is not a party to its public licenses. 411 | Notwithstanding, Creative Commons may elect to apply one of its public 412 | licenses to material it publishes and in those instances will be 413 | considered the "Licensor." Except for the limited purpose of indicating 414 | that material is shared under a Creative Commons public license or as 415 | otherwise permitted by the Creative Commons policies published at 416 | creativecommons.org/policies, Creative Commons does not authorize the 417 | use of the trademark "Creative Commons" or any other trademark or logo 418 | of Creative Commons without its prior written consent including, 419 | without limitation, in connection with any unauthorized modifications 420 | to any of its public licenses or any other arrangements, 421 | understandings, or agreements concerning use of licensed material. For 422 | the avoidance of doubt, this paragraph does not form part of the public 423 | licenses. 424 | 425 | Creative Commons may be contacted at creativecommons.org. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Timeline diagrams 2 | 3 | This repository contains manually drawn diagrams with timelines, as well as 4 | Kotlin code for generating similar types of diagrams. However, please note that 5 | the code is not fully functional yet and currently produces diagrams that are 6 | graphically less refined compared to the manually created ones. 7 | 8 | ## Manually drawn diagrams 9 | 10 | ### Symbolic execution 11 | 12 | See the latest version in 13 | [`symbolic-execution.svg`](diagram/symbolic-execution.svg). 14 | 15 | ![Preview](https://raw.github.com/enzet/symbolic-execution/master/diagram/symbolic-execution.png) 16 | 17 | The [symbolic execution timeline](diagram/symbolic-execution.svg) highlights key 18 | tools and concepts in pure symbolic execution, dynamic symbolic execution 19 | (concolic testing), as well as related ideas of model checking, SAT/SMT solving, 20 | black-box fuzzing, taint data tracking, and other dynamic analysis techniques. 21 | 22 | ### SAT and SMT solving 23 | 24 | See the latest version in [`solving.svg`](diagram/solving.svg). 25 | 26 | ![Preview](https://raw.github.com/enzet/symbolic-execution/master/diagram/solving.png) 27 | 28 | The [solving timeline](diagram/solving.svg) showcases major SAT and SMT 29 | techniques and solvers, including those not directly related to symbolic 30 | execution. 31 | 32 | Additionally, there is [a temporary timeline](diagram/other.svg) for some tools 33 | that are not displayed in the diagrams above. 34 | 35 | ### Building PNG and PDF 36 | 37 | Please install the following fonts for correct SVG display: 38 | - [Roboto](https://fonts.google.com/specimen/Roboto) (regular and italic) and 39 | - [Fira Code](https://github.com/tonsky/FiraCode). 40 | 41 | Use Inkscape to build PNG or PDF files. Example for the `symbolic-execution` 42 | diagram: 43 | - PNG: `inkscape diagram/symbolic-execution.svg --export-png diagram/symbolic-execution.png --export-dpi 150`, 44 | - PDF: `inkscape diagram/symbolic-execution.svg --export-pdf diagram/symbolic-execution.pdf`. 45 | 46 | ## Design 47 | 48 | We use colors from 49 | [GitHub Linguist](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) 50 | for input languages. 51 | 52 | ## Contribution to SVG files 53 | 54 | Feel free to suggest changes or add new information. If your change is minor 55 | (like fixing a typo), you can directly edit the source code of 56 | [`symbolic-execution.svg`](diagram/symbolic-execution.svg). For major changes, 57 | you're encouraged to either create a new issue or edit `symbolic-execution.svg`. 58 | The [Inkscape](https://inkscape.org/en/) editor is strongly recommended due to 59 | source code compatibility issues. 60 | 61 | ### Before commiting 62 | 63 | Please use [SVGO](https://github.com/svg/svgo) for diagram optimization before 64 | commiting (to achieve a cleaner diff): 65 | 66 | ```shell 67 | svgo diagram/symbolic-execution.svg \ 68 | --pretty \ 69 | --enable=sortAttrs \ 70 | --disable=removeEditorsNSData \ 71 | --disable=cleanupIDs \ 72 | --indent=2 73 | ``` 74 | 75 | ## Automatic diagram generation 76 | 77 | The repository also includes Kotlin code that automatically generates similar 78 | diagrams using the [`tools.json`](tools/tools.json) file, which contains 79 | descriptions of the tools, and a [`config`](diagram/config) file that guides the 80 | generator on how to arrange and draw the elements. 81 | 82 | ### Tools structure 83 | 84 | File [`tools.json`](tools/tools.json) contains tools JSON description. E.g.: 85 | 86 | ```json 87 | { 88 | "name": "DART", 89 | "since": 2005, 90 | "languages": ["C"], 91 | "uses": ["lp_solve"], 92 | "based": ["CIL"], 93 | "description": "random testing\nand direct\nexecution", 94 | "type": "concolic", 95 | "authors": ["P. Godefroid (B)", "K. Sen (I)", "N. Klarlund (B)"] 96 | }, 97 | ``` 98 | -------------------------------------------------------------------------------- /code/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | kotlin("jvm") version "1.6.0" 5 | kotlin("plugin.serialization") version "1.5.31" 6 | application 7 | } 8 | 9 | group = "me.enzet" 10 | version = "1.0-SNAPSHOT" 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | dependencies { 17 | testImplementation(kotlin("test")) 18 | implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1") 19 | } 20 | 21 | tasks.test { 22 | useJUnit() 23 | } 24 | 25 | tasks.withType() { 26 | kotlinOptions.jvmTarget = "1.8" 27 | } 28 | 29 | application { 30 | mainClass.set("MainKt") 31 | } -------------------------------------------------------------------------------- /code/core.js: -------------------------------------------------------------------------------- 1 | function clear(elements) { 2 | [].forEach.call(elements, function (element) { 3 | // Restore defaults for element here: 4 | element.style.opacity = "0.2"; 5 | }); 6 | } 7 | 8 | elements = document.getElementsByClassName("element"); 9 | clear(elements); 10 | 11 | [].forEach.call(elements, function (element) { 12 | element.addEventListener("mouseover", function (event) { 13 | clear(elements); 14 | [].forEach.call(element.getAttribute("class").split(" "), function (cl) { 15 | if (className != "element") { 16 | subElements = document.getElementsByClassName(className); 17 | [].forEach.call(subElements, function (subElement) { 18 | // Make element visible here: 19 | subElement.style.opacity = "1.0"; 20 | }); 21 | } 22 | }); 23 | }, false); 24 | }); -------------------------------------------------------------------------------- /code/src/main/kotlin/Geometry.kt: -------------------------------------------------------------------------------- 1 | import java.lang.Double.min 2 | import kotlin.math.PI 3 | import kotlin.math.atan2 4 | import kotlin.math.sqrt 5 | 6 | /** 7 | * Simple 2D vector. 8 | */ 9 | class Vector(var x: Double, var y: Double) { 10 | 11 | fun toSVG() = "$x,$y" 12 | fun toMap() = mapOf("x" to x, "y" to y) 13 | fun toSizeMap() = mapOf("width" to x, "height" to y) 14 | override fun toString() = "($x, $y)" 15 | 16 | operator fun plus(vector: Vector) = Vector(x + vector.x, y + vector.y) 17 | operator fun minus(vector: Vector) = Vector(x - vector.x, y - vector.y) 18 | 19 | fun corner(other: Vector?) = other?.let { Vector(min(x, other.x), min(y, other.y)) } ?: this 20 | fun length() = sqrt(x * x + y * y) 21 | 22 | override fun hashCode(): Int = x.hashCode() + y.hashCode() 23 | override fun equals(other: Any?) = if (other is Vector) x == other.x && y == other.y else false 24 | 25 | fun coerceAtMost(vector: Vector) { 26 | x = x.coerceAtMost(vector.x) 27 | y = y.coerceAtMost(vector.y) 28 | } 29 | 30 | fun coerceAtLeast(vector: Vector) { 31 | x = x.coerceAtLeast(vector.x) 32 | y = y.coerceAtLeast(vector.y) 33 | } 34 | } 35 | 36 | operator fun Double.times(vector: Vector): Vector = Vector(this * vector.x, this * vector.y) 37 | 38 | class Line(val point1: Vector, val point2: Vector) { 39 | 40 | fun findIntersection(other: Line): Vector? { 41 | 42 | val t = 43 | ((point1.x - other.point1.x) * (other.point1.y - other.point2.y) - 44 | (point1.y - other.point1.y) * (other.point1.x - other.point2.x)) / 45 | ((point1.x - point2.x) * (other.point1.y - other.point2.y) - 46 | (point1.y - point2.y) * (other.point1.x - other.point2.x)) 47 | 48 | if (0.0 < t && t < 1.0) 49 | return Vector(point1.x + t * (point2.x - point1.x), point1.y + t * (point2.y - point1.y)) 50 | 51 | // `t` is `NaN` if lines are the same. 52 | // `t` is `Infinity` or `-Infinity` if they are parallel. 53 | 54 | return null 55 | } 56 | 57 | private fun getVector() = Vector(point2.x - point1.x, point2.y - point1.y) 58 | 59 | fun getAngle(other: Line): Double { 60 | val vector = getVector() 61 | val otherVector = other.getVector() 62 | // val angle = atan2(otherVector.y - vector.y, otherVector.x - vector.x) 63 | val dot = vector.x * otherVector.x + vector.y * otherVector.y // dot product between [x1, y1] and [x2, y2] 64 | val det = vector.x * otherVector.y - vector.y * otherVector.x // determinant 65 | var angle = atan2(det, dot) // atan2(y, x) or atan2(sin, cos) 66 | if (angle < 0) { 67 | angle += 2 * PI 68 | } 69 | return angle 70 | } 71 | 72 | override fun hashCode(): Int = point1.hashCode() + point2.hashCode() 73 | override fun equals(other: Any?) = if (other is Line) point1 == other.point1 && point2 == other.point2 else false 74 | override fun toString() = "$point1 -- $point2" 75 | } 76 | 77 | class Polygon(private val points: ArrayList = arrayListOf()) { 78 | 79 | fun toCommand() = "M " + points.joinToString(" L ") { it.toSVG() } + " Z" 80 | 81 | fun toSVG(svg: XML) = svg.add( 82 | "path", mapOf( 83 | "d" to toCommand(), "opacity" to "0.05" 84 | ) 85 | ) 86 | 87 | private fun add(lines: HashMap>, line: Line) { 88 | for (point in listOf(line.point1, line.point2)) { 89 | if (!lines.containsKey(point)) lines[point] = hashSetOf(line) 90 | lines[point]!!.add(line) 91 | } 92 | } 93 | 94 | fun join(other: Polygon): Polygon { 95 | 96 | println(toCommand()) 97 | println(other.toCommand()) 98 | 99 | val lines = HashMap>() 100 | 101 | for (i in 0..points.size - 2) for (j in 0..other.points.size - 2) { 102 | 103 | val line1 = Line(points[i], points[i + 1]) 104 | val line2 = Line(other.points[j], other.points[j + 1]) 105 | val intersection = line1.findIntersection(line2) 106 | 107 | intersection?.let { 108 | add(lines, Line(points[i], intersection)) 109 | add(lines, Line(intersection, points[i + 1])) 110 | add(lines, Line(other.points[i], intersection)) 111 | add(lines, Line(intersection, other.points[i + 1])) 112 | } ?: run { 113 | add(lines, line1) 114 | add(lines, line2) 115 | } 116 | } 117 | 118 | var corner: Vector? = null 119 | 120 | for (point in points + other.points) { 121 | corner = point.corner(corner) 122 | } 123 | val unwrapCorner = corner!! 124 | 125 | var minLength: Double? = null 126 | var leftBottom: Vector? = null 127 | 128 | for (point in points + other.points) { 129 | 130 | val length = (point - unwrapCorner).length() 131 | if (minLength == null || length < minLength) { 132 | leftBottom = point 133 | minLength = length 134 | } 135 | } 136 | if (leftBottom == null) { 137 | throw IllegalAccessError() 138 | } 139 | var point: Vector = leftBottom 140 | var previousPoint = leftBottom + Vector(0.0, 1.0) 141 | val n = Polygon(arrayListOf(leftBottom)) 142 | println(leftBottom.toSVG()) 143 | 144 | while (true) { 145 | val nextLines = lines[point] 146 | 147 | if (nextLines != null) { 148 | var minAngle = 2 * PI 149 | var nextPoint: Vector? = null 150 | 151 | for (nextLine in nextLines) { 152 | val currentNextPoint = if (nextLine.point1 == point) nextLine.point2 else nextLine.point1 153 | if (n.points.contains(currentNextPoint)) continue 154 | println(" try $previousPoint $point $currentNextPoint") 155 | val line1 = Line(point, previousPoint) 156 | val line2 = Line(point, currentNextPoint) 157 | val angle = line1.getAngle(line2) 158 | if (angle <= minAngle) { 159 | minAngle = angle 160 | nextPoint = currentNextPoint 161 | } 162 | println(" $angle") 163 | } 164 | if (nextPoint == null) 165 | break 166 | n.points.add(nextPoint) 167 | previousPoint = point 168 | point = nextPoint 169 | println(nextPoint.toSVG()) 170 | if (nextPoint == leftBottom) { 171 | break 172 | } 173 | } else { 174 | break 175 | } 176 | } 177 | return n 178 | } 179 | } -------------------------------------------------------------------------------- /code/src/main/kotlin/Main.kt: -------------------------------------------------------------------------------- 1 | import kotlinx.serialization.SerialName 2 | import kotlinx.serialization.Serializable 3 | import kotlinx.serialization.decodeFromString 4 | import kotlinx.serialization.json.Json 5 | import java.io.File 6 | import kotlin.math.max 7 | import kotlin.math.min 8 | 9 | const val STEP: Int = 20 10 | 11 | /** 12 | * Type of diagram element: instrument or white paper. 13 | */ 14 | @Serializable 15 | enum class ElementType { 16 | /** Concolic (dynamic symbolic execution) with path exploration. */ 17 | @SerialName("concolic") 18 | CONCOLIC, 19 | 20 | /** Concolic (dynamic symbolic execution) within one path. */ 21 | @SerialName("concolic one path") 22 | CONCOLIC_ONE_PATH, 23 | 24 | @SerialName("static symbolic execution") 25 | STATIC_SYMBOLIC_EXECUTION, 26 | 27 | /** Satisfiability modulo theories solver. */ 28 | @SerialName("SMT") 29 | SMT, 30 | 31 | /** Satisfiability solver. */ 32 | @SerialName("SAT") 33 | SAT, 34 | 35 | @SerialName("model checker") 36 | MODEL_CHECKER, 37 | 38 | @SerialName("static instrumentation") 39 | STATIC_INSTRUMENTATION, 40 | 41 | @SerialName("dynamic instrumentation") 42 | DYNAMIC_INSTRUMENTATION, 43 | 44 | @SerialName("fuzzer") 45 | FUZZER, 46 | 47 | /** 48 | * White paper without instrument. 49 | */ 50 | @SerialName("paper") 51 | PAPER, 52 | 53 | /** 54 | * Dynamic analysis within one execution path. 55 | */ 56 | @SerialName("DA one path") 57 | DYNAMIC_ANALYSIS_ONE_PATH, 58 | } 59 | 60 | class ColorScheme { 61 | fun getColor(type: ElementType?): String { 62 | return when (type) { 63 | ElementType.CONCOLIC -> "#E4D3C2" 64 | ElementType.CONCOLIC_ONE_PATH -> "#CAB7A3" 65 | ElementType.DYNAMIC_INSTRUMENTATION -> "#CFB6E0" 66 | ElementType.FUZZER -> "#E4E1A8" 67 | ElementType.MODEL_CHECKER -> "#E0BBBB" 68 | ElementType.SAT -> "#ADC57D" 69 | ElementType.SMT -> "#C8DAA4" 70 | ElementType.STATIC_INSTRUMENTATION -> "#E0CFEB" 71 | ElementType.STATIC_SYMBOLIC_EXECUTION -> "#C4DAD2" 72 | ElementType.PAPER -> "none" 73 | ElementType.DYNAMIC_ANALYSIS_ONE_PATH -> "#D4CD89" 74 | else -> "#E0DAD5" 75 | } 76 | } 77 | 78 | /** 79 | * Language colors extracted from Linguist project. 80 | * 81 | * See [`languages.yml`](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml) file. 82 | */ 83 | fun getLanguageColor(language: String): String { 84 | return when (language) { 85 | ".NET" -> "#178600" 86 | "C" -> "#555555" 87 | "C++" -> "#f34b7d" 88 | "Fortran" -> "#4d41b1" 89 | "Java bytecode" -> "#B07219" 90 | "Java" -> "#B07219" 91 | "JavaScript" -> "#F1E05A" 92 | "Lisp" -> "#3fb68b" 93 | "PL/I" -> "#6d3b9f" 94 | "Python" -> "#3572a5" 95 | "Rosette" -> "#22228f" 96 | "SMT-LIB 1.2" -> "#C8DAA4" 97 | "SMT-LIB 2" -> "#C8DAA4" 98 | "binary" -> "#887f73" 99 | else -> "#888888" 100 | } 101 | } 102 | } 103 | 104 | @Serializable 105 | class Config(val tools: List) 106 | 107 | @Serializable 108 | open class Tool( 109 | /** Start year. E.g. 2000. */ 110 | val since: Int = 1994, 111 | val type: ElementType? = null, 112 | val name: String, 113 | /** Tool name. E.g. “DART”. */ 114 | val id: String = name, 115 | /** Tool authors. E.g. “P. Godefroid (B)\nK. Sen (I)”. */ 116 | val authors: List = ArrayList(), 117 | /** Tool description. E.g. “Random testing and direct execution”. */ 118 | val description: String = "", 119 | /** Target language. E.g. “C”. */ 120 | val languages: List = ArrayList(), 121 | /** Tools used by the tool. E.g. “Z3” for Z3 solver used to solve paths. */ 122 | val uses: List = ArrayList(), 123 | val based: List = ArrayList(), 124 | val ir: List = ArrayList(), 125 | ) 126 | 127 | /** 128 | * Graphical element representing a tool or article. 129 | */ 130 | data class ToolPicture( 131 | val tool: Tool, 132 | val toolMap: Map, 133 | var position: Vector = Vector(0.0, 0.0), 134 | var size: Vector = Vector(100.0, 150.0), 135 | /** Tool name. E.g. “DART”. */ 136 | var names: List = listOf(), 137 | /** Tool description. E.g. “Random testing and direct execution”. */ 138 | var descriptions: List = listOf(), 139 | ) { 140 | private val padding = 10.0 141 | private val nameHeight = 20.0 142 | private val textHeight = 14.0 143 | 144 | private val paperBorderColor = "#888888" 145 | 146 | init { 147 | names = if (tool.name == "") listOf() else tool.name.split("\n") 148 | descriptions = if (tool.description == "") listOf() else tool.description.split("\n") 149 | size = Vector( 150 | 120.0, 151 | padding * 2 + 152 | (descriptions.size + 1) * textHeight + 153 | names.size * nameHeight 154 | ) 155 | } 156 | 157 | private fun addText( 158 | xml: XML, text: String, position: Vector, fontSize: Double = 12.0, letterSpacing: Double = 0.0 159 | ) = xml.add( 160 | "text", position.toMap() + mapOf( 161 | "font-family" to "Roboto", 162 | "font-weight" to 300, 163 | "font-size" to fontSize, 164 | "fill" to "#363228", 165 | "letter-spacing" to letterSpacing, 166 | ), text 167 | ) 168 | 169 | /** Get total height of all bottom elements: tools and authors. */ 170 | fun getBottomHeight(): Double { 171 | return (tool.uses + tool.based + tool.ir).size * 25 + 172 | (if (tool.authors.isNotEmpty()) 5.0 else 0.0) + 173 | (tool.authors).size * textHeight 174 | } 175 | 176 | /** Get total height of all top language element. */ 177 | fun getTopHeight(): Double { 178 | return if (tool.languages.isNotEmpty()) 25.0 else 0.0 179 | } 180 | 181 | fun draw(xml: XML, scheme: ColorScheme, toolMap: Map) { 182 | 183 | if (position.x == 0.0) return 184 | 185 | val stroke = if (tool.type == ElementType.PAPER) paperBorderColor else "none" 186 | 187 | xml.add( 188 | "rect", 189 | mapOf( 190 | "fill" to scheme.getColor(tool.type), 191 | "stroke" to stroke, 192 | "rx" to 5.0) + 193 | position.toMap() + 194 | size.toSizeMap() 195 | ) 196 | var y = padding 197 | 198 | for (text in names) { 199 | y += nameHeight 200 | addText( 201 | xml, 202 | text, 203 | position + Vector(padding, y), 204 | letterSpacing = if (tool.name.uppercase() == tool.name) 1.8 else 0.0, 205 | fontSize = 20.0, 206 | ) 207 | } 208 | y += textHeight 209 | addText(xml, tool.since.toString(), position + Vector(padding, y)) 210 | for (description in descriptions) { 211 | y += textHeight 212 | addText(xml, description, position + Vector(padding, y)) 213 | } 214 | y += padding 215 | 216 | if (tool.languages.isNotEmpty()) { 217 | var x = 0.0 218 | for (language in tool.languages) { 219 | val width = language.length * 6.0 + 20.0 220 | xml.add( 221 | "rect", (position + Vector(x, -25.0)).toMap() + Vector(width, 20.0).toSizeMap() + mapOf( 222 | "fill" to scheme.getLanguageColor(language), "rx" to 2.5 223 | ) 224 | ) 225 | xml.add( 226 | "text", 227 | (position + Vector(width / 2.0 + x, -11.0)).toMap() + mapOf( 228 | "font-size" to 12.0, 229 | "font-family" to "Roboto", 230 | "fill" to "#FFFFFF", 231 | "text-anchor" to "middle", 232 | "font-weight" to 700, 233 | ), 234 | language, 235 | ) 236 | x += width + 5 237 | } 238 | } 239 | if ((tool.uses + tool.based + tool.ir).isNotEmpty()) { 240 | 241 | for (use in tool.uses + tool.based + tool.ir) { 242 | 243 | y += 5.0 244 | 245 | val fill = toolMap[use]?.tool?.type?.let { scheme.getColor(it) } ?: "#E0DAD5" 246 | /** Very rough estimate of a text width. */ 247 | val width = use.length * 6.0 + 20.0 248 | 249 | xml.add( 250 | "rect", 251 | (position + Vector(0.0, y)).toMap() + 252 | Vector(width, 20.0).toSizeMap() + 253 | mapOf("fill" to fill, "rx" to 2.5) 254 | ) 255 | xml.add( 256 | "text", 257 | (position + Vector(width / 2.0, y + textHeight)).toMap() + mapOf( 258 | "font-size" to 12.0, 259 | "font-family" to "Roboto", 260 | "font-weight" to 300, 261 | "text-anchor" to "middle", 262 | ), 263 | use, 264 | ) 265 | y += 20.0 266 | } 267 | } 268 | if (tool.authors.isNotEmpty()) { 269 | y += 5.0 270 | for (author in tool.authors) { 271 | y += textHeight 272 | addText(xml, author, position + Vector(0.0, y)) 273 | } 274 | } 275 | size.y = y 276 | } 277 | 278 | /** Put this tool below the specified tool. */ 279 | fun putBelow(tool: ToolPicture) { 280 | position.x = tool.position.x 281 | val y = tool.position.y + 282 | tool.size.y + 283 | tool.getBottomHeight() + 284 | 10.0 + 285 | getTopHeight() 286 | position.y = max(position.y, y) 287 | } 288 | 289 | /** Put this tool above the specified tool. */ 290 | fun putAbove(tool: ToolPicture) { 291 | position.x = tool.position.x 292 | val y = tool.position.y - 293 | size.y - 294 | getBottomHeight() - 295 | 10.0 - 296 | tool.getTopHeight() 297 | position.y = min(position.y, y) 298 | } 299 | } 300 | 301 | /** 302 | * Shape around all tools with the same affiliation. 303 | */ 304 | class AffiliationPicture { 305 | 306 | private val padding = Vector(20.0, 20.0) 307 | 308 | private var start = Vector(Double.MAX_VALUE, Double.MAX_VALUE) 309 | private var end = Vector(Double.MIN_VALUE, Double.MIN_VALUE) 310 | 311 | /** Add tool with this affiliation. */ 312 | fun add(toolPicture: ToolPicture) { 313 | start.coerceAtMost(toolPicture.position - Vector(0.0, toolPicture.getTopHeight())) 314 | end.coerceAtLeast(toolPicture.position + toolPicture.size + Vector(0.0, toolPicture.getBottomHeight())) 315 | } 316 | 317 | fun draw(xml: XML) = xml.add( 318 | "rect", (start - padding).toMap() + (end - start + 2.0 * padding).toSizeMap() + mapOf( 319 | "opacity" to 0.07, "rx" to 20.0, "fill" to "#816647" 320 | ) 321 | ) 322 | 323 | fun getPolygon(): Polygon = Polygon(arrayListOf(start, Vector(end.x, start.y), end, Vector(start.x, end.y))) 324 | } 325 | 326 | private data class Timeline(val tools: List, val scheme: ColorScheme, val configuration: List) { 327 | 328 | val toolMap: HashMap = HashMap() 329 | val affiliations: HashMap> = HashMap() 330 | 331 | init { 332 | for (tool in tools) { 333 | toolMap[tool.id] = ToolPicture(tool, toolMap) 334 | } 335 | for (toolPicture in toolMap.values) { 336 | toolPicture.position.y = getY(toolPicture.tool.since).toDouble() 337 | } 338 | 339 | for (line in configuration) { 340 | val parts = line.split(" ") 341 | 342 | if (parts[0] == "->") { 343 | var tool = toolMap[parts[1]] ?: throw NotImplementedError(parts[1]) 344 | for (i in 2 until parts.size) { 345 | val tool2 = toolMap[parts[i]] ?: throw NotImplementedError(parts[i]) 346 | tool2.position.x = tool.position.x + tool.size.x + STEP 347 | tool = tool2 348 | } 349 | 350 | } else if (parts[0] == "v") { 351 | for (i in 2 until parts.size) { 352 | val tool = toolMap[parts[i - 1]] ?: throw NotImplementedError(parts[i - 1]) 353 | val tool2 = toolMap[parts[i]] ?: throw NotImplementedError(parts[i]) 354 | 355 | tool2.putBelow(tool) 356 | } 357 | 358 | } else if (parts.size == 2) { 359 | val tool = toolMap[parts[0]] ?: throw NotImplementedError(parts[0]) 360 | tool.position.x = parts[1].toDouble() 361 | 362 | } else if (parts.size == 3) { 363 | val tool = toolMap[parts[0]] ?: throw NotImplementedError(parts[0]) 364 | val tool2 = toolMap[parts[2]] ?: throw NotImplementedError(parts[2]) 365 | 366 | if (parts[1].startsWith("->")) { 367 | val offset = if (parts[1].length > 2) parts[1].substring(2).toDouble() else 0.0 368 | tool2.position.x = tool.position.x + tool.size.x + STEP * (1 + offset) 369 | } else { 370 | when (parts[1]) { 371 | "<-" -> tool2.position.x = tool.position.x - tool2.size.x - STEP 372 | "v" -> tool2.putBelow(tool) 373 | "^" -> tool2.putAbove(tool) 374 | "|" -> tool2.position.y = tool.position.y 375 | } 376 | } 377 | 378 | } else if (parts.size > 3) { 379 | val affiliation = parts[0] 380 | val picture = AffiliationPicture() 381 | for (i in 2 until parts.size) { 382 | toolMap[parts[i]]?.let { picture.add(it) } 383 | } 384 | if (!affiliations.containsKey(affiliation)) { 385 | affiliations[affiliation] = hashSetOf(picture) 386 | } 387 | affiliations[affiliation]!!.add(picture) 388 | } 389 | } 390 | } 391 | 392 | fun draw(xml: XML, filePath: String) { 393 | for (affiliationPictures in affiliations.keys) { 394 | var polygon: Polygon? = null 395 | for (affiliationPicture in affiliations[affiliationPictures]!!) { 396 | affiliationPicture.draw(xml) 397 | // val polygon2 = affiliationPicture.getPolygon() 398 | // polygon = polygon?.join(polygon2) ?: polygon2 399 | // polygon.toSVG(xml) 400 | } 401 | } 402 | for (toolPicture in toolMap.values) toolPicture.draw(xml, scheme, toolMap) 403 | xml.writeSVG(filePath) 404 | } 405 | } 406 | 407 | fun getYearHeight(year: Int): Int { 408 | if (year <= 1990) return 2 409 | if (year <= 2000) return 20 410 | return when (year) { 411 | 2001 -> 40 412 | 2002, 2003, 2004 -> 60 413 | else -> 140 414 | } 415 | } 416 | 417 | fun getY(year: Int): Int { 418 | var y = 0 419 | for (yr in 1906 until year) { 420 | y += getYearHeight(yr) 421 | } 422 | return y 423 | } 424 | 425 | fun main() { 426 | 427 | val toolsPath = "tools/tools.json" 428 | val diagramConfigurationPath = "diagram/config" 429 | val outputFilePath = "diagram.svg" 430 | 431 | val json = Json { ignoreUnknownKeys = true } 432 | 433 | val config = json.decodeFromString(File(toolsPath).readText(Charsets.UTF_8)) 434 | val scheme = ColorScheme() 435 | val xml = XML() 436 | 437 | val timeline = Timeline(config.tools, scheme, File(diagramConfigurationPath).readLines()) 438 | timeline.draw(xml, outputFilePath) 439 | } 440 | -------------------------------------------------------------------------------- /code/src/main/kotlin/SVG.kt: -------------------------------------------------------------------------------- 1 | import java.io.File 2 | 3 | class XMLParameter(private val key: String, private val value: Any?) { 4 | 5 | override fun toString() = "$key=\"$value\"" 6 | } 7 | 8 | class XMLTag(private val tag: String, private val parameters: List, private val value: String? = null) { 9 | 10 | override fun toString() = "<$tag" + parameters.joinToString(" ", " ") + (value?.let { ">$value" } ?: "/>") 11 | 12 | } 13 | 14 | open class XML { 15 | 16 | /** 17 | * Graphical elements. 18 | */ 19 | var elements: ArrayList = ArrayList() 20 | 21 | /** 22 | * Add graphical element to the drawing. 23 | */ 24 | fun add(tag: String, parameters: Map, text: String? = null) { 25 | 26 | val xmlParameters = parameters.toList().map { XMLParameter(it.first, it.second) } 27 | elements.add(XMLTag(tag, xmlParameters, text)) 28 | } 29 | } 30 | 31 | /** 32 | * Write XML as an SVG drawing to the file with [filePath] path. 33 | * 34 | * @property filePath output SVG file path 35 | */ 36 | fun XML.writeSVG(filePath: String) = File(filePath).printWriter().use { out -> 37 | out.println("") 38 | out.println("") 39 | for (element in elements) out.println(element) 40 | out.println("") 41 | } -------------------------------------------------------------------------------- /diagram/config: -------------------------------------------------------------------------------- 1 | SMT-LIB 190 2 | v SMT-LIB CVC3 SMT-LIB_2 CVC4 CVC4_2 3 | 4 | VeriSoft 1130 5 | VeriSoft -> SPIN 6 | SPIN v DART 7 | DART ->1 CUTE 8 | CUTE v jCUTE 9 | CUTE ->2 Eraser 10 | Eraser v Catchconv 11 | SVC 410 12 | v SVC CVC CVC_Lite EXE KLEE MINESTRONE UC-KLEE 13 | SVC -> Chord 14 | v Chord EGT STP SurveyTestCase 15 | 16 | HAMPI 730 17 | HAMPI -> jFuzz 18 | jFuzz ^ GrammarBased 19 | jFuzz ->2 Z3 20 | v jFuzz Z3-str Z3str2 21 | Z3str2 -> Z3str3 22 | Z3 ^ Yices 23 | Z3 -> Pex 24 | Z3 v Rex 25 | Rex -> SAGAN 26 | SAGAN ->2 Kudzu 27 | Pex -> Splat 28 | Pex ^ SMART 29 | Pex v Lean 30 | Pex v PyExZ3 31 | Splat ->1 SAGE 32 | SAGE ->2 BitBlaze 33 | BitBlaze v LESE 34 | BitBlaze ->2 Replayer 35 | BitBlaze ->1 ATOM 36 | LESE v DTA++ 37 | v DTA++ FuzzBALL Rosette Galactica 38 | Rosette <- Jalangi 39 | 40 | DTA++ ->2 AEG 41 | AEG -> BAP 42 | AEG v Mayhem 43 | Mayhem v MergePoint 44 | MergePoint v ISSTAC 45 | BAP v dReal 46 | 47 | BAP ->2 EFFIGY 48 | EFFIGY ->2 SELECT 49 | SELECT ->2 massachusetts.fortran 50 | massachusetts.fortran ->2 PathCrawler 51 | PathCrawler ->3 GlassTT 52 | PathCrawler v SANTE 53 | GlassTT ->2 Peach 54 | v Peach MiniSAT ExpliSAT Boolector S2E Dowser BORG 55 | S2E -> Cloud9 56 | v S2E Dowser BORG 57 | Dowser ->1 Sherlock 58 | Sherlock v Triton 59 | Sherlock -> libFuzzer 60 | v libFuzzer AFL OSS-Fuzz AFLFast 61 | -> Peach JNuke Autodafé 62 | v EFFIGY Java_PathFinder Java_PathFinder_2 JPF-SE Symbolic_PathFinder JDart 63 | v SELECT Dyninst DynamoRIO Dytan Cinger Green_Solver Pathgrind Firmalice angr 64 | -> angr Driller Mechanical_Phish 65 | v massachusetts.fortran Valgrind PIN AXGEN Debugger ILLITHID 66 | Mechanical_Phish ->1 SymJS 67 | v SymJS BLT Xandra Ponce 68 | BLT -> CIVL 69 | v CIVL Manticore 70 | 71 | v GlassTT Flayer Rubyx Otter SymDroid 72 | 73 | Stanford [ SVC Chord UC-KLEE ] 74 | Bell_labs [ VeriSoft SPIN ] 75 | Bell_labs [ SPIN DART ] 76 | MIT [ HAMPI jFuzz GrammarBased ] 77 | Carnegie_Mellon [ Replayer BAP ISSTAC ] 78 | California,_Santa_Barbara [ Firmalice Mechanical_Phish ] 79 | Maryland [ Rubyx SymDroid ] 80 | CEA_/_Saclay [ PathCrawler SANTE ] 81 | EPFL [ S2E Cloud9 ] 82 | Amsterdam,_Vienna [ Dowser BORG ] 83 | Immunity [ Debugger ILLITHID ] 84 | Digital_Equipment [ Eraser ATOM ] 85 | NASA [ Java_PathFinder JDart ] 86 | Georgia [ Dytan Cinger ] 87 | Microsoft_Research [ Z3 SAGE ] 88 | Microsoft_Research [ SMART PyExZ3 ] 89 | -------------------------------------------------------------------------------- /diagram/other.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Google 92 | 93 | 94 | Ghent 95 | 96 | 97 | Duke 98 | 99 | 100 | Syracuse, USA 101 | 102 | 103 | Hong Kong 104 | 105 | 106 | Oracle 107 | 108 | 109 | Pennsylvania 110 | 111 | 112 | Texas 113 | 114 | 115 | IBM 116 | 117 | 118 | New York 119 | 120 | 121 | Minnesota 122 | 123 | 124 | Rome, USA 125 | 126 | 127 | Intel 128 | 129 | 130 | 131 | 132 | NDroid 2014 for Android: Java and JNI, tracks data flow random input data 133 | 134 | 135 | TaintDroid 2010 for Android, no JNI, only tracks data flow, use taint tags between real variables 136 | 137 | 138 | DroidScope 2012 for Android, Dalvik, Java and JNI, taint tracker for leaks 139 | 140 | 141 | Jinn 2010 for Java, JNI, dynamic analysis 142 | 143 | 144 | Thread Sanitizer 2009 data race detector 145 | 146 | 147 | Java Thread Sanitizer 148 | 149 | 150 | HotSpot 1999 151 | 152 | 153 | Pin 154 | 155 | 156 | Address Sanitizer 2012 buffer overflows, use-after-free 157 | 158 | 159 | Memory Sanitizer 2015 160 | 161 | 162 | Javana 2006 for Java, JNI, dynamic analysis, framework 163 | 164 | 165 | DIOTA 166 | 167 | 168 | DECAF 2016 dynamic binary analysis 169 | 170 | 171 | Jikes RVM 172 | 173 | 174 | Jikes RVM 1997 Research Virtual Machine, for PowerPC and IA-32 175 | 176 | 177 | ThreadSanitizer 178 | 179 | 180 | Valgrind 181 | 182 | 183 | ThreadSanitizer 2011 184 | 185 | 186 | LLVM 187 | 188 | 189 | LLVM 190 | 191 | 192 | GCC 193 | 194 | 195 | ThreadSanitizer 196 | 197 | 198 | ASM 199 | 200 | 201 | LLVM 202 | 203 | 204 | LLVM 205 | 206 | 207 | 208 | 209 | Java 210 | 211 | 212 | Java 213 | 214 | 215 | Java 216 | 217 | 218 | Java 219 | 220 | 221 | Java bytecode 222 | 223 | 224 | Java 225 | 226 | 227 | C++ 228 | 229 | 230 | C++ 231 | 232 | 233 | C 234 | 235 | 236 | Go 237 | 238 | 239 | C 240 | 241 | 242 | C++ 243 | 244 | 245 | C 246 | 247 | 248 | binary 249 | 250 | 251 | 252 | 253 | 2001 254 | 255 | 256 | 2002 257 | 258 | 259 | 2003 260 | 261 | 262 | 2004 263 | 264 | 265 | 2005 266 | 267 | 268 | 2006 269 | 270 | 271 | 2007 272 | 273 | 274 | 2008 275 | 276 | 277 | 2009 278 | 279 | 280 | 2010 281 | 282 | 283 | 2011 284 | 285 | 286 | 2012 287 | 288 | 289 | 2013 290 | 291 | 292 | 2014 293 | 294 | 295 | 2015 296 | 297 | 298 | 2016 299 | 300 | 301 | 2017 302 | 303 | 304 | 1990 305 | 306 | 307 | 1992 308 | 309 | 310 | 1994 311 | 312 | 313 | 1996 314 | 315 | 316 | 1998 317 | 318 | 319 | 2000 320 | 321 | 322 | 1970 323 | 324 | 325 | 326 | 327 | black-box fuzzing path exploration 328 | 329 | 330 | model checking 331 | 332 | 333 | Java virtual machine 334 | 335 | 336 | other 337 | 338 | 339 | Dynamic analysis 340 | 341 | 342 | dynamic analysis within one path 343 | 344 | 345 | B. Lee (T) B. Wiedermann (T), ... 346 | 347 | 348 | D. Buytaert J. Maebe, ... 349 | 350 | 351 | Lok Kwong Yan (S, R) Heng Yin (S) 352 | 353 | 354 | A. Henderson (S) Lok Kwong Yan (R), ... 355 | 356 | 357 | K. Serebryany T. Iskhodzhanov 358 | 359 | 360 | K. Serebryany A. Potapenko, ... 361 | 362 | 363 | K. Serebryany D. Bruening, ... 364 | 365 | 366 | E. Stepanov K. Serebryany, ... 367 | 368 | 369 | Sergey Varatnov and GitHub contributors, 2017 370 | 371 | 372 | github.com/enzet/symbolic-execution 373 | 374 | 375 | W. Enck (P) P. Gilbert (D), ... 376 | 377 | 378 | static symbolic execution 379 | 380 | 381 | 382 | -------------------------------------------------------------------------------- /diagram/solving.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzet/symbolic-execution/1e6a47966a9711bb4fab538b7e3b73615966cd47/diagram/solving.png -------------------------------------------------------------------------------- /diagram/symbolic-execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enzet/symbolic-execution/1e6a47966a9711bb4fab538b7e3b73615966cd47/diagram/symbolic-execution.png -------------------------------------------------------------------------------- /tools/tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "tools": [ 3 | { 4 | "name": "ABC", 5 | "since": 2015, 6 | "description": "string constraint solver and model counter", 7 | "url": "https://vlab.cs.ucsb.edu/ABC/", 8 | "github": "vlab-cs-ucsb/ABC", 9 | "type": "SMT" 10 | }, 11 | { 12 | "name": "ABsolver", 13 | "since": 2007, 14 | "url": "http://absolver.sourceforge.net", 15 | "os": "Linux", 16 | "license": "CPL", 17 | "languages": [ 18 | "SMT-LIB 1.2", 19 | "DIMACS" 20 | ], 21 | "api": "C++", 22 | "technique": "DPLL", 23 | "description": "arithmetic and Boolean solver, DPLL-based SMT solver" 24 | }, 25 | { 26 | "name": "AEG", 27 | "languages": ["C"], 28 | "since": 2011, 29 | "description": "exploit generator", 30 | "type": "concolic one path" 31 | }, 32 | { 33 | "name": "ATOM", 34 | "since": 1994, 35 | "description": "instrumentation\nframework\n", 36 | "affiliations": [ 37 | "Digital Equipment", 38 | "California, Berkeley" 39 | ], 40 | "type": "static instrumentation" 41 | }, 42 | { 43 | "name": "Acteve", 44 | "languages": ["Java"], 45 | "url": "https://code.google.com/archive/p/acteve/" 46 | }, 47 | { 48 | "name": "Alt Ergo", 49 | "os": [ 50 | "Linux", 51 | "macOS", 52 | "Windows" 53 | ], 54 | "license": "CeCILL-C", 55 | "languages": [ 56 | "SMT-LIB 1.2", 57 | "SMT-LIB_2", 58 | "polymorphic first-order language" 59 | ], 60 | "api": "OCaml", 61 | "technique": "SAT", 62 | "description": "SAT-based SMT solver, Shostak-like and Nelson-Oppen" 63 | }, 64 | { 65 | "name": "angr", 66 | "languages": ["binary"], 67 | "url": "http://angr.io/", 68 | "since": 2016, 69 | "uses": ["VEX", "Unicorn", "Z3"], 70 | "type": "concolic", 71 | "authors": ["Y. Shoshitaishvili", "R. Wang", "..."] 72 | }, 73 | { 74 | "name": "BAP", 75 | "languages": ["binary"], 76 | "github": "BinaryAnalysisPlatform/bap", 77 | "since": 2011, 78 | "type": "dynamic instrumentation" 79 | }, 80 | { 81 | "name": "Barcelogic", 82 | "os": "Linux", 83 | "license": "proprietary", 84 | "languages": [ 85 | "SMT-LIB 1.2" 86 | ], 87 | "api": "C++", 88 | "technique": "DPLL", 89 | "type": "SMT", 90 | "description": "DPLL-based SMT solver, congruence closure" 91 | }, 92 | { 93 | "name": "Beaver", 94 | "url": "http://uclid.eecs.berkeley.edu/jha/beaver-dist/beaver.html", 95 | "os": [ 96 | "Linux", 97 | "Windows" 98 | ], 99 | "license": "proprietary", 100 | "languages": [ 101 | "SMT-LIB 1.2" 102 | ], 103 | "description": "SAT-based SMT solver", 104 | "type": "SMT", 105 | "api": "C++" 106 | }, 107 | { 108 | "name": "BitBlaze", 109 | "languages": ["binary"], 110 | "url": "http://bitblaze.cs.berkeley.edu/", 111 | "since": 2008, 112 | "type": "concolic", 113 | "authors": ["D. Song (B)", "D. Brumley (CM)", "... (B)"] 114 | }, 115 | { 116 | "name": "BLT", 117 | "type": "SMT", 118 | "description": "bounded integer\nlinear constraints", 119 | "since": 2015, 120 | "cited": {"count": 2, "date": "2021.12.27"}, 121 | "paper": "Bounded integer linear constraint solving via lattice search", 122 | "authors": ["J. Hendrix", "B. F. Jones"] 123 | }, 124 | { 125 | "name": "Xandra", 126 | "uses": ["AFL"], 127 | "description": "symbolic execution,\nfuzzing, binary\npatching", 128 | "since": 2018, 129 | "cited": {"count": 12, "date": "2021.12.27"}, 130 | "paper": "Xandra: An autonomous cyber battle system for the Cyber Grand Challenge", 131 | "type": "concolic", 132 | "authors": ["A. Nguyen-Tuong", "D. Melski", "JW Davidson", "..."] 133 | }, 134 | { 135 | "name": "Boolector", 136 | "description": "SMT solver", 137 | "paper": "boolector", 138 | "type": "SMT", 139 | "languages": [ 140 | "SMT-LIB", 141 | "SMT-LIB_2" 142 | ], 143 | "license": "GPL 3", 144 | "os": "Linux", 145 | "api": "C", 146 | "authors": ["R. Brummayer", "A. Biere"], 147 | "since": 2009 148 | }, 149 | { 150 | "name": "Ponce", 151 | "description": "interactive\nsymbolic\nexecution", 152 | "type": "concolic", 153 | "uses": ["IDA_Pro"], 154 | "authors": ["A. G. Illera", "F. Oca"], 155 | "languages": ["x86", "x64"], 156 | "since": 2015 157 | }, 158 | { 159 | "name": "SANTE", 160 | "since": 2012, 161 | "description": "combination of\ndynamic\nand static analysis", 162 | "based": ["PathCrawler"], 163 | "languages": ["C"], 164 | "authors": ["O. Chebaro", "N. Kosmatov", "A. Giorgetti", "J. Julliand"], 165 | "type": "concolic" 166 | }, 167 | { 168 | "name": "PEBIL", 169 | "type": "static instrumentation", 170 | "based": ["ATOM"], 171 | "description": "static binary\ninstrumentator", 172 | "languages": ["binary"] 173 | }, 174 | { 175 | "name": "CATG", 176 | "languages": ["Java"], 177 | "github": "ksen007/janala2" 178 | }, 179 | { 180 | "name": "Chord", 181 | "uses": [ 182 | "Javassist", 183 | "bddbddb" 184 | ], 185 | "since": 2001, 186 | "languages": ["Java"], 187 | "type": "concolic" 188 | }, 189 | { 190 | "name": "CIVL", 191 | "languages": ["C"], 192 | "url": "http://vsl.cis.udel.edu/civl/", 193 | "since": 2015, 194 | "description": "for concurrency", 195 | "type": "concolic", 196 | "authors": ["S. F. Siegel (D)", "Manchun Zheng (D)", "..."] 197 | }, 198 | { 199 | "name": "Manticore", 200 | "since": 2017, 201 | "description": "symbolic execution,\ntaint analysis", 202 | "type": "concolic", 203 | "languages": ["binary"] 204 | }, 205 | { 206 | "name": "Dowser", 207 | "since": 2013, 208 | "description": "guided SE to find\nbuffer overflow", 209 | "uses": ["S2E"], 210 | "type": "concolic", 211 | "authors": ["I. Haller (A)", "A. Slowinksa (A)", "M. Neugsch-", "wandtner (V)", "H. Bos (A)"] 212 | }, 213 | { 214 | "name": "BORG", 215 | "since": 2015, 216 | "description": "SA and DA\ncombination,\nguided SE to find\nbuffer over-read", 217 | "uses": ["S2E"], 218 | "authors": ["M. Neugsch-", "wandtner (V)", "P. M. Comparetti (L)", "I. Haller (A)", "H. Bos (A)"], 219 | "type": "concolic" 220 | }, 221 | { 222 | "name": "Sherlock", 223 | "since": 2014, 224 | "description": "static analysis and\nconcolic for\ndeadlocks,\nscheduler control", 225 | "authors": ["M. Eslamimehr", "J. Palsberg"], 226 | "languages": ["Java"], 227 | "type": "concolic" 228 | }, 229 | { 230 | "name": "Cloud9", 231 | "languages": ["LLVM bitcode"], 232 | "url": "http://cloud9.epfl.ch/", 233 | "since": 2011, 234 | "type": "concolic", 235 | "authors": ["S. Bucur", "V. Ureche", "..."] 236 | }, 237 | { 238 | "name": "clsat", 239 | "type": "SMT" 240 | }, 241 | { 242 | "name": "CORAL", 243 | "type": "SMT" 244 | }, 245 | { 246 | "name": "CREST", 247 | "languages": ["C"], 248 | "github": "jburnim/crest" 249 | }, 250 | { 251 | "name": "CUTE", 252 | "since": 2005, 253 | "type": "concolic", 254 | "uses": [ 255 | "lp_solve" 256 | ], 257 | "based": ["CIL"], 258 | "languages": ["C"], 259 | "description": "concolic testing", 260 | "url": "http://lpsolve.sourceforge.net/", 261 | "authors": ["K. Sen", "D. Marinov", "G.Agha"] 262 | }, 263 | { 264 | "name": "CVC", 265 | "since": 2002, 266 | "type": "SMT", 267 | "description": "SMT solver", 268 | "long_description": "SMT solver, SAT-based (Chaff algorithm), Nelson-Oppen, no quantifiers", 269 | "based": ["Chaff"], 270 | "authors": ["A. Stump", "C. W. Barrett", "..."] 271 | }, 272 | { 273 | "name": "CVC Lite", 274 | "id": "CVC_Lite", 275 | "since": 2004, 276 | "type": "SMT", 277 | "description": "SMT solver", 278 | "authors": ["C. W. Barrett (N)", "S. Berezin (S)"] 279 | }, 280 | { 281 | "name": "CVC3", 282 | "description": "SMT solver", 283 | "paper": "cvc3", 284 | "type": "SMT", 285 | "based": ["MiniSAT"], 286 | "since": 2007, 287 | "authors": ["C. Barrett (N)", "C. Tinelli (I)"] 288 | }, 289 | { 290 | "name": "CVC4", 291 | "since": 2011, 292 | "type": "SMT", 293 | "description": "DPLL(T)\nSMT solver", 294 | "based": ["MiniSAT"], 295 | "languages": [ 296 | "SMT-LIB 2", 297 | "CVC" 298 | ], 299 | "license": "BSD", 300 | "os": [ 301 | "Linux", 302 | "macOS", 303 | "Windows" 304 | ], 305 | "api": "C++", 306 | "authors": ["C. Barrett (N)", "..."] 307 | }, 308 | { 309 | "name": "CVC4", 310 | "id": "CVC4_2", 311 | "since": 2016, 312 | "description": "with string\nconstraints", 313 | "authors": ["T. Liang (I)", "..."], 314 | "type": "SMT" 315 | }, 316 | { 317 | "name": "DART", 318 | "since": 2005, 319 | "languages": ["C"], 320 | "uses": ["lp_solve"], 321 | "based": ["CIL"], 322 | "description": "random testing\nand direct\nexecution", 323 | "type": "concolic", 324 | "authors": ["P. Godefroid (B)", "K. Sen (I)", "N. Klarlund (B)"] 325 | }, 326 | { 327 | "name": "DPrle", 328 | "url": "http://www.cs.virginia.edu/~ph4u/dprle/", 329 | "github": "seliopou/dprle", 330 | "description": "decision procedure for systems of equations that consist of regular languages, concatenation, and grounded subset constraints" 331 | }, 332 | { 333 | "name": "DTA++", 334 | "since": 2011, 335 | "languages": ["binary"], 336 | "type": "concolic", 337 | "authors": ["M. Kang (B, CM)", "S. McCamant (B)", "..."] 338 | }, 339 | { 340 | "name": "Dyninst", 341 | "paper": "dyninst", 342 | "type": "dynamic instrumentation", 343 | "description": "dynamic binary\ninstrumentator", 344 | "creator": "ParaDyn", 345 | "since": 1999 346 | }, 347 | { 348 | "name": "DynamoRIO", 349 | "paper": "dynamorio", 350 | "description": "dynamic binary\ninstrumentator", 351 | "since": 2002, 352 | "type": "dynamic instrumentation" 353 | }, 354 | { 355 | "name": "EFFIGY", 356 | "since": 1976, 357 | "description": "symbolic execution", 358 | "languages": ["PL/I"], 359 | "affiliations": [ 360 | "IBM" 361 | ], 362 | "authors": [ 363 | "J. King" 364 | ], 365 | "type": "concolic" 366 | }, 367 | { 368 | "name": "EGT", 369 | "since": 2005, 370 | "type": "concolic", 371 | "authors": ["C. Cadar", "D. Engler"] 372 | }, 373 | { 374 | "name": "Eraser", 375 | "since": 1997, 376 | "based": ["ATOM"], 377 | "description": "data race detector:\nlockset and\nhappens-before,\nbinary rewriting", 378 | "authors": ["S. Savage (W)", "M. Burrows (DE)", "G. Nelson (DE)", "P. Sobalvarro (DE)", "T. Anderson (B)"], 379 | "type": "DA one path", 380 | "languages": ["binary"] 381 | }, 382 | { 383 | "name": "EXE", 384 | "since": 2006, 385 | "uses": ["STP"], 386 | "languages": ["binary"], 387 | "type": "concolic", 388 | "authors": ["C. Cadar, V. Ganesh", "P. Pawlowski", "D. Engler, D. Dill"] 389 | }, 390 | { 391 | "name": "ExtSAT", 392 | "type": "SMT" 393 | }, 394 | { 395 | "name": "Flayer", 396 | "languages": ["binary"], 397 | "based": [ 398 | "Valgrind", 399 | "Memcheck" 400 | ], 401 | "paper": "flayer", 402 | "since": 2007, 403 | "type": "concolic", 404 | "authors": ["W. Drewry", "T. Ormandy"], 405 | "description": "taint flow,\nredirect flow" 406 | }, 407 | { 408 | "name": "libFuzzer", 409 | "based": ["LLVM"], 410 | "description": "coverage-guided", 411 | "type": "fuzzer", 412 | "since": 2016, 413 | "paper": "Continuous fuzzing with libfuzzer and addresssanitizer", 414 | "authors": ["K. Serebryany"], 415 | "cited": {"count": 67, "date": "2021.12.27"} 416 | }, 417 | { 418 | "name": "Memcheck", 419 | "type": "model checker" 420 | }, 421 | { 422 | "name": "Fx7", 423 | "type": "SMT" 424 | }, 425 | { 426 | "name": "FuzzBALL", 427 | "languages": ["x86"], 428 | "url": "http://bitblaze.cs.berkeley.edu/fuzzball.html", 429 | "since": 2012, 430 | "based": ["BitBlaze"], 431 | "authors": ["L. Martignoni (B)", "S. McCamant (B)", "..."], 432 | "type": "concolic" 433 | }, 434 | { 435 | "name": "Galactica", 436 | "since": 2016, 437 | "type": "concolic", 438 | "based": ["S2E"] 439 | }, 440 | { 441 | "name": "ISSTAC", 442 | "since": 2016, 443 | "type": "concolic", 444 | "based": ["SPF"] 445 | }, 446 | { 447 | "name": "dReal", 448 | "since": 2013, 449 | "type": "SMT", 450 | "authors": ["S. Kong"] 451 | }, 452 | { 453 | "name": "Java\nPathFinder", 454 | "id": "Java_PathFinder", 455 | "languages": ["Java"], 456 | "since": 1998, 457 | "type": "model checker" 458 | }, 459 | { 460 | "name": "Java\nPathFinder", 461 | "id": "Java_PathFinder_2", 462 | "since": 2005, 463 | "languages": ["Java"], 464 | "type": "model checker", 465 | "uses": ["Omega"], 466 | "authors": ["W. Visser (N)", "C. Păsăreanu (N)", "S. Khurshid (T)"] 467 | }, 468 | { 469 | "name": "Omega", 470 | "type": "SMT" 471 | }, 472 | { 473 | "name": "UC-KLEE", 474 | "since": 2014, 475 | "type": "concolic", 476 | "languages": ["C", "C++"], 477 | "based": ["KLEE"], 478 | "authors": ["D. A. Ramos", "D. Engler"] 479 | }, 480 | { 481 | "name": "GSAT", 482 | "description": "stochastic local search", 483 | "paper": "gsat" 484 | }, 485 | { 486 | "name": "HAMPI", 487 | "type": "SMT", 488 | "description": "string constraints", 489 | "since": 2009 490 | }, 491 | { 492 | "name": "HTP", 493 | "type": "SMT" 494 | }, 495 | { 496 | "name": "Java ThreadSanitizer", 497 | "languages": ["Java bytecode"] 498 | }, 499 | { 500 | "name": "Jalangi", 501 | "languages": ["JavaScript"], 502 | "since": 2013, 503 | "type": "concolic", 504 | "authors": ["K. Sen (B)", "S. Kalasapur (S)", "..."] 505 | }, 506 | { 507 | "name": "Jalangi2", 508 | "languages": ["JavaScript"], 509 | "github": "Samsung/jalangi2" 510 | }, 511 | { 512 | "name": "Jat", 513 | "type": "SMT" 514 | }, 515 | { 516 | "name": "JBSE", 517 | "languages": ["Java"], 518 | "url": "http://pietrobraione.github.io/jbse/" 519 | }, 520 | { 521 | "name": "jCUTE", 522 | "since": 2006, 523 | "uses": [ 524 | "Soot", 525 | "lp_solve" 526 | ], 527 | "languages": ["Java"], 528 | "type": "concolic", 529 | "url": "http://osl.cs.illinois.edu/software/jcute/", 530 | "description": "concolic testing", 531 | "authors": ["K. Sen", "G.Agha"] 532 | }, 533 | { 534 | "name": "JDart", 535 | "languages": ["Java"], 536 | "github": "psycopaths/jdart", 537 | "since": 2016, 538 | "type": "concolic", 539 | "authors": ["K. Luckow (CM)", "M. Dimjašević (U)", "D. Giannakopoulou (N)", "..."] 540 | }, 541 | { 542 | "name": "jFuzz", 543 | "since": 2009, 544 | "languages": ["Java"], 545 | "url": "http://people.csail.mit.edu/akiezun/jfuzz/" 546 | }, 547 | { 548 | "name": "Fuzzgrind", 549 | "since": 2009, 550 | "based": ["Valgrind"], 551 | "uses": ["STP"], 552 | "authors": ["G. Campana"], 553 | "type": "concolic" 554 | }, 555 | { 556 | "name": "Key", 557 | "languages": ["Java"], 558 | "url": "https://www.key-project.org/" 559 | }, 560 | { 561 | "name": "Kite", 562 | "languages": ["LLVM bitcode"], 563 | "url": "http://www.cs.ubc.ca/labs/isd/Projects/Kite/" 564 | }, 565 | { 566 | "name": "KLEE", 567 | "since": 2008, 568 | "description": "online DSE,\nconstraint\noptimizations", 569 | "based": ["LLVM"], 570 | "languages": ["bitcode LLVM"], 571 | "url": "http://klee.github.io/", 572 | "type": "concolic", 573 | "authors": ["C. Cadar", "D. Dunbar", "D. Engler"] 574 | }, 575 | { 576 | "name": "Lean", 577 | "type": "SMT", 578 | "since": 2013, 579 | "authors": ["L. de Moura", "S. Kong"] 580 | }, 581 | { 582 | "name": "LESE", 583 | "description": "loop-based extended SE", 584 | "since": 2009, 585 | "languages": ["binary"], 586 | "type": "concolic", 587 | "authors": ["P. Saxena (B)", "S. McCamant (B)", "P. Poosankam (B, CM)", "D. Song (B)"] 588 | }, 589 | { 590 | "name": "LimeTB", 591 | "languages": ["Java"], 592 | "url": "http://www.tcs.hut.fi/Software/lime/" 593 | }, 594 | { 595 | "name": "", 596 | "id": "massachusetts.fortran", 597 | "since": 1976, 598 | "description": "test generation,\nsymbolic execution\n", 599 | "authors": [ 600 | "L. Clarke" 601 | ], 602 | "languages": ["Fortran"], 603 | "type": "concolic", 604 | "affiliation": [ 605 | "Massachusetts" 606 | ] 607 | }, 608 | { 609 | "name": "MathSAT", 610 | "type": "SMT", 611 | "languages": [ 612 | "SMT-LIB_2" 613 | ], 614 | "license": "proprietary", 615 | "os": [ 616 | "Linux", 617 | "macOs", 618 | "Windows" 619 | ], 620 | "api": [ 621 | "C", 622 | "C++", 623 | "Python" 624 | ] 625 | }, 626 | { 627 | "name": "Mayhem", 628 | "languages": ["binary"], 629 | "uses": [ 630 | "Pin", 631 | "BAP", 632 | "Z3" 633 | ], 634 | "since": 2012, 635 | "type": "concolic", 636 | "authors": ["D. Brumley", "..."], 637 | "description": "hybrid: online and\noffline DSE,\ndefect detection,\nexploit generation" 638 | }, 639 | { 640 | "name": "miasm", 641 | "languages": ["binary"], 642 | "github": "cea-sec/miasm" 643 | }, 644 | { 645 | "name": "MINESTRONE", 646 | "since": 2011, 647 | "based": ["KLEE"], 648 | "uses": ["Pin"], 649 | "languages": [ 650 | "C", 651 | "C++" 652 | ], 653 | "type": "concolic", 654 | "authors": ["A. D. Keromytis (C)", "S. J. Stolfo (C)", "Junfeng Yang (C)", "..."] 655 | }, 656 | { 657 | "name": "MiniSAT", 658 | "languages": ["DIMACS-CNF"], 659 | "type": "SAT", 660 | "since": 2003, 661 | "authors": ["N. Eén", "N. Sörensson"] 662 | }, 663 | { 664 | "name": "ExpliSAT", 665 | "since": 2007, 666 | "description": "formal verification,\nsymbolic execution", 667 | "authors": ["S. Barner (I)", "C. Eisner (I)", "..."], 668 | "type": "model checker", 669 | "uses": ["Mage"], 670 | "languages": ["C"] 671 | }, 672 | { 673 | "name": "MiniSMT", 674 | "type": "SMT" 675 | }, 676 | { 677 | "name": "Nort", 678 | "since": 2014, 679 | "url": "http://user.it.uu.se/~jarst116/norn/", 680 | "type": "SMT", 681 | "description": "string constraints" 682 | }, 683 | { 684 | "name": "MergePoint", 685 | "since": 2014, 686 | "description": "veritesting: switch\nbetween DSE\nand SSE", 687 | "languages": ["binary"], 688 | "type": "concolic", 689 | "authors": ["T. Avgerinos", "A. Rebert", "Sang Kil Cha", "D. Brumley"] 690 | }, 691 | { 692 | "name": "NuSMV", 693 | "type": "SMT" 694 | }, 695 | { 696 | "name": "OpenSMT", 697 | "type": "SMT", 698 | "languages": [ 699 | "Princess native language", 700 | "SMT-LIB_2", 701 | "TPTP" 702 | ] 703 | }, 704 | { 705 | "name": "Otter", 706 | "languages": ["C"], 707 | "bitbucket": "khooyp/otter", 708 | "since": 2011, 709 | "description": "directed SE", 710 | "uses": ["STP"], 711 | "authors": ["Kin-Keung Ma", "Khoo Yit Phang", "J. S. Foster", "..."], 712 | "type": "concolic" 713 | }, 714 | { 715 | "name": "SymDroid", 716 | "type": "concolic", 717 | "description": "for Dalvik", 718 | "uses": ["Z3"], 719 | "since": 2012, 720 | "authors": ["J. Jeon", "K. K. Micinski", "J. S. Foster"] 721 | }, 722 | { 723 | "name": "PathGrind", 724 | "languages": ["binary"], 725 | "github": "codelion/pathgrind", 726 | "since": 2014 727 | }, 728 | { 729 | "name": "Pex", 730 | "since": 2008, 731 | "languages": [".NET"], 732 | "url": "http://pex4fun.com/About.aspx", 733 | "uses": ["Z3"], 734 | "type": "concolic", 735 | "authors": ["N. Tillmann", "J. de Halleux"] 736 | }, 737 | { 738 | "name": "Rex", 739 | "type": "SMT", 740 | "uses": ["Z3"], 741 | "description": "regular expressions", 742 | "since": 2010, 743 | "authors": ["M. Veanes", "P. Halleux", "N. Tillmann"] 744 | }, 745 | { 746 | "name": "Rosette", 747 | "since": 2013, 748 | "languages": ["Rosette"], 749 | "description": "symbolic\nvirtual\nmachine", 750 | "type": "SMT", 751 | "authors": ["E. Torlak", "R. Bodik"] 752 | }, 753 | { 754 | "name": "PyExZ3", 755 | "languages": ["Python"], 756 | "github": "thomasjball/PyExZ3", 757 | "since": 2016, 758 | "type": "concolic", 759 | "authors": ["T. Ball", "J. Daniel"] 760 | }, 761 | { 762 | "name": "pysymemu", 763 | "languages": [ 764 | "x86", 765 | "x64" 766 | ], 767 | "github": "feliam/pysymemu" 768 | }, 769 | { 770 | "name": "Rubyx", 771 | "languages": ["Ruby"], 772 | "since": 2010, 773 | "uses": ["Drails", "Yices"], 774 | "authors": ["A. Chaudhuri", "J. S. Foster"], 775 | "type": "concolic" 776 | }, 777 | { 778 | "name": "S3", 779 | "type": "SMT", 780 | "based": ["Z3-str"], 781 | "description": "string solver", 782 | "authors": ["Y. Zheng (P)", "X. Zhang (P)", "V. Ganesh (W)"] 783 | }, 784 | { 785 | "name": "S3P", 786 | "type": "SMT", 787 | "based": ["Z3"], 788 | "description": "string solver, progressive S3P" 789 | }, 790 | { 791 | "name": "SAGE", 792 | "since": 2008, 793 | "languages": ["x86"], 794 | "description": "concolic, fuzzing", 795 | "uses": ["Z3"], 796 | "type": "concolic", 797 | "authors": ["P. Godefroid (M)", "D. Molnar (B)", "M. Levin (M)"] 798 | }, 799 | { 800 | "name": "SAGAN +\nJobCenter", 801 | "id": "SAGAN", 802 | "since": 2010, 803 | "based": ["SAGE"], 804 | "authors": ["P. Godefroid", "D. Molnar", "E. Bounimova"], 805 | "type": "concolic" 806 | }, 807 | { 808 | "name": "SELECT", 809 | "since": 1976, 810 | "description": "path constraints,\ntest generation,\nassertions check\n", 811 | "languages": ["Lisp"], 812 | "authors": [ 813 | "R. S. Boyer", 814 | "B. Elspas", 815 | "K. N. Levitt" 816 | ], 817 | "type": "concolic", 818 | "affiliations": [ 819 | "SRI" 820 | ] 821 | }, 822 | { 823 | "name": "SMART", 824 | "since": 2007, 825 | "type": "concolic" 826 | }, 827 | { 828 | "name": "S2E", 829 | "languages": ["binary"], 830 | "url": "http://s2e.epfl.ch/", 831 | "type": "concolic", 832 | "based": ["QEMU", "KLEE", "LLVM"], 833 | "since": 2011, 834 | "description": "selective symbolic,\nconcrete execution\nframework", 835 | "authors": ["G. Candea", "V. Kuznetsov", "V. Chipounov"] 836 | }, 837 | { 838 | "name": "STP", 839 | "paper": "stp", 840 | "since": 2007, 841 | "type": "SMT", 842 | "uses": ["MiniSAT"] 843 | }, 844 | { 845 | "name": "SPIN", 846 | "type": "model checker", 847 | "since": 1997, 848 | "affiliations": [ 849 | "Bell labs" 850 | ], 851 | "authors": [ 852 | "G. Holzmann" 853 | ] 854 | }, 855 | { 856 | "name": "Splat", 857 | "languages": ["C"], 858 | "since": 2008, 859 | "uses": ["STP"], 860 | "description": "symbolic length", 861 | "type": "concolic", 862 | "authors": ["Ru-Gang Xu (C)", "P. Godefroid (M)", "R. Majumdar (C)"] 863 | }, 864 | { 865 | "name": "SVC", 866 | "since": 1996, 867 | "description": "validity checker", 868 | "type": "SMT", 869 | "affiliations": "Stanford", 870 | "authors": ["C. W. Barrett", "D. L. Dill", "J. Levitt"] 871 | }, 872 | { 873 | "name": "Symbolic Java Pathfinder", 874 | "languages": ["Java"], 875 | "url": "https://babelfish.arc.nasa.gov/trac/jpf/wiki/projects/jpf-symbc" 876 | }, 877 | { 878 | "name": "SymJS", 879 | "languages": ["JavaScript"], 880 | "since": 2014, 881 | "authors": ["G. Li (F)", "E. Andreasen (A)", "..."], 882 | "type": "concolic" 883 | }, 884 | { 885 | "name": "ThreadSanitizer", 886 | "languages": [ 887 | "c", 888 | "cpp", 889 | "go" 890 | ], 891 | "based": ["Valgrind"] 892 | }, 893 | { 894 | "name": "Triton", 895 | "languages": ["x86", "x64"], 896 | "url": "https://triton.quarkslab.com/", 897 | "uses": ["Capstone", "Pin"], 898 | "authors": ["J. Salwan"], 899 | "description": "framework for DSE", 900 | "type": "concolic one path", 901 | "since": 2015 902 | }, 903 | { 904 | "name": "UC KLEE", 905 | "since": 2014, 906 | "based": ["KLEE"] 907 | }, 908 | { 909 | "name": "Valgrind", 910 | "paper": "valgrind", 911 | "description": "dynamic binary\ninstrumentator", 912 | "ir": ["VEX"], 913 | "since": 2000, 914 | "type": "dynamic instrumentation" 915 | }, 916 | { 917 | "name": "VeriSoft", 918 | "since": 1997, 919 | "type": "model checker", 920 | "authors": [ 921 | "P. Godefroid" 922 | ], 923 | "affiliations": [ 924 | "Bell labs" 925 | ] 926 | }, 927 | { 928 | "name": "WSAT", 929 | "alias": "Walksat", 930 | "description": "stochastic local search", 931 | "paper": "gsat" 932 | }, 933 | { 934 | "name": "Yices", 935 | "paper": "yices", 936 | "since": 2006, 937 | "type": "SMT", 938 | "description": "SMT solver" 939 | }, 940 | { 941 | "name": "Z3", 942 | "type": "SMT", 943 | "description": "SMT solver, SAT: DPLL", 944 | "since": 2008, 945 | "authors": ["L. de Moura", "N. Bjørner"] 946 | }, 947 | { 948 | "name": "Z3-str", 949 | "type": "SMT", 950 | "since": 2013 951 | }, 952 | { 953 | "name": "Z3str2", 954 | "type": "SMT", 955 | "since": 2017, 956 | "authors": ["Y. Zheng (I)", "X. Zhang (P)", "V. Ganesh (W)"] 957 | }, 958 | { 959 | "name": "Z3str3", 960 | "type": "SMT", 961 | "since": 2017, 962 | "authors": ["M. Berzish (W)", "Y. Zheng (I)", "V. Ganesh (W)"] 963 | }, 964 | { 965 | "name": "Chaff", 966 | "type": "SAT" 967 | }, 968 | { 969 | "name": "zChaff", 970 | "description": "SMT solver based on Chaff algorithm", 971 | "url": "http://www.princeton.edu/~chaff/zchaff.html", 972 | "type": "SMT", 973 | "since": 2001, 974 | "license": "free for noncommercial" 975 | }, 976 | { 977 | "name": "PathCrawler", 978 | "since": 2005, 979 | "languages": ["C"], 980 | "type": "concolic", 981 | "description": "limit loop iterations", 982 | "uses": ["CIL", "ECLIPSE"], 983 | "authors": ["N. Williams, B. Marre", "P. Mouy, M. Roger"] 984 | }, 985 | { 986 | "name": "GlassTT", 987 | "since": 2004, 988 | "type": "concolic", 989 | "languages": ["Java"], 990 | "description": "SJVM on top of\nJVM, analyze only\nmethod" 991 | }, 992 | { 993 | "name": "Peach", 994 | "since": 2000, 995 | "type": "fuzzer" 996 | }, 997 | { 998 | "name": "JNuke", 999 | "since": 2004, 1000 | "type": "model checker", 1001 | "languages": ["Java"] 1002 | }, 1003 | { 1004 | "name": "Autodafé", 1005 | "since": 2005, 1006 | "affiliations": ["EPFL"], 1007 | "type": "concolic" 1008 | }, 1009 | { 1010 | "name": "JPF-SE", 1011 | "languages": ["Java"], 1012 | "type": "concolic", 1013 | "since": 2007, 1014 | "authors": ["W. Visser (N)", "C. Păsăreanu (N)", "S. Anand (G)"] 1015 | }, 1016 | { 1017 | "name": "Symbolic\nPathFinder", 1018 | "id": "Symbolic_PathFinder", 1019 | "since": 2010, 1020 | "type": "concolic" 1021 | }, 1022 | { 1023 | "name": "Dytan", 1024 | "since": 2007, 1025 | "type": "concolic", 1026 | "authors": ["J. Clause", "W. Li", "A. Orso"] 1027 | }, 1028 | { 1029 | "name": "Pathgrind", 1030 | "since": 2014, 1031 | "type": "concolic", 1032 | "authors": ["A. Sharma"] 1033 | }, 1034 | { 1035 | "name": "Firmalice", 1036 | "since": 2015, 1037 | "type": "concolic", 1038 | "authors": ["Y. Shoshitaishvili", "R. Wang", "..."], 1039 | "description": "firmware auth.\nbypass, uses SA to\nextract CFG,\nDSE on slice" 1040 | }, 1041 | { 1042 | "name": "PIN", 1043 | "since": 2007, 1044 | "type": "dynamic instrumentation", 1045 | "authors": ["Chi-Keung Luk", "R. Cohn", "..."] 1046 | }, 1047 | { 1048 | "name": "Cinger", 1049 | "languages": ["Java"], 1050 | "type": "concolic", 1051 | "since": 2010, 1052 | "authors": ["S. Anand", "M. J. Harrold"] 1053 | }, 1054 | { 1055 | "name": "Green\nSolver", 1056 | "id": "Green_Solver", 1057 | "type": "SMT", 1058 | "since": 2012, 1059 | "authors": ["W. Visser (S)", "J. Geldenhuys (S)", "M. B. Dwyer (N)"], 1060 | "description": "permanent cache" 1061 | }, 1062 | { 1063 | "name": "AXGEN", 1064 | "type": "concolic one path", 1065 | "description": "exploit generation", 1066 | "languages": ["binary"], 1067 | "since": 2009, 1068 | "authors": ["S. Heelan"] 1069 | }, 1070 | { 1071 | "name": "Debugger", 1072 | "type": "static symbolic execution", 1073 | "authors": ["P. Sole", "S. Heelan"] 1074 | }, 1075 | { 1076 | "name": "ILLITHID", 1077 | "type": "static symbolic execution", 1078 | "authors": ["S. Heelan", "P. Sole", "R. Huizer"] 1079 | }, 1080 | { 1081 | "name": "DISSECT", 1082 | "since": 1977, 1083 | "authors": ["W. Howden"] 1084 | }, 1085 | { 1086 | "name": "Grammar-\nbased\nwhitebox\nfuzzing", 1087 | "id": "GrammarBased", 1088 | "since": 2008, 1089 | "type": "paper", 1090 | "authors": [ 1091 | "P. Godefroid", 1092 | "A. Kiezun", 1093 | "M. Y. Levin" 1094 | ] 1095 | }, 1096 | { 1097 | "name": "SMT-LIB", 1098 | "since": 2006, 1099 | "authors": ["S. Rainse (N)", "C. Tinelli (I)"], 1100 | "affiliations": ["Iowa", "Nancy"] 1101 | }, 1102 | { 1103 | "name": "SMT-\nLIB 2", 1104 | "id": "SMT-LIB_2", 1105 | "since": 2010, 1106 | "authors": ["C. Barrett (N)", "A. Stump", "C. Tinelli (I)"] 1107 | }, 1108 | { 1109 | "name": "Scaling Up\nDPLL(T)\nString Solvers", 1110 | "id": "ScalingUp", 1111 | "authors": ["M. Woo", "C. Barrett", "D. Brumley", "T. Liang", "..."], 1112 | "type": "paper", 1113 | "since": 2017 1114 | }, 1115 | { 1116 | "name": "Accelerating\nArray\nConstraints", 1117 | "id": "AcceleratingArray", 1118 | "authors": ["D. M. Perry", "A. Mattavelli", "X. Zhang", "C. Cadar"], 1119 | "type": "paper", 1120 | "since": 2017 1121 | }, 1122 | { 1123 | "name": "Catchconv", 1124 | "since": 2007, 1125 | "type": "concolic", 1126 | "uses": ["STP", "Valgrind"], 1127 | "authors": ["D. Molnar", "D. Wagner"] 1128 | }, 1129 | { 1130 | "name": "Replayer", 1131 | "since": 2006, 1132 | "description": "execution replay\nfor dialog program", 1133 | "authors": ["D. Brumley", "J. Newsome", "J. Franklin"], 1134 | "type": "concolic", 1135 | "uses": ["STP", "Valgrind"] 1136 | }, 1137 | { 1138 | "name": "Driller", 1139 | "uses": ["AFL", "angr", "VEX"], 1140 | "since": 2016, 1141 | "description": "hybrid fuzzing and\nDSE", 1142 | "authors": ["N. Stephens", "J. Grosen"], 1143 | "type": "concolic" 1144 | }, 1145 | { 1146 | "name": "Mechanical\nPhish", 1147 | "id": "Mechanical_Phish", 1148 | "description": "symbolic execution,\nfuzzing, binary\npatching", 1149 | "uses": ["AFL", "Patcherex", "Driller", "angr"], 1150 | "since": 2016, 1151 | "type": "concolic" 1152 | }, 1153 | { 1154 | "name": "lp_solve", 1155 | "type": "SMT" 1156 | }, 1157 | { 1158 | "name": "AFL", 1159 | "type": "fuzzer", 1160 | "since": 2014, 1161 | "authors": ["M. Zalewski"], 1162 | "description": "fuzzer\ngenetic algorithm" 1163 | }, 1164 | { 1165 | "name": "OSS-Fuzz", 1166 | "description": "fuzzer", 1167 | "languages": ["C", "C++"], 1168 | "type": "fuzzer", 1169 | "since": 2017, 1170 | "authors": ["K. Serebryany"] 1171 | }, 1172 | { 1173 | "name": "AFLFast", 1174 | "since": 2017, 1175 | "description": "coverage-based\ngreybox fuzzing,\nMarkov chains", 1176 | "based": ["AFL"], 1177 | "authors": ["M. Böhme", "Van-Thuan Pham", "..."], 1178 | "type": "fuzzer" 1179 | }, 1180 | { 1181 | "name": "Survey of\nTest Case\nGeneration", 1182 | "id": "SurveyTestCase", 1183 | "type": "paper", 1184 | "since": 2013, 1185 | "authors": ["S. Anand (S)", "E. Burke", "Tsong Yueh Chen", "J. Clark", "..."] 1186 | }, 1187 | { 1188 | "name": "MultiSE", 1189 | "since": 2015, 1190 | "authors": ["K. Sen", "G. Necula", "L. Gong", "W. Choi"], 1191 | "type": "paper" 1192 | }, 1193 | { 1194 | "name": "Kudzu", 1195 | "languages": ["JavaScript"], 1196 | "since": 2010, 1197 | "description": "symbolic\nexecution", 1198 | "type": "concolic", 1199 | "authors": ["P. Saxena, D. Akhawe", "S. Hanna, F. Mao", "S. McCamant, D. Song"] 1200 | } 1201 | ] 1202 | } --------------------------------------------------------------------------------