@@ -655,7 +655,8 @@ static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid
655655*/
656656static bool php_snmp_parse_oid (
657657 zval * object , int st , struct objid_query * objid_query , zend_string * oid_str , HashTable * oid_ht ,
658- zend_string * type_str , HashTable * type_ht , zend_string * value_str , HashTable * value_ht
658+ zend_string * type_str , HashTable * type_ht , zend_string * value_str , HashTable * value_ht ,
659+ uint32_t oid_argument_offset , uint32_t type_argument_offset , uint32_t value_argument_offset
659660) {
660661 char * pptr ;
661662 uint32_t idx_type = 0 , idx_value = 0 ;
@@ -682,7 +683,7 @@ static bool php_snmp_parse_oid(
682683 ZEND_ASSERT (type_str && value_str );
683684
684685 if (ZSTR_LEN (type_str ) != 1 ) {
685- zend_value_error ( "Type must be a single character" );
686+ zend_argument_value_error ( type_argument_offset , " must be a single character" );
686687 efree (objid_query -> vars );
687688 return false;
688689 }
@@ -693,7 +694,7 @@ static bool php_snmp_parse_oid(
693694 objid_query -> count ++ ;
694695 } else if (oid_ht ) { /* we got objid array */
695696 if (zend_hash_num_elements (oid_ht ) == 0 ) {
696- zend_value_error ( "Array of object IDs must not be empty" );
697+ zend_argument_value_error ( oid_argument_offset , " must not be empty when passed as an array " );
697698 return false;
698699 }
699700 objid_query -> vars = (snmpobjarg * )safe_emalloc (sizeof (snmpobjarg ), zend_hash_num_elements (oid_ht ), 0 );
@@ -738,14 +739,14 @@ static bool php_snmp_parse_oid(
738739 char ptype = * ZSTR_VAL (type );
739740 zend_string_release (type );
740741 if (len != 1 ) {
741- zend_value_error ( "Type must be a single character" );
742+ zend_argument_value_error ( type_argument_offset , " must be a single character" );
742743 php_free_objid_query (objid_query , oid_ht , value_ht , st );
743744 return false;
744745 }
745746 objid_query -> vars [objid_query -> count ].type = ptype ;
746747 idx_type ++ ;
747748 } else {
748- php_error_docref ( NULL , E_WARNING , "'%s': no type set " , ZSTR_VAL (tmp ));
749+ zend_argument_value_error ( type_argument_offset , "must contain a type for object ID '%s' " , ZSTR_VAL (tmp ));
749750 php_free_objid_query (objid_query , oid_ht , value_ht , st );
750751 return false;
751752 }
@@ -780,7 +781,7 @@ static bool php_snmp_parse_oid(
780781 objid_query -> vars [objid_query -> count ].value = ZSTR_VAL (tmp );
781782 idx_value ++ ;
782783 } else {
783- php_error_docref ( NULL , E_WARNING , "'%s': no value set " , ZSTR_VAL (tmp ));
784+ zend_argument_value_error ( value_argument_offset , "must contain a value for object ID '%s' " , ZSTR_VAL (tmp ));
784785 php_free_objid_query (objid_query , oid_ht , value_ht , st );
785786 return false;
786787 }
@@ -827,7 +828,7 @@ static bool php_snmp_parse_oid(
827828/* {{{ snmp_session_init
828829 allocates memory for session and session->peername, caller should free it manually using snmp_session_free() and efree()
829830*/
830- static bool snmp_session_init (php_snmp_session * * session_p , int version , zend_string * hostname , zend_string * community , zend_long timeout , zend_long retries , int timeout_argument_offset )
831+ static bool snmp_session_init (php_snmp_session * * session_p , int version , zend_string * hostname , zend_string * community , zend_long timeout , zend_long retries , int hostname_argument_offset , int timeout_argument_offset )
831832{
832833 php_snmp_session * session ;
833834 char * pptr , * host_ptr ;
@@ -841,23 +842,13 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st
841842 ZEND_ASSERT (hostname != NULL );
842843 ZEND_ASSERT (community != NULL );
843844
844- if (zend_str_has_nul_byte (hostname )) {
845- zend_argument_value_error (2 , "must not contain any null bytes" );
846- return false;
847- }
848-
849845 if (ZSTR_LEN (hostname ) >= MAX_NAME_LEN ) {
850- zend_argument_value_error (2 , "length must be lower than %d" , MAX_NAME_LEN );
851- return false;
852- }
853-
854- if (zend_str_has_nul_byte (community )) {
855- zend_argument_value_error (3 , "must not contain any null bytes" );
846+ zend_argument_value_error (hostname_argument_offset , "length must be lower than %d" , MAX_NAME_LEN );
856847 return false;
857848 }
858849
859850 if (ZSTR_LEN (community ) == 0 ) {
860- zend_argument_must_not_be_empty_error (3 );
851+ zend_argument_must_not_be_empty_error (hostname_argument_offset + 1 );
861852 return false;
862853 }
863854
@@ -899,22 +890,22 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st
899890 char * pport = pptr + 2 ;
900891 tmp_port = atoi (pport );
901892 if (tmp_port < 0 || tmp_port > USHRT_MAX ) {
902- zend_argument_value_error (2 , "remote port must be between 0 and %u" , USHRT_MAX );
893+ zend_argument_value_error (hostname_argument_offset , "remote port must be between 0 and %u" , USHRT_MAX );
903894 return false;
904895 }
905896 remote_port = (unsigned short )tmp_port ;
906897 }
907898 * pptr = '\0' ;
908899 } else {
909- php_error_docref ( NULL , E_WARNING , "Malformed IPv6 address, closing square bracket missing" );
900+ zend_argument_value_error ( hostname_argument_offset , "has a malformed IPv6 address, closing square bracket missing" );
910901 return false;
911902 }
912903 } else { /* IPv4 address */
913904 if ((pptr = strchr (host_ptr , ':' ))) {
914905 char * pport = pptr + 1 ;
915906 tmp_port = atoi (pport );
916907 if (tmp_port < 0 || tmp_port > USHRT_MAX ) {
917- zend_argument_value_error (2 , "remote port must be between 0 and %u" , USHRT_MAX );
908+ zend_argument_value_error (hostname_argument_offset , "remote port must be between 0 and %u" , USHRT_MAX );
918909 return false;
919910 }
920911 remote_port = (unsigned short )tmp_port ;
@@ -1123,14 +1114,13 @@ static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_sec_key(struct snmp_session
11231114/* }}} */
11241115
11251116/* {{{ Set context Engine Id in the snmpv3 session */
1126- static bool snmp_session_set_contextEngineID (struct snmp_session * s , zend_string * contextEngineID )
1117+ static bool snmp_session_set_contextEngineID (struct snmp_session * s , zend_string * contextEngineID , uint32_t contextEngineID_argument_offset )
11271118{
11281119 size_t ebuf_len = 32 , eout_len = 0 ;
11291120 uint8_t * ebuf = (uint8_t * ) emalloc (ebuf_len );
11301121
11311122 if (!snmp_hex_to_binary (& ebuf , & ebuf_len , & eout_len , 1 , ZSTR_VAL (contextEngineID ))) {
1132- // TODO Promote to Error?
1133- php_error_docref (NULL , E_WARNING , "Bad engine ID value '%s'" , ZSTR_VAL (contextEngineID ));
1123+ zend_argument_value_error (contextEngineID_argument_offset , "must be a valid context engine ID" );
11341124 efree (ebuf );
11351125 return false;
11361126 }
@@ -1145,11 +1135,14 @@ static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string
11451135}
11461136/* }}} */
11471137
1148- /* {{{ Set all snmpv3-related security options */
1138+ /* {{{ Set all snmpv3-related security options
1139+ * auth_protocol_argnum and contextEngineID_argument_offset are the userland
1140+ * argument numbers used for error reporting.
1141+ */
11491142static ZEND_ATTRIBUTE_NONNULL_ARGS (2 ) bool snmp_session_set_security (struct snmp_session * session , zend_string * sec_level ,
11501143 zend_string * auth_protocol , zend_string * auth_passphrase , zend_string * priv_protocol ,
11511144 zend_string * priv_passphrase , zend_string * contextName , zend_string * contextEngineID ,
1152- uint32_t auth_protocol_argnum )
1145+ uint32_t auth_protocol_argnum , uint32_t contextEngineID_argument_offset )
11531146{
11541147
11551148 /* Setting the security level. */
@@ -1215,7 +1208,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp
12151208 }
12161209
12171210 /* Setting contextEngineIS if specified */
1218- if (contextEngineID && ZSTR_LEN (contextEngineID ) && !snmp_session_set_contextEngineID (session , contextEngineID )) {
1211+ if (contextEngineID && ZSTR_LEN (contextEngineID ) && !snmp_session_set_contextEngineID (session , contextEngineID , contextEngineID_argument_offset )) {
12191212 /* Warning message sent already, just bail out */
12201213 return false;
12211214 }
@@ -1243,6 +1236,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12431236 php_snmp_session * session ;
12441237 int session_less_mode = (getThis () == NULL );
12451238 int timeout_argument_offset = -1 ;
1239+ uint32_t oid_argument_offset = 1 , type_argument_offset = 0 , value_argument_offset = 0 ;
12461240 php_snmp_object * snmp_object ;
12471241 php_snmp_object glob_snmp_object ;
12481242
@@ -1255,8 +1249,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12551249 if (version == SNMP_VERSION_3 ) {
12561250 if (st & SNMP_CMD_SET ) {
12571251 ZEND_PARSE_PARAMETERS_START (10 , 12 )
1258- Z_PARAM_STR (a1 )
1259- Z_PARAM_STR (a2 )
1252+ Z_PARAM_PATH_STR (a1 )
1253+ Z_PARAM_PATH_STR (a2 )
12601254 Z_PARAM_STR (a3 )
12611255 Z_PARAM_STR (a4 )
12621256 Z_PARAM_STR (a5 )
@@ -1271,14 +1265,17 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12711265 ZEND_PARSE_PARAMETERS_END ();
12721266
12731267 timeout_argument_offset = 10 ;
1268+ oid_argument_offset = 8 ;
1269+ type_argument_offset = 9 ;
1270+ value_argument_offset = 10 ;
12741271 } else {
12751272 /* SNMP_CMD_GET
12761273 * SNMP_CMD_GETNEXT
12771274 * SNMP_CMD_WALK
12781275 */
12791276 ZEND_PARSE_PARAMETERS_START (8 , 10 )
1280- Z_PARAM_STR (a1 )
1281- Z_PARAM_STR (a2 )
1277+ Z_PARAM_PATH_STR (a1 )
1278+ Z_PARAM_PATH_STR (a2 )
12821279 Z_PARAM_STR (a3 )
12831280 Z_PARAM_STR (a4 )
12841281 Z_PARAM_STR (a5 )
@@ -1291,12 +1288,13 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12911288 ZEND_PARSE_PARAMETERS_END ();
12921289
12931290 timeout_argument_offset = 9 ;
1291+ oid_argument_offset = 8 ;
12941292 }
12951293 } else {
12961294 if (st & SNMP_CMD_SET ) {
12971295 ZEND_PARSE_PARAMETERS_START (5 , 7 )
1298- Z_PARAM_STR (a1 )
1299- Z_PARAM_STR (a2 )
1296+ Z_PARAM_PATH_STR (a1 )
1297+ Z_PARAM_PATH_STR (a2 )
13001298 Z_PARAM_ARRAY_HT_OR_STR (oid_ht , oid_str )
13011299 Z_PARAM_ARRAY_HT_OR_STR (type_ht , type_str )
13021300 Z_PARAM_ARRAY_HT_OR_STR (value_ht , value_str )
@@ -1306,21 +1304,25 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13061304 ZEND_PARSE_PARAMETERS_END ();
13071305
13081306 timeout_argument_offset = 6 ;
1307+ oid_argument_offset = 3 ;
1308+ type_argument_offset = 4 ;
1309+ value_argument_offset = 5 ;
13091310 } else {
13101311 /* SNMP_CMD_GET
13111312 * SNMP_CMD_GETNEXT
13121313 * SNMP_CMD_WALK
13131314 */
13141315 ZEND_PARSE_PARAMETERS_START (3 , 5 )
1315- Z_PARAM_STR (a1 )
1316- Z_PARAM_STR (a2 )
1316+ Z_PARAM_PATH_STR (a1 )
1317+ Z_PARAM_PATH_STR (a2 )
13171318 Z_PARAM_ARRAY_HT_OR_STR (oid_ht , oid_str )
13181319 Z_PARAM_OPTIONAL
13191320 Z_PARAM_LONG (timeout )
13201321 Z_PARAM_LONG (retries )
13211322 ZEND_PARSE_PARAMETERS_END ();
13221323
13231324 timeout_argument_offset = 4 ;
1325+ oid_argument_offset = 3 ;
13241326 }
13251327 }
13261328 } else {
@@ -1330,6 +1332,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13301332 Z_PARAM_ARRAY_HT_OR_STR (type_ht , type_str )
13311333 Z_PARAM_ARRAY_HT_OR_STR (value_ht , value_str )
13321334 ZEND_PARSE_PARAMETERS_END ();
1335+ type_argument_offset = 2 ;
1336+ value_argument_offset = 3 ;
13331337 } else if (st & SNMP_CMD_WALK ) {
13341338 ZEND_PARSE_PARAMETERS_START (1 , 4 )
13351339 Z_PARAM_ARRAY_HT_OR_STR (oid_ht , oid_str )
@@ -1359,20 +1363,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13591363 }
13601364 }
13611365
1362- if (!php_snmp_parse_oid (getThis (), st , & objid_query , oid_str , oid_ht , type_str , type_ht , value_str , value_ht )) {
1366+ if (!php_snmp_parse_oid (getThis (), st , & objid_query , oid_str , oid_ht , type_str , type_ht , value_str , value_ht ,
1367+ oid_argument_offset , type_argument_offset , value_argument_offset )) {
13631368 RETURN_FALSE ;
13641369 }
13651370
13661371 if (session_less_mode ) {
1367- if (!snmp_session_init (& session , version , a1 , a2 , timeout , retries , timeout_argument_offset )) {
1372+ if (!snmp_session_init (& session , version , a1 , a2 , timeout , retries , 1 , timeout_argument_offset )) {
13681373 php_free_objid_query (& objid_query , oid_ht , value_ht , st );
13691374 snmp_session_free (& session );
13701375 RETURN_FALSE ;
13711376 }
1372- if (version == SNMP_VERSION_3 && !snmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL , 4 )) {
1377+ if (version == SNMP_VERSION_3 && !snmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL , 4 , 0 )) {
13731378 php_free_objid_query (& objid_query , oid_ht , value_ht , st );
13741379 snmp_session_free (& session );
1375- /* Warning message sent already, just bail out */
1380+ /* An error has already been emitted , just bail out. */
13761381 RETURN_FALSE ;
13771382 }
13781383 } else {
@@ -1645,7 +1650,7 @@ PHP_METHOD(SNMP, __construct)
16451650
16461651 snmp_object = Z_SNMP_P (object );
16471652
1648- if (zend_parse_parameters (ZEND_NUM_ARGS (), "lSS |ll" , & version , & a1 , & a2 , & timeout , & retries ) == FAILURE ) {
1653+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "lPP |ll" , & version , & a1 , & a2 , & timeout , & retries ) == FAILURE ) {
16491654 RETURN_THROWS ();
16501655 }
16511656
@@ -1664,7 +1669,7 @@ PHP_METHOD(SNMP, __construct)
16641669 snmp_session_free (& (snmp_object -> session ));
16651670 }
16661671
1667- if (!snmp_session_init (& (snmp_object -> session ), version , a1 , a2 , timeout , retries , 4 )) {
1672+ if (!snmp_session_init (& (snmp_object -> session ), version , a1 , a2 , timeout , retries , 2 , 4 )) {
16681673 return ;
16691674 }
16701675 snmp_object -> max_oids = 0 ;
@@ -1738,8 +1743,9 @@ PHP_METHOD(SNMP, setSecurity)
17381743 RETURN_THROWS ();
17391744 }
17401745
1741- if (!snmp_session_set_security (snmp_object -> session , a1 , a2 , a3 , a4 , a5 , a6 , a7 , 2 )) {
1742- /* Warning message sent already, just bail out */
1746+ /* authProtocol is argument #2 and contextEngineId is argument #7. */
1747+ if (!snmp_session_set_security (snmp_object -> session , a1 , a2 , a3 , a4 , a5 , a6 , a7 , 2 , 7 )) {
1748+ /* An error has already been emitted, just bail out. */
17431749 RETURN_FALSE ;
17441750 }
17451751 RETURN_TRUE ;
0 commit comments