Skip to content

Commit 62c20c6

Browse files
committed
Promote warnings to Error in SNMP extension
1 parent 1a8936c commit 62c20c6

10 files changed

+265
-184
lines changed

ext/snmp/snmp.c

+52-47
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,6 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
659659
*
660660
* OID parser (and type, value for SNMP_SET command)
661661
*/
662-
663662
static int php_snmp_parse_oid(
664663
zval *object, int st, struct objid_query *objid_query, zend_string *oid_str, HashTable *oid_ht,
665664
zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht
@@ -674,25 +673,33 @@ static int php_snmp_parse_oid(
674673
objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg));
675674
objid_query->vars[objid_query->count].oid = ZSTR_VAL(oid_str);
676675
if (st & SNMP_CMD_SET) {
677-
if (type_str && value_str) {
678-
if (ZSTR_LEN(type_str) != 1) {
679-
php_error_docref(NULL, E_WARNING, "Bogus type '%s', should be single char, got %zu", ZSTR_VAL(type_str), ZSTR_LEN(type_str));
680-
efree(objid_query->vars);
681-
return FALSE;
682-
}
683-
pptr = ZSTR_VAL(type_str);
684-
objid_query->vars[objid_query->count].type = *pptr;
685-
objid_query->vars[objid_query->count].value = ZSTR_VAL(value_str);
686-
} else {
687-
php_error_docref(NULL, E_WARNING, "Single objid and multiple type or values are not supported");
676+
if (type_ht) {
677+
zend_type_error("Type must be of type string when object ID is a string");
678+
efree(objid_query->vars);
679+
return FALSE;
680+
}
681+
if (value_ht) {
682+
zend_type_error("Value must be of type string when object ID is a string");
688683
efree(objid_query->vars);
689684
return FALSE;
690685
}
686+
687+
/* Both type and value must be valid strings */
688+
ZEND_ASSERT(type_str && value_str);
689+
690+
if (ZSTR_LEN(type_str) != 1) {
691+
zend_value_error("Type must be a single character");
692+
efree(objid_query->vars);
693+
return FALSE;
694+
}
695+
pptr = ZSTR_VAL(type_str);
696+
objid_query->vars[objid_query->count].type = *pptr;
697+
objid_query->vars[objid_query->count].value = ZSTR_VAL(value_str);
691698
}
692699
objid_query->count++;
693700
} else if (oid_ht) { /* we got objid array */
694701
if (zend_hash_num_elements(oid_ht) == 0) {
695-
php_error_docref(NULL, E_WARNING, "Got empty OID array");
702+
zend_value_error("Array of object IDs cannot be empty");
696703
return FALSE;
697704
}
698705
objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0);
@@ -715,7 +722,7 @@ static int php_snmp_parse_oid(
715722
if (idx_type < type_ht->nNumUsed) {
716723
convert_to_string_ex(tmp_type);
717724
if (Z_STRLEN_P(tmp_type) != 1) {
718-
php_error_docref(NULL, E_WARNING, "'%s': bogus type '%s', should be single char, got %zu", Z_STRVAL_P(tmp_oid), Z_STRVAL_P(tmp_type), Z_STRLEN_P(tmp_type));
725+
zend_value_error("Type must be a single character");
719726
efree(objid_query->vars);
720727
return FALSE;
721728
}
@@ -916,6 +923,7 @@ static int netsnmp_session_set_sec_level(struct snmp_session *s, char *level)
916923
} else if (!strcasecmp(level, "authPriv") || !strcasecmp(level, "ap")) {
917924
s->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
918925
} else {
926+
zend_value_error("Security level must be one of \"noAuthNoPriv\", \"authNoPriv\", or \"authPriv\"");
919927
return (-1);
920928
}
921929
return (0);
@@ -933,7 +941,7 @@ static int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot)
933941
s->securityAuthProto = usmHMACSHA1AuthProtocol;
934942
s->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
935943
} else {
936-
php_error_docref(NULL, E_WARNING, "Unknown authentication protocol '%s'", prot);
944+
zend_value_error("Authentication protocol must be either MD5 or SHA");
937945
return (-1);
938946
}
939947
return (0);
@@ -953,7 +961,11 @@ static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot)
953961
s->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
954962
#endif
955963
} else {
956-
php_error_docref(NULL, E_WARNING, "Unknown security protocol '%s'", prot);
964+
#ifdef HAVE_AES
965+
zend_value_error("Security protocol must be one of DES, AES128, or AES");
966+
#else
967+
zend_value_error("Security protocol must be DES");
968+
#endif
957969
return (-1);
958970
}
959971
return (0);
@@ -987,7 +999,7 @@ static int netsnmp_session_gen_sec_key(struct snmp_session *s, char *pass)
987999
(u_char *)pass, strlen(pass),
9881000
s->securityPrivKey, &(s->securityPrivKeyLen)))) {
9891001
php_error_docref(NULL, E_WARNING, "Error generating a key for privacy pass phrase '%s': %s", pass, snmp_api_errstring(snmp_errno));
990-
return (-2);
1002+
return (-1);
9911003
}
9921004
return (0);
9931005
}
@@ -1001,6 +1013,7 @@ static int netsnmp_session_set_contextEngineID(struct snmp_session *s, char * co
10011013
u_char *ebuf = (u_char *) emalloc(ebuf_len);
10021014

10031015
if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, contextEngineID)) {
1016+
// TODO Promote to Error?
10041017
php_error_docref(NULL, E_WARNING, "Bad engine ID value '%s'", contextEngineID);
10051018
efree(ebuf);
10061019
return (-1);
@@ -1023,15 +1036,15 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_
10231036

10241037
/* Setting the security level. */
10251038
if (netsnmp_session_set_sec_level(session, sec_level)) {
1026-
php_error_docref(NULL, E_WARNING, "Invalid security level '%s'", sec_level);
1039+
/* ValueError already generated, just bail out */
10271040
return (-1);
10281041
}
10291042

10301043
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
10311044

10321045
/* Setting the authentication protocol. */
10331046
if (netsnmp_session_set_auth_protocol(session, auth_protocol)) {
1034-
/* Warning message sent already, just bail out */
1047+
/* ValueError already generated, just bail out */
10351048
return (-1);
10361049
}
10371050

@@ -1044,7 +1057,7 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_
10441057
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
10451058
/* Setting the security protocol. */
10461059
if (netsnmp_session_set_sec_protocol(session, priv_protocol)) {
1047-
/* Warning message sent already, just bail out */
1060+
/* ValueError already generated, just bail out */
10481061
return (-1);
10491062
}
10501063

@@ -1220,9 +1233,9 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12201233
snmp_object = Z_SNMP_P(object);
12211234
session = snmp_object->session;
12221235
if (!session) {
1223-
php_error_docref(NULL, E_WARNING, "Invalid or uninitialized SNMP object");
1236+
zend_throw_error(NULL, "Invalid or uninitialized SNMP object");
12241237
efree(objid_query.vars);
1225-
RETURN_FALSE;
1238+
RETURN_THROWS();
12261239
}
12271240

12281241
if (snmp_object->max_oids > 0) {
@@ -1351,11 +1364,9 @@ PHP_FUNCTION(snmp_set_oid_output_format)
13511364
case NETSNMP_OID_OUTPUT_NONE:
13521365
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, a1);
13531366
RETURN_TRUE;
1354-
break;
13551367
default:
1356-
php_error_docref(NULL, E_WARNING, "Unknown SNMP output print format '%d'", (int) a1);
1357-
RETURN_FALSE;
1358-
break;
1368+
zend_argument_value_error(1, "must be an SNMP_OID_OUTPUT_* constant");
1369+
RETURN_THROWS();
13591370
}
13601371
}
13611372
/* }}} */
@@ -1443,8 +1454,8 @@ PHP_FUNCTION(snmp_set_valueretrieval)
14431454
SNMP_G(valueretrieval) = method;
14441455
RETURN_TRUE;
14451456
} else {
1446-
php_error_docref(NULL, E_WARNING, "Unknown SNMP value retrieval method '" ZEND_LONG_FMT "'", method);
1447-
RETURN_FALSE;
1457+
zend_argument_value_error(1, "must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT");
1458+
RETURN_THROWS();
14481459
}
14491460
}
14501461
/* }}} */
@@ -1827,48 +1838,46 @@ PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(exceptions_enabled)
18271838
/* {{{ */
18281839
static int php_snmp_write_info(php_snmp_object *snmp_object, zval *newval)
18291840
{
1830-
php_error_docref(NULL, E_WARNING, "info property is read-only");
1841+
zend_throw_error(NULL, "SNMP::$info property is read-only");
18311842
return FAILURE;
18321843
}
18331844
/* }}} */
18341845

18351846
/* {{{ */
18361847
static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval)
18371848
{
1838-
int ret = SUCCESS;
18391849
zend_long lval;
18401850

18411851
if (Z_TYPE_P(newval) == IS_NULL) {
18421852
snmp_object->max_oids = 0;
1843-
return ret;
1853+
return SUCCESS;
18441854
}
18451855

18461856
lval = zval_get_long(newval);
18471857

1848-
if (lval > 0) {
1849-
snmp_object->max_oids = lval;
1850-
} else {
1851-
php_error_docref(NULL, E_WARNING, "max_oids should be positive integer or NULL, got " ZEND_LONG_FMT, lval);
1858+
if (lval <= 0) {
1859+
zend_value_error("max_oids must be greater than 0 or null");
1860+
return FAILURE;
18521861
}
1862+
snmp_object->max_oids = lval;
18531863

1854-
return ret;
1864+
return SUCCESS;
18551865
}
18561866
/* }}} */
18571867

18581868
/* {{{ */
18591869
static int php_snmp_write_valueretrieval(php_snmp_object *snmp_object, zval *newval)
18601870
{
1861-
int ret = SUCCESS;
18621871
zend_long lval = zval_get_long(newval);
18631872

18641873
if (lval >= 0 && lval <= (SNMP_VALUE_LIBRARY|SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT)) {
18651874
snmp_object->valueretrieval = lval;
18661875
} else {
1867-
php_error_docref(NULL, E_WARNING, "Unknown SNMP value retrieval method '" ZEND_LONG_FMT "'", lval);
1868-
ret = FAILURE;
1876+
zend_value_error("SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT");
1877+
return FAILURE;
18691878
}
18701879

1871-
return ret;
1880+
return SUCCESS;
18721881
}
18731882
/* }}} */
18741883

@@ -1892,7 +1901,6 @@ PHP_SNMP_BOOL_PROPERTY_WRITER_FUNCTION(oid_increasing_check)
18921901
/* {{{ */
18931902
static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval *newval)
18941903
{
1895-
int ret = SUCCESS;
18961904
zend_long lval = zval_get_long(newval);
18971905

18981906
switch(lval) {
@@ -1903,14 +1911,11 @@ static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval *
19031911
case NETSNMP_OID_OUTPUT_UCD:
19041912
case NETSNMP_OID_OUTPUT_NONE:
19051913
snmp_object->oid_output_format = lval;
1906-
break;
1914+
return SUCCESS;
19071915
default:
1908-
php_error_docref(NULL, E_WARNING, "Unknown SNMP output print format '" ZEND_LONG_FMT "'", lval);
1909-
ret = FAILURE;
1910-
break;
1916+
zend_value_error("SNMP output print format must be an SNMP_OID_OUTPUT_* constant");
1917+
return FAILURE;
19111918
}
1912-
1913-
return ret;
19141919
}
19151920
/* }}} */
19161921

ext/snmp/tests/snmp-object-error.phpt

+27-17
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,35 @@ var_dump($session->close());
5454

5555
echo "Open normal session\n";
5656
$session = new SNMP(SNMP::VERSION_3, $hostname, $user_noauth, $timeout, $retries);
57-
$session->valueretrieval = 67;
58-
var_dump($session->valueretrieval);
57+
try {
58+
$session->valueretrieval = 67;
59+
var_dump($session->valueretrieval);
60+
} catch (\ValueError $e) {
61+
echo $e->getMessage() . \PHP_EOL;
62+
}
5963
echo "Closing session\n";
6064
var_dump($session->close());
61-
var_dump($session->get('.1.3.6.1.2.1.1.1.0'));
62-
var_dump($session->close());
65+
66+
try {
67+
var_dump($session->get('.1.3.6.1.2.1.1.1.0'));
68+
var_dump($session->close());
69+
} catch (\Error $e) {
70+
echo $e->getMessage() . \PHP_EOL;
71+
}
6372

6473
$session = new SNMP(SNMP::VERSION_2c, $hostname, $community, $timeout, $retries);
6574

6675
var_dump($session->max_oids);
67-
$session->max_oids = "ttt";
68-
$session->max_oids = 0;
76+
try {
77+
$session->max_oids = "ttt";
78+
} catch (\ValueError $e) {
79+
echo $e->getMessage() . \PHP_EOL;
80+
}
81+
try {
82+
$session->max_oids = 0;
83+
} catch (\ValueError $e) {
84+
echo $e->getMessage() . \PHP_EOL;
85+
}
6986
var_dump($session->max_oids);
7087
?>
7188
--EXPECTF--
@@ -81,18 +98,11 @@ int(32)
8198
string(46) "Invalid object identifier: .1.3.6.1.2.1.1.1..0"
8299
bool(true)
83100
Open normal session
84-
85-
Warning: main(): Unknown SNMP value retrieval method '67' in %s on line %d
86-
int(%d)
101+
SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT
87102
Closing session
88103
bool(true)
89-
90-
Warning: SNMP::get(): Invalid or uninitialized SNMP object in %s on line %d
91-
bool(false)
92-
bool(true)
104+
Invalid or uninitialized SNMP object
93105
NULL
94-
95-
Warning: main(): max_oids should be positive integer or NULL, got 0 in %s on line %d
96-
97-
Warning: main(): max_oids should be positive integer or NULL, got 0 in %s on line %d
106+
max_oids must be greater than 0 or null
107+
max_oids must be greater than 0 or null
98108
NULL

ext/snmp/tests/snmp-object-properties.phpt

+21-23
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,24 @@ $param = 'there is no such parameter';
5454
var_dump($session->$param);
5555
var_dump(property_exists($session, $param));
5656

57-
$session->valueretrieval = 67;
58-
var_dump($session->valueretrieval);
59-
$session->oid_output_format = 78;
60-
var_dump($session->oid_output_format);
61-
62-
$session->info = array("blah" => 2);
63-
var_dump($session->info);
57+
try {
58+
$session->valueretrieval = 67;
59+
var_dump($session->valueretrieval);
60+
} catch (\ValueError $e) {
61+
echo $e->getMessage() . \PHP_EOL;
62+
}
63+
try {
64+
$session->oid_output_format = 78;
65+
var_dump($session->oid_output_format);
66+
} catch (\ValueError $e) {
67+
echo $e->getMessage() . \PHP_EOL;
68+
}
69+
try {
70+
$session->info = array("blah" => 2);
71+
var_dump($session->info);
72+
} catch (\Error $e) {
73+
echo $e->getMessage() . \PHP_EOL;
74+
}
6475

6576
$session->max_oids = NULL;
6677
var_dump($session->max_oids);
@@ -179,20 +190,7 @@ Error handling
179190
Warning: Undefined property: SNMP::$there is no such parameter in %s on line %d
180191
NULL
181192
bool(false)
182-
183-
Warning: main(): Unknown SNMP value retrieval method '67' in %s on line %d
184-
int(1)
185-
186-
Warning: main(): Unknown SNMP output print format '78' in %s on line %d
187-
int(3)
188-
189-
Warning: main(): info property is read-only in %s on line %d
190-
array(3) {
191-
["hostname"]=>
192-
string(%d) "%s"
193-
["timeout"]=>
194-
int(%i)
195-
["retries"]=>
196-
int(%d)
197-
}
193+
SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT
194+
SNMP output print format must be an SNMP_OID_OUTPUT_* constant
195+
SNMP::$info property is read-only
198196
NULL

0 commit comments

Comments
 (0)