2016-03-20 15:54:58 +08:00
|
|
|
# coding: utf-8
|
2016-12-09 02:15:16 +08:00
|
|
|
from __future__ import unicode_literals
|
2016-11-05 05:00:09 +01:00
|
|
|
|
2019-12-06 05:49:03 +01:00
|
|
|
import base64
|
2017-09-24 00:08:27 +07:00
|
|
|
import subprocess
|
2017-01-25 23:27:22 +07:00
|
|
|
|
2016-03-20 16:49:44 +08:00
|
|
|
from ..utils import (
|
2017-09-24 00:08:27 +07:00
|
|
|
check_executable,
|
|
|
|
encodeArgument,
|
2016-03-20 16:49:44 +08:00
|
|
|
ExtractorError,
|
2017-09-24 00:08:27 +07:00
|
|
|
get_exe_version,
|
2016-03-20 16:49:44 +08:00
|
|
|
)
|
2016-03-20 15:54:58 +08:00
|
|
|
|
|
|
|
|
2019-12-06 05:49:03 +01:00
|
|
|
class NodejsWrapper(object):
|
|
|
|
"""Node.js wrapper class"""
|
2017-09-24 00:08:27 +07:00
|
|
|
|
|
|
|
@staticmethod
|
2019-12-06 05:49:03 +01:00
|
|
|
def version():
|
|
|
|
return get_exe_version('nodejs', version_re=r'([0-9.]+)')
|
2017-12-24 20:47:42 +08:00
|
|
|
|
2019-12-06 05:49:03 +01:00
|
|
|
def __init__(self):
|
|
|
|
self.exe = check_executable('nodejs', ['-v'])
|
2017-09-24 00:08:27 +07:00
|
|
|
if not self.exe:
|
2019-12-06 05:49:03 +01:00
|
|
|
raise ExtractorError('Node.js executable not found in PATH, '
|
|
|
|
'download it from http://nodejs.org',
|
2017-09-24 00:08:27 +07:00
|
|
|
expected=True)
|
|
|
|
|
2019-12-06 05:49:03 +01:00
|
|
|
def run_in_sandbox(self, jscode, timeout=10000):
|
2017-09-24 00:08:27 +07:00
|
|
|
"""
|
2019-12-06 05:49:03 +01:00
|
|
|
Executes JS in a sandbox
|
2017-09-24 00:08:27 +07:00
|
|
|
|
|
|
|
Params:
|
2019-12-06 05:49:03 +01:00
|
|
|
jscode: code to be executed
|
|
|
|
timeout: number of milliseconds before execution is cancelled
|
2017-09-24 00:08:27 +07:00
|
|
|
|
|
|
|
"""
|
2019-12-06 05:49:03 +01:00
|
|
|
jscode_wrapper = (
|
|
|
|
'const vm = require("vm");'
|
|
|
|
'const jscode = Buffer.from("{jscode_b64}", "base64").toString("binary");'
|
|
|
|
'const options = {{timeout: {timeout:d}}};'
|
|
|
|
'process.stdout.write(String(vm.runInNewContext(jscode, {{}}, options)));').format(
|
|
|
|
jscode_b64=base64.b64encode(jscode.encode('utf-8')).decode(),
|
|
|
|
timeout=timeout)
|
|
|
|
args = [encodeArgument(a) for a in [self.exe, '-e', jscode_wrapper]]
|
|
|
|
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
stdout, stderr = p.communicate()
|
2017-09-24 00:08:27 +07:00
|
|
|
if p.returncode != 0:
|
2019-12-06 05:49:03 +01:00
|
|
|
raise ExtractorError(stderr.decode('utf-8', 'replace'))
|
|
|
|
return stdout.decode('utf-8')
|