2017年5月2日火曜日

開発環境

メタプログラミングRuby 第2版(Paolo Perrotta (著)、角 征典 (翻訳)、オライリージャパン)の1部(メタプログラミング Ruby)、6章(金曜日: コードを記述するコード)、6.2(Kernel#eval)、6.2.1(アラウンドエイリアス)を JavaScript で取り組んでみる。

HTML5

<pre id="output0"></pre>
<button id="run0">run</button>
<button id="clear0">clear</button>

<script src="sample1.js"></script>

JavaScript

let btn0 = document.querySelector('#run0'),
    btn1 = document.querySelector('#clear0'),
    pre0 = document.querySelector('#output0'),
    p = (x) => pre0.textContent += x + '\n';

let Resource = () => {
    let that = {},
        get = (n) => `get ${n}`,
        post = (n) => `post ${n}`,
        put = (n) => `put ${n}`,
        del = (n) => `del ${n}`;

    that.get = get;
    that.post = post;
    that.put = put;
    that.del = del;

    return that;
};

let POSSIBLE_VERBS = ['get', 'put', 'post', 'del'],
    r = Resource();

POSSIBLE_VERBS.forEach((m) => {
    eval(`window.${m} = (...args) => r.${m}(...args);`);
});

let exploreArray = (method) => {
    let code = `['a', 'b', 'c'].${method};`
    p(`Evaluating: ${code}`);
    return eval(code);
};

let exploreArray1 = (method, ...args) =>
    Array.prototype[method].apply(['a', 'b', 'c'], args);

let output = () => {
    p('6.2 Kernel#eval');
    let array = [10, 20],
        element = 30;

    p(eval('array.push(element)'));
    p(eval('array.push(40); array'));

    p('6.2.1 REST Client の例');
    p(get(1));
    p(put(2));
    p(post(3));
    p(del(4));

    p('6.2.5 eval の問題点');
    p('コードインジェクション');
    p(exploreArray('indexOf("b")'));
    p(exploreArray('map((e) => String.fromCodePoint(e.codePointAt(0) + 1))'));

    p('コードインジェクションから身を守る');
    POSSIBLE_VERBS.forEach((m) => {
        window[m] = (...args) => {
            p('POSSIBLE_VERBS 2');

            return r[m](...args);
        };
    });
    p(get(1));
    p(put(2));
    p(post(3));
    p(del(4));

    p(exploreArray1('indexOf', 'b'));
    p(exploreArray1('map', (e) => String.fromCodePoint(e.codePointAt(0) + 1)));
};

btn0.onclick = output;
btn1.onclick = () => pre0.textContent = '';

output();




  








						

0 コメント:

コメントを投稿