[PECL-CVS] [pecl-web_services-oauth] fix-callback-exception-segfault: fixes #27
[email protected] (Rasmus Lerdorf) Sat, 4 Apr 2026 21:23:08 +0000
| Newsgroups | php.pecl.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Rasmus Lerdorf (rlerdorf)
Date: 2026-04-04T17:22:57-04:00
Commit: https://github.com/php/pecl-web_services-oauth/commit/d3ab35eba01b4eb1e5afc0f4f0fd0070d02342e3
Raw diff: https://github.com/php/pecl-web_services-oauth/commit/d3ab35eba01b4eb1e5afc0f4f0fd0070d02342e3.diff
fixes #27
Changed paths:
A tests/oauthprovider_009.phpt
M provider.c
M provider.h
Diff:
diff --git a/provider.c b/provider.c
index 9d54dca..d9808b7 100644
--- a/provider.c
+++ b/provider.c
@@ -383,6 +383,13 @@ static zval *oauth_provider_call_cb(INTERNAL_FUNCTION_PARAMETERS, int type) /* {
zval_ptr_dtor(&args);
+ /* If the callback threw an exception, return_value may be in an
+ * undefined state. Return NULL so callers don't try to use it.
+ * See issue #27. */
+ if (EG(exception)) {
+ return NULL;
+ }
+
return return_value;
}
/* }}} */
diff --git a/provider.h b/provider.h
index 90ec01a..a2b44cb 100644
--- a/provider.h
+++ b/provider.h
@@ -26,7 +26,12 @@
OAUTH_PROVIDER_COPY_ZVAL_FROM_PZVAL(dest, src, 0)
#define OAUTH_PROVIDER_CALL_CB(pt, m) \
- ZVAL_DUP(return_value, oauth_provider_call_cb(pt, m)); \
+ { \
+ zval *_cb_ret = oauth_provider_call_cb(pt, m); \
+ if (_cb_ret) { \
+ ZVAL_DUP(return_value, _cb_ret); \
+ } \
+ }
#define OAUTH_PROVIDER_FREE_FCALL_INFO(o) \
if(o) { \
diff --git a/tests/oauthprovider_009.phpt b/tests/oauthprovider_009.phpt
new file mode 100644
index 0000000..51e6e93
--- /dev/null
+++ b/tests/oauthprovider_009.phpt
@@ -0,0 +1,45 @@
+--TEST--
+OAuthProvider callback exception handling (issue #27)
+--SKIPIF--
+<?php
+if (!extension_loaded("oauth")) die("skip oauth extension not loaded");
+?>
+--FILE--
+<?php
+$params = [
+ "oauth_consumer_key" => "key",
+ "oauth_signature" => "sig",
+ "oauth_nonce" => "nonce",
+ "oauth_timestamp" => "12345"
+];
+
+$p = new OAuthProvider($params);
+$p->consumerHandler(function() { throw new RuntimeException("consumer exception"); });
+$p->tokenHandler(function() { throw new RuntimeException("token exception"); });
+$p->timestampNonceHandler(function() { throw new RuntimeException("nonce exception"); });
+
+try {
+ $p->callconsumerHandler();
+} catch (RuntimeException $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ $p->calltokenHandler();
+} catch (RuntimeException $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ $p->callTimestampNonceHandler();
+} catch (RuntimeException $e) {
+ echo $e->getMessage() . "\n";
+}
+
+echo "OK\n";
+?>
+--EXPECT--
+consumer exception
+token exception
+nonce exception
+OK