8344891: Remove uses of sun.misc.ReflectUtil in java.desktop

Reviewed-by: kizune, azvegint
This commit is contained in:
Phil Race 2024-11-23 23:20:15 +00:00
parent 822a1554cb
commit 7be94d043d
24 changed files with 9 additions and 68 deletions

View File

@ -38,7 +38,6 @@ import javax.swing.plaf.UIResource;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.lwawt.macosx.CPlatformWindow; import sun.lwawt.macosx.CPlatformWindow;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
import com.apple.laf.AquaImageFactory.SlicedImageControl; import com.apple.laf.AquaImageFactory.SlicedImageControl;
@ -174,7 +173,6 @@ final class AquaUtils {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
T getInstance() { T getInstance() {
try { try {
ReflectUtil.checkPackageAccess(clazz);
return clazz.newInstance(); return clazz.newInstance();
} catch (ReflectiveOperationException ignored) { } catch (ReflectiveOperationException ignored) {
} }

View File

@ -24,8 +24,6 @@
*/ */
package com.sun.beans.finder; package com.sun.beans.finder;
import static sun.reflect.misc.ReflectUtil.checkPackageAccess;
/** /**
* This is utility class that provides {@code static} methods * This is utility class that provides {@code static} methods
* to find a class with the specified name using the specified class loader. * to find a class with the specified name using the specified class loader.
@ -56,7 +54,6 @@ public final class ClassFinder {
* @see Thread#getContextClassLoader() * @see Thread#getContextClassLoader()
*/ */
public static Class<?> findClass(String name) throws ClassNotFoundException { public static Class<?> findClass(String name) throws ClassNotFoundException {
checkPackageAccess(name);
try { try {
ClassLoader loader = Thread.currentThread().getContextClassLoader(); ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) { if (loader == null) {
@ -95,7 +92,6 @@ public final class ClassFinder {
* @see Class#forName(String,boolean,ClassLoader) * @see Class#forName(String,boolean,ClassLoader)
*/ */
public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException { public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException {
checkPackageAccess(name);
if (loader != null) { if (loader != null) {
try { try {
return Class.forName(name, false, loader); return Class.forName(name, false, loader);

View File

@ -30,7 +30,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import static com.sun.beans.util.Cache.Kind.SOFT; import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/** /**
* This utility class provides {@code static} methods * This utility class provides {@code static} methods
@ -81,7 +80,7 @@ public final class ConstructorFinder extends AbstractFinder<Constructor<?>> {
throw new NoSuchMethodException("Abstract class cannot be instantiated: " throw new NoSuchMethodException("Abstract class cannot be instantiated: "
+ type.getName()); + type.getName());
} }
if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { if (!Modifier.isPublic(type.getModifiers())) {
throw new NoSuchMethodException("Class is not accessible: " + type.getName()); throw new NoSuchMethodException("Class is not accessible: " + type.getName());
} }
PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); PrimitiveWrapperMap.replacePrimitivesWithWrappers(args);

View File

@ -27,8 +27,6 @@ package com.sun.beans.finder;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/** /**
* This utility class provides {@code static} methods * This utility class provides {@code static} methods
* to find a public field with specified name * to find a public field with specified name
@ -62,7 +60,7 @@ public final class FieldFinder {
throw new NoSuchFieldException("Field '" + name + "' is not public"); throw new NoSuchFieldException("Field '" + name + "' is not public");
} }
type = field.getDeclaringClass(); type = field.getDeclaringClass();
if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { if (!Modifier.isPublic(type.getModifiers())) {
throw new NoSuchFieldException("Field '" + name + "' is not accessible"); throw new NoSuchFieldException("Field '" + name + "' is not accessible");
} }
return field; return field;

View File

@ -34,7 +34,6 @@ import java.lang.reflect.Type;
import java.util.Arrays; import java.util.Arrays;
import static com.sun.beans.util.Cache.Kind.SOFT; import static com.sun.beans.util.Cache.Kind.SOFT;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/** /**
* This utility class provides {@code static} methods * This utility class provides {@code static} methods
@ -79,7 +78,7 @@ public final class MethodFinder extends AbstractFinder<Method> {
try { try {
Method method = CACHE.get(signature); Method method = CACHE.get(signature);
return (method == null) || isPackageAccessible(method.getDeclaringClass()) ? method : CACHE.create(signature); return (method == null) ? method : CACHE.create(signature);
} }
catch (SignatureException exception) { catch (SignatureException exception) {
throw exception.toNoSuchMethodException("Method '" + name + "' is not found"); throw exception.toNoSuchMethodException("Method '" + name + "' is not found");
@ -138,7 +137,7 @@ public final class MethodFinder extends AbstractFinder<Method> {
if (!FinderUtils.isExported(type)) { if (!FinderUtils.isExported(type)) {
throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible"); throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible");
} }
if (Modifier.isPublic(type.getModifiers()) && isPackageAccessible(type)) { if (Modifier.isPublic(type.getModifiers())) {
return method; return method;
} }
if (Modifier.isStatic(method.getModifiers())) { if (Modifier.isStatic(method.getModifiers())) {

View File

@ -31,8 +31,6 @@ import java.util.Map;
import com.sun.beans.util.Cache; import com.sun.beans.util.Cache;
import static sun.reflect.misc.ReflectUtil.checkPackageAccess;
public final class ClassInfo { public final class ClassInfo {
private static final ClassInfo DEFAULT = new ClassInfo(null); private static final ClassInfo DEFAULT = new ClassInfo(null);
private static final Cache<Class<?>,ClassInfo> CACHE private static final Cache<Class<?>,ClassInfo> CACHE
@ -48,7 +46,6 @@ public final class ClassInfo {
return DEFAULT; return DEFAULT;
} }
try { try {
checkPackageAccess(type);
return CACHE.get(type); return CACHE.get(type);
} catch (SecurityException exception) { } catch (SecurityException exception) {
return DEFAULT; return DEFAULT;

View File

@ -39,8 +39,6 @@ import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.Soundbank; import javax.sound.midi.Soundbank;
import javax.sound.midi.spi.SoundbankReader; import javax.sound.midi.spi.SoundbankReader;
import sun.reflect.misc.ReflectUtil;
/** /**
* JarSoundbankReader is used to read soundbank object from jar files. * JarSoundbankReader is used to read soundbank object from jar files.
* *
@ -95,7 +93,6 @@ public final class JARSoundbankReader extends SoundbankReader {
try { try {
Class<?> c = Class.forName(line.trim(), false, ucl); Class<?> c = Class.forName(line.trim(), false, ucl);
if (Soundbank.class.isAssignableFrom(c)) { if (Soundbank.class.isAssignableFrom(c)) {
ReflectUtil.checkPackageAccess(c);
Object o = c.newInstance(); Object o = c.newInstance();
soundbanks.add((Soundbank) o); soundbanks.add((Soundbank) o);
} }

View File

@ -27,7 +27,7 @@ package java.beans;
import java.util.*; import java.util.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.Objects; import java.util.Objects;
import sun.reflect.misc.*; import sun.reflect.misc.MethodUtil;
/** /**
@ -222,9 +222,6 @@ public class DefaultPersistenceDelegate extends PersistenceDelegate {
// Write out the properties of this instance. // Write out the properties of this instance.
private void initBean(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { private void initBean(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
for (Field field : type.getFields()) { for (Field field : type.getFields()) {
if (!ReflectUtil.isPackageAccessible(field.getDeclaringClass())) {
continue;
}
int mod = field.getModifiers(); int mod = field.getModifiers();
if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) { if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
continue; continue;

View File

@ -30,7 +30,6 @@ import java.lang.reflect.Proxy;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import sun.reflect.misc.MethodUtil; import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
/** /**
* The {@code EventHandler} class provides * The {@code EventHandler} class provides
@ -691,7 +690,6 @@ public class EventHandler implements InvocationHandler {
} }
private static ClassLoader getClassLoader(Class<?> type) { private static ClassLoader getClassLoader(Class<?> type) {
ReflectUtil.checkPackageAccess(type);
ClassLoader loader = type.getClassLoader(); ClassLoader loader = type.getClassLoader();
if (loader == null) { if (loader == null) {
loader = Thread.currentThread().getContextClassLoader(); // avoid use of BCP loader = Thread.currentThread().getContextClassLoader(); // avoid use of BCP

View File

@ -47,7 +47,6 @@ import com.sun.beans.introspect.EventSetInfo;
import com.sun.beans.introspect.PropertyInfo; import com.sun.beans.introspect.PropertyInfo;
import jdk.internal.access.JavaBeansAccess; import jdk.internal.access.JavaBeansAccess;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import sun.reflect.misc.ReflectUtil;
/** /**
* The Introspector class provides a standard way for tools to learn about * The Introspector class provides a standard way for tools to learn about
@ -186,9 +185,6 @@ public class Introspector {
public static BeanInfo getBeanInfo(Class<?> beanClass) public static BeanInfo getBeanInfo(Class<?> beanClass)
throws IntrospectionException throws IntrospectionException
{ {
if (!ReflectUtil.isPackageAccessible(beanClass)) {
return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
}
ThreadGroupContext context = ThreadGroupContext.getContext(); ThreadGroupContext context = ThreadGroupContext.getContext();
BeanInfo beanInfo = context.getBeanInfo(beanClass); BeanInfo beanInfo = context.getBeanInfo(beanClass);
if (beanInfo == null) { if (beanInfo == null) {

View File

@ -50,8 +50,6 @@ import javax.swing.plaf.ColorUIResource;
import sun.swing.PrintColorUIResource; import sun.swing.PrintColorUIResource;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
/* /*
* Like the {@code Introspector}, the {@code MetaData} class * Like the {@code Introspector}, the {@code MetaData} class
* contains <em>meta</em> objects that describe the way * contains <em>meta</em> objects that describe the way
@ -749,7 +747,7 @@ static final class java_awt_AWTKeyStroke_PersistenceDelegate extends Persistence
static class StaticFieldsPersistenceDelegate extends PersistenceDelegate { static class StaticFieldsPersistenceDelegate extends PersistenceDelegate {
protected void installFields(Encoder out, Class<?> cls) { protected void installFields(Encoder out, Class<?> cls) {
if (Modifier.isPublic(cls.getModifiers()) && isPackageAccessible(cls)) { if (Modifier.isPublic(cls.getModifiers())) {
Field[] fields = cls.getFields(); Field[] fields = cls.getFields();
for(int i = 0; i < fields.length; i++) { for(int i = 0; i < fields.length; i++) {
Field field = fields[i]; Field field = fields[i];

View File

@ -29,8 +29,6 @@ import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
final class MethodRef { final class MethodRef {
private String signature; private String signature;
private SoftReference<Method> methodRef; private SoftReference<Method> methodRef;
@ -68,7 +66,7 @@ final class MethodRef {
} }
this.methodRef = new SoftReference<>(method); this.methodRef = new SoftReference<>(method);
} }
return isPackageAccessible(method.getDeclaringClass()) ? method : null; return method;
} }
private static Method find(Class<?> type, String signature) { private static Method find(Class<?> type, String signature) {

View File

@ -30,7 +30,6 @@ import java.lang.reflect.Constructor;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.sun.beans.introspect.PropertyInfo; import com.sun.beans.introspect.PropertyInfo;
import sun.reflect.misc.ReflectUtil;
/** /**
* A PropertyDescriptor describes one property that a Java Bean * A PropertyDescriptor describes one property that a Java Bean
@ -467,8 +466,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
Object editor = null; Object editor = null;
final Class<?> cls = getPropertyEditorClass(); final Class<?> cls = getPropertyEditorClass();
if (cls != null && PropertyEditor.class.isAssignableFrom(cls) if (cls != null && PropertyEditor.class.isAssignableFrom(cls)) {
&& ReflectUtil.isPackageAccessible(cls)) {
Constructor<?> ctor = null; Constructor<?> ctor = null;
if (bean != null) { if (bean != null) {
try { try {

View File

@ -35,8 +35,6 @@ import com.sun.beans.finder.ConstructorFinder;
import com.sun.beans.finder.MethodFinder; import com.sun.beans.finder.MethodFinder;
import sun.reflect.misc.MethodUtil; import sun.reflect.misc.MethodUtil;
import static sun.reflect.misc.ReflectUtil.checkPackageAccess;
/** /**
* A {@code Statement} object represents a primitive statement * A {@code Statement} object represents a primitive statement
* in which a single method is applied to a target and * in which a single method is applied to a target and
@ -189,13 +187,8 @@ public class Statement {
// Class.forName(String className) won't load classes outside // Class.forName(String className) won't load classes outside
// of core from a class inside core. Special // of core from a class inside core. Special
// case this method. // case this method.
// checkPackageAccess(name) will be called by ClassFinder
return ClassFinder.resolveClass(name, this.loader); return ClassFinder.resolveClass(name, this.loader);
} }
// The 3 args Class.forName(String className, boolean, classloader)
// requires getClassLoader permission, but we will be stricter and
// will require access to the package as well.
checkPackageAccess(name);
} }
Class<?>[] argClasses = new Class<?>[arguments.length]; Class<?>[] argClasses = new Class<?>[arguments.length];
for(int i = 0; i < arguments.length; i++) { for(int i = 0; i < arguments.length; i++) {

View File

@ -108,7 +108,6 @@ public final class SimpleDoc implements Doc {
Class<?> repClass = null; Class<?> repClass = null;
try { try {
String className = flavor.getRepresentationClassName(); String className = flavor.getRepresentationClassName();
sun.reflect.misc.ReflectUtil.checkPackageAccess(className);
repClass = Class.forName(className, false, repClass = Class.forName(className, false,
Thread.currentThread().getContextClassLoader()); Thread.currentThread().getContextClassLoader());
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -94,8 +94,6 @@ import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.HTMLEditorKit;
import sun.reflect.misc.ReflectUtil;
/** /**
* A text component to edit various kinds of content. * A text component to edit various kinds of content.
* You can find how-to information and examples of using editor panes in * You can find how-to information and examples of using editor panes in
@ -1238,7 +1236,6 @@ public class JEditorPane extends JTextComponent {
try { try {
Class<?> c; Class<?> c;
if (loader != null) { if (loader != null) {
ReflectUtil.checkPackageAccess(classname);
c = loader.loadClass(classname); c = loader.loadClass(classname);
} else { } else {
// Will only happen if developer has invoked // Will only happen if developer has invoked

View File

@ -113,7 +113,6 @@ import javax.swing.table.TableRowSorter;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.MouseEventAccessor; import sun.awt.AWTAccessor.MouseEventAccessor;
import sun.reflect.misc.ReflectUtil;
import sun.swing.PrintingStatus; import sun.swing.PrintingStatus;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
import sun.swing.SwingUtilities2.Section; import sun.swing.SwingUtilities2.Section;
@ -5585,7 +5584,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
if (type == Object.class) { if (type == Object.class) {
type = String.class; type = String.class;
} }
ReflectUtil.checkPackageAccess(type);
SwingUtilities2.checkAccess(type.getModifiers()); SwingUtilities2.checkAccess(type.getModifiers());
constructor = type.getConstructor(argTypes); constructor = type.getConstructor(argTypes);
} }

View File

@ -24,7 +24,6 @@
*/ */
package javax.swing; package javax.swing;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
import sun.swing.UIAction; import sun.swing.UIAction;
@ -2033,7 +2032,6 @@ public class SwingUtilities implements SwingConstants
static Class<?> loadSystemClass(String className) throws ClassNotFoundException { static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(className);
return Class.forName(className, true, Thread.currentThread(). return Class.forName(className, true, Thread.currentThread().
getContextClassLoader()); getContextClassLoader());
} }

View File

@ -51,7 +51,6 @@ import java.awt.Dimension;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import sun.reflect.misc.MethodUtil; import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingAccessor; import sun.swing.SwingAccessor;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
@ -702,7 +701,6 @@ public class UIDefaults extends Hashtable<Object,Object>
try { try {
String className = (String)get(uiClassID); String className = (String)get(uiClassID);
if (className != null) { if (className != null) {
ReflectUtil.checkPackageAccess(className);
Class<?> cls = (Class)get(className); Class<?> cls = (Class)get(className);
if (cls == null) { if (cls == null) {
@ -1142,7 +1140,6 @@ public class UIDefaults extends Hashtable<Object,Object>
cl = ClassLoader.getSystemClassLoader(); cl = ClassLoader.getSystemClassLoader();
} }
} }
ReflectUtil.checkPackageAccess(className);
c = Class.forName(className, true, (ClassLoader)cl); c = Class.forName(className, true, (ClassLoader)cl);
SwingUtilities2.checkAccess(c.getModifiers()); SwingUtilities2.checkAccess(c.getModifiers());
if (methodName != null) { if (methodName != null) {

View File

@ -33,8 +33,6 @@ import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.EventListener; import java.util.EventListener;
import sun.reflect.misc.ReflectUtil;
/** /**
* A class that holds a list of EventListeners. A single instance * A class that holds a list of EventListeners. A single instance
* can be used to hold all listeners (of all types) for the instance * can be used to hold all listeners (of all types) for the instance
@ -303,7 +301,6 @@ public class EventListenerList implements Serializable {
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
EventListener l = (EventListener)s.readObject(); EventListener l = (EventListener)s.readObject();
String name = (String) listenerTypeOrNull; String name = (String) listenerTypeOrNull;
ReflectUtil.checkPackageAccess(name);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<EventListener> tmp = (Class<EventListener>)Class.forName(name, true, cl); Class<EventListener> tmp = (Class<EventListener>)Class.forName(name, true, cl);
add(tmp, l); add(tmp, l);

View File

@ -67,7 +67,6 @@ import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import com.sun.beans.decoder.DocumentHandler; import com.sun.beans.decoder.DocumentHandler;
import sun.reflect.misc.ReflectUtil;
class SynthParser extends DefaultHandler { class SynthParser extends DefaultHandler {
// //
@ -646,7 +645,7 @@ class SynthParser extends DefaultHandler {
} }
else { else {
try { try {
typeClass = ReflectUtil.forName(typeName.substring( typeClass = Class.forName(typeName.substring(
0, classIndex)); 0, classIndex));
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
throw new SAXException("Unknown class: " + throw new SAXException("Unknown class: " +

View File

@ -24,7 +24,6 @@
*/ */
package javax.swing.text; package javax.swing.text;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
import java.io.Serializable; import java.io.Serializable;
@ -248,7 +247,6 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter
Constructor<?> cons; Constructor<?> cons;
try { try {
ReflectUtil.checkPackageAccess(vc);
SwingUtilities2.checkAccess(vc.getModifiers()); SwingUtilities2.checkAccess(vc.getModifiers());
cons = vc.getConstructor(new Class<?>[]{String.class}); cons = vc.getConstructor(new Class<?>[]{String.class});

View File

@ -33,7 +33,6 @@ import java.text.NumberFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.Map; import java.util.Map;
import sun.reflect.misc.ReflectUtil;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
/** /**
@ -437,7 +436,6 @@ public class NumberFormatter extends InternationalFormatter {
valueClass = value.getClass(); valueClass = value.getClass();
} }
try { try {
ReflectUtil.checkPackageAccess(valueClass);
SwingUtilities2.checkAccess(valueClass.getModifiers()); SwingUtilities2.checkAccess(valueClass.getModifiers());
Constructor<?> cons = valueClass.getConstructor( Constructor<?> cons = valueClass.getConstructor(
new Class<?>[] { String.class }); new Class<?>[] { String.class });

View File

@ -31,7 +31,6 @@ import java.beans.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import sun.reflect.misc.MethodUtil; import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
/** /**
* Component decorator that implements the view interface * Component decorator that implements the view interface
@ -100,7 +99,6 @@ public class ObjectView extends ComponentView {
AttributeSet attr = getElement().getAttributes(); AttributeSet attr = getElement().getAttributes();
String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID);
try { try {
ReflectUtil.checkPackageAccess(classname);
Class<?> c = Class.forName(classname, false,Thread.currentThread(). Class<?> c = Class.forName(classname, false,Thread.currentThread().
getContextClassLoader()); getContextClassLoader());
if (Component.class.isAssignableFrom(c)) { if (Component.class.isAssignableFrom(c)) {