From cd0c6d5ff3577ee4b85a2d8b13dd7be7657b8eb6 Mon Sep 17 00:00:00 2001 From: Manu Garg Date: Mon, 29 Jun 2026 18:29:41 -0700 Subject: [PATCH] Document that the pacparser API is not thread-safe pacparser keeps all engine state in process-global variables and creates no threads of its own, so the API is single-instance and not thread-safe. Document the contract in the README and pacparser.h: callers must serialize all pacparser_* calls and must not call pacparser_cleanup() while another thread is in find_proxy()/parse_pac*(). Addresses GHSA-q2v4-fh98-357r. Co-Authored-By: Claude Opus 4.8 --- README.md | 14 ++++++++++++++ src/pacparser.h | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index b46c37f..cc82421 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,20 @@ manugarg@hobbiton:~$ ./pactest wpad.dat http://www.google.com www.google.com PROXY proxy1.manugarg.com:3128; PROXY proxy2.manugarg.com:3128; DIRECT ``` +#### Thread safety +pacparser keeps all of its JavaScript engine state (the QuickJS runtime and +context, the parsed PAC script, and the last result) in process-global +variables, and the library creates no threads of its own. The API is therefore +**not thread-safe**: there is a single, shared parser instance per process. + +If you use pacparser from a multi-threaded program, you must serialize **all** +calls into the library (`pacparser_init`, `pacparser_parse_pac*`, +`pacparser_find_proxy`, `pacparser_setmyip`, `pacparser_cleanup`, ...) with your +own lock. In particular, never call `pacparser_cleanup()` while another thread +is inside `pacparser_find_proxy()` or `pacparser_parse_pac*()`: cleanup frees +the QuickJS runtime/context that the other thread is still using, which crashes +the process (and is a use-after-free in builds compiled with `-DNDEBUG`). + #### Platforms pacparser has been tested to work on Linux (all architectures supported by Debian), FreeBSD, Mac OS X and Win32 systems. diff --git a/src/pacparser.h b/src/pacparser.h index e7f9f14..6be45a1 100644 --- a/src/pacparser.h +++ b/src/pacparser.h @@ -33,6 +33,15 @@ extern "C" { /// files. See project homepage: http://github.com/pacparser/pacparser /// for more information. /// @author Manu Garg +/// +/// @note **Thread safety:** pacparser keeps all engine state in process-global +/// variables and creates no threads of its own. The API is not +/// thread-safe; there is a single, shared parser instance per process. +/// Callers in multi-threaded programs must serialize all pacparser_* +/// calls with their own lock. In particular, do not call +/// pacparser_cleanup() while another thread is executing +/// pacparser_find_proxy() or pacparser_parse_pac*(): doing so frees +/// state that is still in use and crashes the process. /// @brief Initializes pac parser. /// @returns 0 on failure and 1 on success.