Skip to content
This repository was archived by the owner on Dec 9, 2025. It is now read-only.

Commit d9edc7c

Browse files
committed
New feature: obfuscated code can be evaluated and its console.log calls are displayed.
1 parent 74fba92 commit d9edc7c

4 files changed

Lines changed: 140 additions & 16 deletions

File tree

App/containers/CodeContainer.js

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import React, { Component } from 'react';
22

33
import { connect } from 'react-redux';
44

5-
import { Form, Segment, Button, Icon } from 'semantic-ui-react';
5+
import { Form, Grid, Segment, Button, Icon } from 'semantic-ui-react';
66

77
import classNames from 'classnames';
88
import Dropzone from 'react-dropzone';
9+
import prettyFormat from 'pretty-format';
910

1011
import EditorContainer from '../containers/EditorContainer';
1112

@@ -33,7 +34,10 @@ class CodeContainer extends Component {
3334
super(props);
3435
this.state = {
3536
selectedTabIndex: TAB_CODE,
37+
evaluate: false,
38+
evaluatedResult: '',
3639
}
40+
this.capturingConsole = null;
3741
}
3842

3943
componentWillReceiveProps(nextProps) {
@@ -42,6 +46,10 @@ class CodeContainer extends Component {
4246
selectedTabIndex: TAB_RESULTS,
4347
})
4448
}
49+
50+
if (this.state.evaluate) {
51+
this.evaluate(nextProps.obfuscatedCode);
52+
}
4553
}
4654

4755
onTabClick(index) {
@@ -62,6 +70,64 @@ class CodeContainer extends Component {
6270

6371
}
6472

73+
toggleEvaluate = () => {
74+
const nextEvaluate = !this.state.evaluate;
75+
76+
this.setState({
77+
evaluate: nextEvaluate,
78+
});
79+
80+
if (nextEvaluate) {
81+
this.evaluate(this.props.obfuscatedCode);
82+
}
83+
84+
}
85+
86+
// from https://github.com/babel/babel.github.io/blob/e7d082e4d545a75d7aa29b1df580c86114ab1586/scripts/7.js#L361
87+
evaluate (code) {
88+
this.capturingConsole = Object.create(console);
89+
const capturingConsole = this.capturingConsole;
90+
let buffer = [];
91+
var done = false;
92+
93+
const self = this;
94+
95+
function flush() {
96+
self.setState({
97+
evaluatedResult: buffer.join('\n'),
98+
})
99+
}
100+
101+
function write(data) {
102+
buffer.push(data);
103+
if (done) flush();
104+
}
105+
106+
function capture() {
107+
const logs = [].map.call(arguments, (log) => {
108+
return prettyFormat(log);
109+
});
110+
write(logs.join('\n'));
111+
}
112+
113+
['error', 'log', 'info', 'debug'].forEach(function(key) {
114+
capturingConsole[key] = function() {
115+
Function.prototype.apply.call(console[key], console, arguments);
116+
capture.apply(this, arguments);
117+
};
118+
});
119+
120+
try {
121+
new Function('console', code)(capturingConsole);
122+
} catch (err) {
123+
buffer.push(err.message);
124+
}
125+
126+
done = true;
127+
flush();
128+
129+
}
130+
65131
render() {
66132
const tabIndex = this.state.selectedTabIndex;
67133

@@ -113,21 +179,43 @@ class CodeContainer extends Component {
113179
onFocus={(event) => event.target.select()}
114180
></Form.TextArea>
115181
</Form>
116-
<Segment basic>
117-
<Button
118-
disabled={!hasObfuscatedCode}
119-
onClick={onDownloadCodeClick}
120-
>
121-
<Icon name='download' /> Download obfuscated code
122-
</Button>
123-
{ hasSourceMap &&
124-
<Button
125-
onClick={onDownloadSourceMapClick}
126-
>
127-
<Icon name='download' /> Download source map file
128-
</Button>
129-
}
130-
</Segment>
182+
183+
<Grid columns={2} relaxed>
184+
<Grid.Column width={13}>
185+
<Segment basic>
186+
<Button
187+
disabled={!hasObfuscatedCode}
188+
onClick={onDownloadCodeClick}
189+
>
190+
<Icon name='download' /> Download obfuscated code
191+
</Button>
192+
{ hasSourceMap &&
193+
<Button
194+
onClick={onDownloadSourceMapClick}
195+
>
196+
<Icon name='download' /> Download source map file
197+
</Button>
198+
}
199+
</Segment>
200+
</Grid.Column>
201+
202+
<Grid.Column width={3}>
203+
<Segment basic>
204+
<Form.Checkbox
205+
label='Evaluate'
206+
checked={this.state.evaluate}
207+
onChange={this.toggleEvaluate} />
208+
</Segment>
209+
</Grid.Column>
210+
</Grid>
211+
212+
{this.state.evaluate &&
213+
<Segment basic>
214+
<div className="evaluatedCode">
215+
{this.state.evaluatedResult}
216+
</div>
217+
</Segment>
218+
}
131219
</Pane>
132220

133221
</div>

App/styles/main.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,12 @@ code {
3030
padding: 0.2em;
3131
background-color: rgba(0,0,0,0.04);
3232
border-radius: 3px;
33+
}
34+
35+
.evaluatedCode {
36+
white-space: pre;
37+
padding: 0.2em;
38+
background-color: rgba(0,0,0,0.04);
39+
overflow: auto;
40+
max-height: 200px;
3341
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"javascript-obfuscator": "^0.10.0",
3434
"less": "^2.7.1",
3535
"less-loader": "^2.2.3",
36+
"pretty-format": "^20.0.3",
3637
"react": "^15.3.1",
3738
"react-codemirror": "^0.2.6",
3839
"react-dom": "^15.3.1",

yarn.lock

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ ansi-regex@^2.0.0:
6767
version "2.0.0"
6868
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107"
6969

70+
ansi-regex@^2.1.1:
71+
version "2.1.1"
72+
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
73+
7074
ansi-regex@^3.0.0:
7175
version "3.0.0"
7276
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
@@ -75,6 +79,12 @@ ansi-styles@^2.2.1:
7579
version "2.2.1"
7680
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
7781

82+
ansi-styles@^3.0.0:
83+
version "3.2.0"
84+
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
85+
dependencies:
86+
color-convert "^1.9.0"
87+
7888
anymatch@^1.3.0:
7989
version "1.3.0"
8090
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@@ -1236,10 +1246,20 @@ color-convert@^1.3.0:
12361246
version "1.5.0"
12371247
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.5.0.tgz#7a2b4efb4488df85bca6443cb038b7100fbe7de1"
12381248

1249+
color-convert@^1.9.0:
1250+
version "1.9.0"
1251+
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
1252+
dependencies:
1253+
color-name "^1.1.1"
1254+
12391255
color-name@^1.0.0:
12401256
version "1.1.1"
12411257
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
12421258

1259+
color-name@^1.1.1:
1260+
version "1.1.3"
1261+
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
1262+
12431263
color-string@^0.3.0:
12441264
version "0.3.0"
12451265
resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991"
@@ -3514,6 +3534,13 @@ preserve@^0.2.0:
35143534
version "0.2.0"
35153535
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
35163536

3537+
pretty-format:
3538+
version "20.0.3"
3539+
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14"
3540+
dependencies:
3541+
ansi-regex "^2.1.1"
3542+
ansi-styles "^3.0.0"
3543+
35173544
private@^0.1.6, private@~0.1.5:
35183545
version "0.1.6"
35193546
resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1"

0 commit comments

Comments
 (0)