mirror of
https://github.com/l1ving/youtube-dl
synced 2020-11-18 19:53:54 -08:00
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
# coding: utf-8
|
|
from __future__ import unicode_literals
|
|
|
|
import base64
|
|
import subprocess
|
|
|
|
from ..utils import (
|
|
check_executable,
|
|
encodeArgument,
|
|
ExtractorError,
|
|
get_exe_version,
|
|
)
|
|
|
|
|
|
class NodejsWrapper(object):
|
|
"""Node.js wrapper class"""
|
|
|
|
@staticmethod
|
|
def version():
|
|
return get_exe_version('nodejs', version_re=r'([0-9.]+)')
|
|
|
|
def __init__(self):
|
|
self.exe = check_executable('nodejs', ['-v'])
|
|
if not self.exe:
|
|
raise ExtractorError('Node.js executable not found in PATH, '
|
|
'download it from http://nodejs.org',
|
|
expected=True)
|
|
|
|
def run_in_sandbox(self, jscode, timeout=10000):
|
|
"""
|
|
Executes JS in a sandbox
|
|
|
|
Params:
|
|
jscode: code to be executed
|
|
timeout: number of milliseconds before execution is cancelled
|
|
|
|
"""
|
|
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()
|
|
if p.returncode != 0:
|
|
raise ExtractorError(stderr.decode('utf-8', 'replace'))
|
|
return stdout.decode('utf-8')
|