Skip to content

Commit

Permalink
Fix #198 and #206 - quickjs crash
Browse files Browse the repository at this point in the history
  • Loading branch information
genotrance committed Feb 22, 2024
1 parent 30bd6e1 commit a3872b5
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ v0.9.1 - TBD
- Fixed issue with environment variables not propagating to all processes in Linux
- Documented how to install binary version of Px on Windows without running in a
console window - #203
- Fixed issue with quickjs crashing in PAC mode with multiple threads - #198 / #206

v0.9.0 - 2024-01-25
- Added support for domains in noproxy - #2
Expand Down
1 change: 0 additions & 1 deletion px/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import sys
import threading
import time
import traceback
import urllib.parse

from .debug import pprint, dprint, Debug
Expand Down
26 changes: 20 additions & 6 deletions px/pac.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import socket
import sys
import threading

try:
import quickjs
Expand All @@ -18,31 +19,42 @@
class Pac:
"Load and run PAC files using quickjs"

ctxt = None
_ctxt = None
_lock = None

def __init__(self, debug_print = None):
"Initialize a quickjs context with default PAC utility functions"
global dprint
if debug_print is not None:
dprint = debug_print

self.ctxt = quickjs.Context()
self._ctxt = quickjs.Context()
self._lock = threading.Lock()

dprint("Loading PAC utils")

# Load Python callables
for func in [self.alert, self.dnsResolve, self.myIpAddress]:
self.ctxt.add_callable(func.__name__, func)
self._ctxt.add_callable(func.__name__, func)

# Load PAC js utils
self.ctxt.eval(PACUTILS)
self._ctxt.eval(PACUTILS)

def __del__(self):
"Release quickjs context"
if self._lock is not None:
if self._ctxt is not None:
with self._lock:
self._ctxt = None
self._lock = None

def load(self, pac_data, pac_encoding):
"Load PAC data in specified encoding into this context"
pac_encoding = pac_encoding or "utf-8"
text = pac_data.decode(pac_encoding)
try:
self.ctxt.eval(text)
with self._lock:
self._ctxt.eval(text)
except quickjs.JSException as exc:
dprint(f"PAC file parsing failed - syntax error or file not encoded in {pac_encoding}")
dprint("Use --pac_encoding or proxy:pac_encoding in px.ini to change")
Expand Down Expand Up @@ -71,7 +83,9 @@ def find_proxy_for_url(self, url, host):
Return comma-separated list of proxy servers to use for this url
DIRECT can be returned as one of the options in the response
"""
proxies = self.ctxt.eval("FindProxyForURL")(url, host)
dprint(f"Finding proxy for {url}")
with self._lock:
proxies = self._ctxt.eval("FindProxyForURL")(url, host)

# Fix #160 - convert PAC return values into CURLOPT_PROXY schemes
for ptype in ["PROXY", "HTTP"]:
Expand Down

0 comments on commit a3872b5

Please sign in to comment.