diff options
author | Arif Ali <arif.ali@canonical.com> | 2023-07-14 12:50:58 +0100 |
---|---|---|
committer | Jake Hunsaker <jacob.r.hunsaker@gmail.com> | 2023-07-18 21:01:14 -0400 |
commit | d2a14422ef5771fd704a4c761f26768d4bd9bb7f (patch) | |
tree | f302b7ad13176ae60118a518d1ed0be6222136a2 | |
parent | 5bcdb79cb59edf3169d99227777bf700f04a036e (diff) | |
download | sos-d2a14422ef5771fd704a4c761f26768d4bd9bb7f.tar.gz |
[plugins] py311 fix for re.M
Add a common regex for re.MULTILINE so that doesn't need to be defined
and remove the definitions where `(?m)` is being defined
Closes: #3301
Signed-off-by: Arif Ali <arif.ali@canonical.com>
28 files changed, 48 insertions, 46 deletions
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py index e8aedca8..a4dfbb64 100644 --- a/sos/report/plugins/__init__.py +++ b/sos/report/plugins/__init__.py @@ -1274,12 +1274,13 @@ class Plugin(): """ try: path = self._get_dest_for_srcpath(srcpath) + common_flags = re.IGNORECASE | re.MULTILINE if hasattr(regexp, "pattern"): pattern = regexp.pattern - flags = regexp.flags | re.IGNORECASE + flags = regexp.flags | common_flags else: pattern = regexp - flags = re.IGNORECASE + flags = common_flags self._log_debug("substituting scrpath '%s'" % srcpath) self._log_debug("substituting '%s' for '%s' in '%s'" % (subst, pattern, path)) diff --git a/sos/report/plugins/collectd.py b/sos/report/plugins/collectd.py index 818f1568..65355543 100644 --- a/sos/report/plugins/collectd.py +++ b/sos/report/plugins/collectd.py @@ -51,7 +51,7 @@ class Collectd(Plugin, IndependentPlugin): "Password", "User", "[<]*URL", "Address" ] - regexp = r"((?m)^[#]*\s*(%s)\s* \s*)(.*)" % "|".join(protect_keys) + regexp = r"(^[#]*\s*(%s)\s* \s*)(.*)" % "|".join(protect_keys) self.do_path_regex_sub( "/etc/collectd.d/*.conf", regexp, r'\1"*********"' diff --git a/sos/report/plugins/grafana.py b/sos/report/plugins/grafana.py index f58f1871..4aa5668c 100644 --- a/sos/report/plugins/grafana.py +++ b/sos/report/plugins/grafana.py @@ -42,6 +42,6 @@ class Grafana(Plugin, IndependentPlugin): "admin_password", "secret_key" ] - regexp = r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) + regexp = r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) self.do_path_regex_sub("/etc/grafana/grafana.ini", regexp, r"\1*********") diff --git a/sos/report/plugins/juju.py b/sos/report/plugins/juju.py index 3a947b54..b0208042 100644 --- a/sos/report/plugins/juju.py +++ b/sos/report/plugins/juju.py @@ -63,7 +63,7 @@ class Juju(Plugin, UbuntuPlugin): ] # Redact simple yaml style "key: value". - keys_regex = r"((?m)^\s*(%s)\s*:\s*)(.*)" % "|".join(protect_keys) + keys_regex = r"(^\s*(%s)\s*:\s*)(.*)" % "|".join(protect_keys) sub_regex = r"\1*********" self.do_path_regex_sub(agents_path, keys_regex, sub_regex) # Redact certificates diff --git a/sos/report/plugins/openssl.py b/sos/report/plugins/openssl.py index b9c77f4d..1003f99d 100644 --- a/sos/report/plugins/openssl.py +++ b/sos/report/plugins/openssl.py @@ -27,7 +27,7 @@ class OpenSSL(Plugin): "challengePassword" ] - regexp = r"(?m)^(\s*#?\s*(%s).*=)(.*)" % "|".join(protect_keys) + regexp = r"^(\s*#?\s*(%s).*=)(.*)" % "|".join(protect_keys) self.do_file_sub( '/etc/ssl/openssl.cnf', diff --git a/sos/report/plugins/openstack_ansible.py b/sos/report/plugins/openstack_ansible.py index c7488e76..1d260147 100644 --- a/sos/report/plugins/openstack_ansible.py +++ b/sos/report/plugins/openstack_ansible.py @@ -34,7 +34,7 @@ class OpenStackAnsible(Plugin, IndependentPlugin): "/etc/openstack_deploy/user_secrets.yml", "/etc/rpc_deploy/user_secrets.yml" ] - regexp = r"(?m)^\s*#*([\w_]*:\s*).*" + regexp = r"^\s*#*([\w_]*:\s*).*" for secrets_file in secrets_files: self.do_path_regex_sub( secrets_file, diff --git a/sos/report/plugins/openstack_aodh.py b/sos/report/plugins/openstack_aodh.py index 3688706b..a53e15e3 100644 --- a/sos/report/plugins/openstack_aodh.py +++ b/sos/report/plugins/openstack_aodh.py @@ -80,11 +80,11 @@ class OpenStackAodh(Plugin): connection_keys = ["connection", "backend_url", "transport_url"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_barbican.py b/sos/report/plugins/openstack_barbican.py index aaa6c0fb..14a75f1d 100644 --- a/sos/report/plugins/openstack_barbican.py +++ b/sos/report/plugins/openstack_barbican.py @@ -42,7 +42,7 @@ class OpenStackBarbican(Plugin, DebianPlugin, UbuntuPlugin): ] self.do_file_sub( "/etc/barbican/barbican.conf", - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1********" ) @@ -50,7 +50,7 @@ class OpenStackBarbican(Plugin, DebianPlugin, UbuntuPlugin): self.do_path_regex_sub( "/etc/barbican/barbican.conf", - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6") diff --git a/sos/report/plugins/openstack_ceilometer.py b/sos/report/plugins/openstack_ceilometer.py index 0031afd2..7b313f54 100644 --- a/sos/report/plugins/openstack_ceilometer.py +++ b/sos/report/plugins/openstack_ceilometer.py @@ -59,11 +59,11 @@ class OpenStackCeilometer(Plugin): connection_keys = ["connection", "backend_url", "transport_url"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_cinder.py b/sos/report/plugins/openstack_cinder.py index 23483a8d..56f65cce 100644 --- a/sos/report/plugins/openstack_cinder.py +++ b/sos/report/plugins/openstack_cinder.py @@ -94,11 +94,11 @@ class OpenStackCinder(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_designate.py b/sos/report/plugins/openstack_designate.py index a2ea37ab..616bb0c1 100644 --- a/sos/report/plugins/openstack_designate.py +++ b/sos/report/plugins/openstack_designate.py @@ -81,7 +81,7 @@ class OpenStackDesignate(Plugin): "ssl_key_password", "ssl_client_key_password", "memcache_secret_key" ] - regexp = r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) + regexp = r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) self.do_path_regex_sub("/etc/designate/*", regexp, r"\1*********") self.do_path_regex_sub( diff --git a/sos/report/plugins/openstack_glance.py b/sos/report/plugins/openstack_glance.py index ec0feee6..c8ec8fff 100644 --- a/sos/report/plugins/openstack_glance.py +++ b/sos/report/plugins/openstack_glance.py @@ -96,11 +96,11 @@ class OpenStackGlance(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_heat.py b/sos/report/plugins/openstack_heat.py index 28e20ad2..3d046039 100644 --- a/sos/report/plugins/openstack_heat.py +++ b/sos/report/plugins/openstack_heat.py @@ -109,11 +109,11 @@ class OpenStackHeat(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_horizon.py b/sos/report/plugins/openstack_horizon.py index 167b377a..f7952df9 100644 --- a/sos/report/plugins/openstack_horizon.py +++ b/sos/report/plugins/openstack_horizon.py @@ -50,7 +50,7 @@ class OpenStackHorizon(Plugin): "SECRET_KEY", "EMAIL_HOST_PASSWORD" ] - regexp = r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) + regexp = r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) for regpath in [r"/etc/openstack-dashboard/.*\.json", "/etc/openstack-dashboard/local_settings$"]: self.do_path_regex_sub(regpath, regexp, r"\1*********") diff --git a/sos/report/plugins/openstack_instack.py b/sos/report/plugins/openstack_instack.py index af99b0d1..1ca70fb0 100644 --- a/sos/report/plugins/openstack_instack.py +++ b/sos/report/plugins/openstack_instack.py @@ -133,13 +133,13 @@ class OpenStackInstack(Plugin): "undercloud_swift_password", "undercloud_tuskar_password", ] - regexp = r"((?m)(%s)=)(.*)" % "|".join(protected_keys) + regexp = r"((%s)=)(.*)" % "|".join(protected_keys) self.do_file_sub("/home/stack/.instack/install-undercloud.log", regexp, r"\1*********") self.do_file_sub(UNDERCLOUD_CONF_PATH, regexp, r"\1*********") protected_json_keys = ["pm_password", "ssh-key", "password"] - json_regexp = r'((?m)"(%s)": )(".*?")' % "|".join(protected_json_keys) + json_regexp = r'("(%s)": )(".*?")' % "|".join(protected_json_keys) self.do_file_sub("/home/stack/instackenv.json", json_regexp, r"\1*********") self.do_file_sub('/home/stack/.tripleo/history', diff --git a/sos/report/plugins/openstack_ironic.py b/sos/report/plugins/openstack_ironic.py index 6646f45b..05985e53 100644 --- a/sos/report/plugins/openstack_ironic.py +++ b/sos/report/plugins/openstack_ironic.py @@ -145,11 +145,11 @@ class OpenStackIronic(Plugin): connection_keys = ["connection", "sql_connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_keystone.py b/sos/report/plugins/openstack_keystone.py index 378d359c..0fa5f1d5 100644 --- a/sos/report/plugins/openstack_keystone.py +++ b/sos/report/plugins/openstack_keystone.py @@ -98,11 +98,11 @@ class OpenStackKeystone(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) @@ -110,7 +110,7 @@ class OpenStackKeystone(Plugin): # obfuscate LDAP plaintext passwords in domain config dir self.do_path_regex_sub( self.domain_config_dir, - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1********" ) diff --git a/sos/report/plugins/openstack_manila.py b/sos/report/plugins/openstack_manila.py index 3c0e49c2..4c03e50f 100644 --- a/sos/report/plugins/openstack_manila.py +++ b/sos/report/plugins/openstack_manila.py @@ -64,11 +64,11 @@ class OpenStackManila(Plugin): connection_keys = ["connection", "sql_connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_neutron.py b/sos/report/plugins/openstack_neutron.py index a9f2e637..f24dfebe 100644 --- a/sos/report/plugins/openstack_neutron.py +++ b/sos/report/plugins/openstack_neutron.py @@ -89,11 +89,11 @@ class OpenStackNeutron(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_nova.py b/sos/report/plugins/openstack_nova.py index 8bdcb1c6..15e3ecc1 100644 --- a/sos/report/plugins/openstack_nova.py +++ b/sos/report/plugins/openstack_nova.py @@ -109,6 +109,7 @@ class OpenStackNova(Plugin): self.add_copy_spec(self.path_join(novadir, novalog)) self.add_copy_spec([ "/var/log/{}*/nova*.log".format(self.apachepkg), + "/var/log/{}*/placement*.log".format(self.apachepkg), ]) pp = ['', '_libvirt', '_metadata', '_placement'] @@ -154,11 +155,11 @@ class OpenStackNova(Plugin): connection_keys = ["connection", "sql_connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_octavia.py b/sos/report/plugins/openstack_octavia.py index 45d68635..75657d31 100644 --- a/sos/report/plugins/openstack_octavia.py +++ b/sos/report/plugins/openstack_octavia.py @@ -117,7 +117,7 @@ class OpenStackOctavia(Plugin): "connection", "transport_url", "server_certs_key_passphrase", "memcache_secret_key" ] - regexp = r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) + regexp = r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) self.do_path_regex_sub("/etc/octavia/*", regexp, r"\1*********") self.do_path_regex_sub( diff --git a/sos/report/plugins/openstack_placement.py b/sos/report/plugins/openstack_placement.py index 637b95fd..6d63cb35 100644 --- a/sos/report/plugins/openstack_placement.py +++ b/sos/report/plugins/openstack_placement.py @@ -75,11 +75,11 @@ class OpenStackPlacement(Plugin): connection_keys = ["database_connection", "slave_connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_sahara.py b/sos/report/plugins/openstack_sahara.py index 99361d7d..0a7fcf04 100644 --- a/sos/report/plugins/openstack_sahara.py +++ b/sos/report/plugins/openstack_sahara.py @@ -52,11 +52,11 @@ class OpenStackSahara(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_swift.py b/sos/report/plugins/openstack_swift.py index 232a65ed..4f4324c2 100644 --- a/sos/report/plugins/openstack_swift.py +++ b/sos/report/plugins/openstack_swift.py @@ -62,11 +62,11 @@ class OpenStackSwift(Plugin): connection_keys = ["connection", "sql_connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/openstack_trove.py b/sos/report/plugins/openstack_trove.py index f617072b..de8fe77c 100644 --- a/sos/report/plugins/openstack_trove.py +++ b/sos/report/plugins/openstack_trove.py @@ -51,11 +51,11 @@ class OpenStackTrove(Plugin): connection_keys = ["connection"] self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), + r"(^\s*(%s)\s*=\s*)(.*)" % "|".join(protect_keys), r"\1*********" ) self.apply_regex_sub( - r"((?m)^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % + r"(^\s*(%s)\s*=\s*(.*)://(\w*):)(.*)(@(.*))" % "|".join(connection_keys), r"\1*********\6" ) diff --git a/sos/report/plugins/ovirt.py b/sos/report/plugins/ovirt.py index 19375deb..d5b6d772 100644 --- a/sos/report/plugins/ovirt.py +++ b/sos/report/plugins/ovirt.py @@ -263,7 +263,7 @@ class Ovirt(Plugin, RedHatPlugin): "pool.default.ssl.truststore.password", "config.datasource.dbpassword" ] - regexp = r"((?m)^\s*#*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) + regexp = r"(^\s*#*(%s)\s*=\s*)(.*)" % "|".join(protect_keys) self.do_path_regex_sub(r"/etc/ovirt-engine/aaa/.*\.properties", regexp, r"\1*********") diff --git a/sos/report/plugins/salt.py b/sos/report/plugins/salt.py index c2a830b0..bad5e3a6 100644 --- a/sos/report/plugins/salt.py +++ b/sos/report/plugins/salt.py @@ -30,7 +30,7 @@ class Salt(Plugin, IndependentPlugin): self.add_forbidden_path("/etc/salt/pki/*/*.pem") def postproc(self): - regexp = r'((?m)^\s+.*(pass|secret|(?<![A-z])key(?![A-z])).*:\ ).+$' + regexp = r'(^\s+.*(pass|secret|(?<![A-z])key(?![A-z])).*:\ ).+$' subst = r'\1******' self.do_path_regex_sub("/etc/salt/*", regexp, subst) diff --git a/sos/report/plugins/saltmaster.py b/sos/report/plugins/saltmaster.py index b81935d6..99c750ba 100644 --- a/sos/report/plugins/saltmaster.py +++ b/sos/report/plugins/saltmaster.py @@ -29,7 +29,7 @@ class SaltMaster(Plugin, IndependentPlugin): self.add_cmd_output("salt-key --list all") def postproc(self): - regexp = r'((?m)^\s+.*(pass|secret|(?<![A-z])key(?![A-z])).*:\ ).+$' + regexp = r'(^\s+.*(pass|secret|(?<![A-z])key(?![A-z])).*:\ ).+$' subst = r'\1******' self.do_path_regex_sub("/etc/salt/*", regexp, subst) |