Skip to content

Instantly share code, notes, and snippets.

@CherryDT
Last active March 29, 2020 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CherryDT/7ced888d73090e876e2e4c598715f88f to your computer and use it in GitHub Desktop.
Save CherryDT/7ced888d73090e876e2e4c598715f88f to your computer and use it in GitHub Desktop.
Example how to make an Elm program break from the outside

This is an example how we can break an Elm program from the outside by messing with its stuff in unexpected ways.

Compile using elm make Main.elm --output=main.js and open index.html in a browser.

Write something into the text field. The text will get reversed and on every character the counter counts up. Click the button and you'll see it counts up as well.

Looking at the Elm source file, this program can't crash or otherwise suddenly start to misbehave, right?

Well, let's see.

Now enter PWN3D into the text field.

From now on, the program is broken entirely. Writing any character will throw an uncaught error nope from inside Elm which you can see in the browser devtools.

Even worse, clicking the button will now cause Elm to emit a loop of uncaught errors many times a second.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Main</title>
<script src="main.js"></script>
</head>
<body>
<div id="elm"></div>
<script>
var app = Elm.Main.init({
node: document.getElementById('elm')
});
</script>
<script>
// I'm a rogue script!
document.querySelector('input').addEventListener('input', function () {
try {
if (this.value === 'PWN3D') {
Object.defineProperty(this, 'value', { get: () => { throw new Error('nope') } })
}
} catch (e) {}
})
</script>
</body>
</html>
-- from https://elm-lang.org/examples/text-fields
-- modified to include an additional counter
-- the counter will count up on any change of the text OR when clicking the button
import Browser
import Html exposing (Html, Attribute, div, input, button, text)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput, onClick)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model =
{ content : String,
updateCounter: Int
}
init : Model
init =
{ content = "",
updateCounter = 0
}
-- UPDATE
type Msg
= Change String | Count
update : Msg -> Model -> Model
update msg model =
case msg of
Change newContent ->
{ model | content = newContent, updateCounter = model.updateCounter + 1 }
Count ->
{ model | updateCounter = model.updateCounter + 1 }
-- VIEW
view : Model -> Html Msg
view model =
div []
[ div [] [ text "Enter text to reverse it and also count up, or click button to just count" ]
, input [ placeholder "Text to reverse", value model.content, onInput Change ] []
, button [ onClick Count ] [ text "Just count" ]
, div [] [ text (String.reverse model.content) ]
, div [] [ text (String.fromInt model.updateCounter) ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment