@@ -274,6 +274,34 @@ def mock_add_extension(*args, **kwargs):
274274 parser .parse_args ('test new-ext reset pos1 pos2' .split ()) # test positional args
275275 self .assertIn ("Extension another-ext-name installed. Please rerun your command." , logger_msgs [6 ])
276276
277+ # test dynamic extension install with the command rerun after installation.
278+ # The command must be rerun via run_az_cmd (args as a list, no shell) to avoid command injection.
279+ from knack .util import CommandResultItem
280+ run_az_cmd_args = []
281+
282+ def mock_run_az_cmd (args , out_file = None ): # pylint: disable=unused-argument
283+ run_az_cmd_args .append (args )
284+ return CommandResultItem (None , exit_code = 0 )
285+
286+ with mock .patch .object (logging .Logger , 'error' , mock_log_error ), \
287+ mock .patch .object (azure .cli .core .extension .operations , 'add_extension' , mock_add_extension ), \
288+ mock .patch .object (azure .cli .core .extension .dynamic_install , '_get_extension_command_tree' ,
289+ mock_ext_cmd_tree_load ), \
290+ mock .patch .object (azure .cli .core .extension .dynamic_install , '_get_extension_use_dynamic_install_config' ,
291+ return_value = 'yes_without_prompt' ), \
292+ mock .patch .object (azure .cli .core .extension .dynamic_install ,
293+ '_get_extension_run_after_dynamic_install_config' , return_value = True ), \
294+ mock .patch .object (azure .cli .core .util , 'run_az_cmd' , mock_run_az_cmd ):
295+ with self .assertRaises (SystemExit ) as cm :
296+ parser .parse_args (['test' , 'new-ext' , 'create' , '--opt' , 'enum_2 & echo injected' ])
297+ # exit code comes from the rerun result
298+ self .assertEqual (cm .exception .code , 0 )
299+ # args are passed as a list without the 'az' entry point, so no shell can reinterpret them
300+ self .assertEqual (run_az_cmd_args ,
301+ [['test' , 'new-ext' , 'create' , '--opt' , 'enum_2 & echo injected' ]])
302+ # error message is only for telemetry, it should not be printed again
303+ self .assertEqual (len (logger_msgs ), 7 )
304+
277305
278306class VerifyError : # pylint: disable=too-few-public-methods
279307
0 commit comments