summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Catanzaro <mcatanzaro@gnome.org>2020-08-12 16:02:31 -0500
committerMichael Catanzaro <mcatanzaro@gnome.org>2020-09-10 14:53:56 -0500
commit89bb1053bed5c5ab21b51f037f8481b8f898961f (patch)
tree575f457cb9e541873bf2584f0f80013b5454cee3
parentcd619d3e9d683237f6317f979d5c6a7290d7e429 (diff)
downloadlibproxy-git-89bb1053bed5c5ab21b51f037f8481b8f898961f.tar.gz
Remove nonfunctional and crashy pacrunner caching
libproxy currently attempts to cache pacrunner objects in the pr member variable of its pacrunner_extension object. This is broken, though, because it relies on the pacrunner object also being stored in pacrunner_extension's last member variable, which is never written to. So that caching has never worked properly. In practice, it only does one thing: it causes a threadsafety bug, #68, because it causes the old pacrunner object to be deleted on the thread that is creating the new pacrunner, which is illegal for both the mozjs and WebKit-based pacrunner extensions that expect their objects to be deleted on the same thread they were created on. This patch was originally written by Dan Winship for Fedora 19. It got dropped in Fedora 24, then resurrected again for Fedora 28 after we noticed 30,000 crash reports. I've tweaked it a bit to completely remove the unused member variables. Finally, note that this code is not exception-safe: if an exception is thrown, the pacrunner could be leaked. But this seems to be a common problem throughout libproxy. It should be fixed by using std::unique_ptr instead of raw new and delete. https://bugzilla.redhat.com/show_bug.cgi?id=998232 Fixes #68
-rw-r--r--libproxy/extension_pacrunner.cpp10
-rw-r--r--libproxy/extension_pacrunner.hpp4
-rw-r--r--libproxy/proxy.cpp4
3 files changed, 4 insertions, 14 deletions
diff --git a/libproxy/extension_pacrunner.cpp b/libproxy/extension_pacrunner.cpp
index de2ea7b..698f25f 100644
--- a/libproxy/extension_pacrunner.cpp
+++ b/libproxy/extension_pacrunner.cpp
@@ -23,19 +23,11 @@ using namespace libproxy;
pacrunner::pacrunner(const string &, const url&) {}
pacrunner_extension::pacrunner_extension() {
- this->pr = NULL;
}
pacrunner_extension::~pacrunner_extension() {
- if (this->pr) delete this->pr;
}
pacrunner* pacrunner_extension::get(const string &pac, const url& pacurl) {
- if (this->pr) {
- if (this->last == pac)
- return this->pr;
- delete this->pr;
- }
-
- return this->pr = this->create(pac, pacurl);
+ return this->create(pac, pacurl);
}
diff --git a/libproxy/extension_pacrunner.hpp b/libproxy/extension_pacrunner.hpp
index eeb30f9..4834eb9 100644
--- a/libproxy/extension_pacrunner.hpp
+++ b/libproxy/extension_pacrunner.hpp
@@ -56,10 +56,6 @@ public:
protected:
// Abstract methods
virtual pacrunner* create(string pac, const url& pacurl) =0;
-
-private:
- pacrunner* pr;
- string last;
};
}
diff --git a/libproxy/proxy.cpp b/libproxy/proxy.cpp
index 2d01d53..af09e72 100644
--- a/libproxy/proxy.cpp
+++ b/libproxy/proxy.cpp
@@ -416,7 +416,9 @@ void proxy_factory::run_pac(url &realurl, const url &confurl, vector<string> &re
/* Run the PAC, but only try one PACRunner */
if (debug) cerr << "Using pacrunner: " << typeid(*pacrunners[0]).name() << endl;
- string pacresp = pacrunners[0]->get(this->pac, this->pacurl->to_string())->run(realurl);
+ pacrunner* runner = pacrunners[0]->get(this->pac, this->pacurl->to_string());
+ string pacresp = runner->run(realurl);
+ delete runner;
if (debug) cerr << "Pacrunner returned: " << pacresp << endl;
format_pac_response(pacresp, response);
}