diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2017-01-26 18:03:50 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2017-01-26 20:32:24 +0000 |
commit | 20f7cfcbdab795b1730e3d1d14fc3833a7f5e705 (patch) | |
tree | baeeca30c453c642303496a131055f9be0da7c05 /src/network/kernel/qnetworkproxy_mac.cpp | |
parent | 6d5489f5df1220ac82d76bbee1f3caa93b34100d (diff) |
qnetworkproxy_mac - fix proxyAutoConfigCallback
We have an invalid pointer dereference in our callback.
Apple's docs are quite ambiguous, whatever we receive in our callback's
'client' parameter is our PACInfo, not clientContext's address.
That's what we pass to CFNetworkExecuteProxyAutoConfigurationURL:
"clientContext - A stream context containing a client info object and optionally
retain and release callbacks for that object."
This 'client info' is our PACInfo struct with 2 pointers.
Now in a callback, 'client':
"The client reference originally passed in the clientContext
parameter of the ..."
So apparently we should read this as "client info originally passed in ...."
Otherwise incorrect cast results in invalid pointer (apparently
the value of retain/release/copy pointers we carefully set to 0)
and a crash on dereference.
Task-number: QTBUG-56747
Change-Id: I89378f1582679638cd29a36c563e506d8f5af518
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
Diffstat (limited to 'src/network/kernel/qnetworkproxy_mac.cpp')
-rw-r--r-- | src/network/kernel/qnetworkproxy_mac.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp index c13a472b90..92f91956b9 100644 --- a/src/network/kernel/qnetworkproxy_mac.cpp +++ b/src/network/kernel/qnetworkproxy_mac.cpp @@ -189,12 +189,19 @@ struct PACInfo { void proxyAutoConfigCallback(void *client, CFArrayRef proxylist, CFErrorRef error) { - PACInfo *info = reinterpret_cast<PACInfo *>(reinterpret_cast<CFStreamClientContext *>(client)->info); + Q_ASSERT(client); + + PACInfo *info = static_cast<PACInfo *>(client); info->done = true; - if (proxylist) + + if (error) { + CFRetain(error); + info->error = error; + } + if (proxylist) { CFRetain(proxylist); - info->proxies = proxylist; - info->error = error; + info->proxies = proxylist; + } } } // anon namespace |