Program: 54
Project: VUL4J
Buggy source:
//* * The MIT License *  * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Alan Harder *  * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and//or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: *  * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. *//package hudson.util;import com.google.common.collect.ImmutableList;import com.google.common.collect.ImmutableMap;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.mapper.AnnotationMapper;import com.thoughtworks.xstream.mapper.Mapper;import com.thoughtworks.xstream.mapper.MapperWrapper;import com.thoughtworks.xstream.converters.ConversionException;import com.thoughtworks.xstream.converters.Converter;import com.thoughtworks.xstream.converters.ConverterMatcher;import com.thoughtworks.xstream.converters.DataHolder;import com.thoughtworks.xstream.converters.MarshallingContext;import com.thoughtworks.xstream.converters.SingleValueConverter;import com.thoughtworks.xstream.converters.SingleValueConverterWrapper;import com.thoughtworks.xstream.converters.UnmarshallingContext;import com.thoughtworks.xstream.converters.extended.DynamicProxyConverter;import com.thoughtworks.xstream.core.JVM;import com.thoughtworks.xstream.io.HierarchicalStreamDriver;import com.thoughtworks.xstream.io.HierarchicalStreamReader;import com.thoughtworks.xstream.io.HierarchicalStreamWriter;import com.thoughtworks.xstream.mapper.CannotResolveClassException;import edu.umd.cs.findbugs.annotations.SuppressWarnings;import hudson.PluginManager;import hudson.PluginWrapper;import hudson.diagnosis.OldDataMonitor;import hudson.remoting.ClassFilter;import hudson.util.xstream.ImmutableSetConverter;import hudson.util.xstream.ImmutableSortedSetConverter;import jenkins.model.Jenkins;import hudson.model.Label;import hudson.model.Result;import hudson.model.Saveable;import hudson.util.xstream.ImmutableListConverter;import hudson.util.xstream.ImmutableMapConverter;import hudson.util.xstream.MapperDelegate;import java.io.IOException;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.Writer;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.nio.charset.Charset;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import javax.annotation.CheckForNull;import org.kohsuke.accmod.Restricted;import org.kohsuke.accmod.restrictions.NoExternalUse;//** * {@link XStream} enhanced for additional Java5 support and improved robustness. * @author Kohsuke Kawaguchi *//public class XStream2 extends XStream {    private RobustReflectionConverter reflectionConverter;    private final ThreadLocal<Boolean> oldData = new ThreadLocal<Boolean>();    private final @CheckForNull ClassOwnership classOwnership;    private final Map<String,Class<?>> compatibilityAliases = new ConcurrentHashMap<String, Class<?>>();    //**     * Hook to insert {@link Mapper}s after they are created.     *//    private MapperInjectionPoint mapperInjectionPoint;    public XStream2() {        init();        classOwnership = null;    }    public XStream2(HierarchicalStreamDriver hierarchicalStreamDriver) {        super(hierarchicalStreamDriver);        init();        classOwnership = null;    }    XStream2(ClassOwnership classOwnership) {        init();        this.classOwnership = classOwnership;    }    @Override    public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) {                        Jenkins h = Jenkins.getInstance();        if(h!=null && h.pluginManager!=null && h.pluginManager.uberClassLoader!=null) {            setClassLoader(h.pluginManager.uberClassLoader);        }        Object o = super.unmarshal(reader,root,dataHolder);        if (oldData.get()!=null) {            oldData.remove();            if (o instanceof Saveable) OldDataMonitor.report((Saveable)o, "1.106");        }        return o;    }    @Override    protected Converter createDefaultConverter() {                reflectionConverter = new RobustReflectionConverter(getMapper(),new JVM().bestReflectionProvider(), new PluginClassOwnership());        return reflectionConverter;    }    //**     * Specifies that a given field of a given class should not be treated with laxity by {@link RobustCollectionConverter}.     * @param clazz a class which we expect to hold a non-{@code transient} field     * @param field a field name in that class     *//    @Restricted(NoExternalUse.class)     public void addCriticalField(Class<?> clazz, String field) {        reflectionConverter.addCriticalField(clazz, field);    }    static String trimVersion(String version) {                return version.replaceFirst(" .+$", "");    }    private void init() {                addImmutableType(Result.class);                <START_BUG> <END_BUG>        registerConverter(new RobustCollectionConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new RobustMapConverter(getMapper()), 10);        registerConverter(new ImmutableMapConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new ImmutableSortedSetConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new ImmutableSetConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new ImmutableListConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new ConcurrentHashMapConverter(getMapper(),getReflectionProvider()),10);        registerConverter(new CopyOnWriteMap.Tree.ConverterImpl(getMapper()),10);         registerConverter(new DescribableList.ConverterImpl(getMapper()),10);         registerConverter(new Label.ConverterImpl(),10);                        registerConverter(new AssociatedConverterImpl(this), -10);        registerConverter(new BlacklistedTypesConverter(), PRIORITY_VERY_HIGH);         registerConverter(new DynamicProxyConverter(getMapper()) {             @Override public boolean canConvert(Class type) {                return //* this precedes NullConverter *// type != null && super.canConvert(type);            }            @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {                throw new ConversionException("<dynamic-proxy> not supported");            }        }, PRIORITY_VERY_HIGH);    }    @Override    protected MapperWrapper wrapMapper(MapperWrapper next) {        Mapper m = new CompatibilityMapper(new MapperWrapper(next) {            @Override            public String serializedClass(Class type) {                if (type != null && ImmutableMap.class.isAssignableFrom(type))                    return super.serializedClass(ImmutableMap.class);                else if (type != null && ImmutableList.class.isAssignableFrom(type))                    return super.serializedClass(ImmutableList.class);                else                    return super.serializedClass(type);            }        });        AnnotationMapper a = new AnnotationMapper(m, getConverterRegistry(), getConverterLookup(), getClassLoader(), getReflectionProvider(), getJvm());                a.autodetectAnnotations(true);        mapperInjectionPoint = new MapperInjectionPoint(a);        return mapperInjectionPoint;    }    public Mapper getMapperInjectionPoint() {        return mapperInjectionPoint.getDelegate();    }    //**     * @deprecated Uses default encoding yet fails to write an encoding header. Prefer {@link #toXMLUTF8}.     *//    @Deprecated    @Override public void toXML(Object obj, OutputStream out) {        super.toXML(obj, out);    }    //**     * Serializes to a byte stream.     * Uses UTF-8 encoding and specifies that in the XML encoding declaration.     * @since 1.504     *//    public void toXMLUTF8(Object obj, OutputStream out) throws IOException {        Writer w = new OutputStreamWriter(out, Charset.forName("UTF-8"));        w.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");        toXML(obj, w);    }    //**     * This method allows one to insert additional mappers after {@link XStream2} was created,     * but because of the way XStream works internally, this needs to be done carefully.     * Namely,     *     * <ol>     * <li>You need to {@link #getMapperInjectionPoint()} wrap it, then put that back into {@link #setMapper(Mapper)}.     * <li>The whole sequence needs to be synchronized against this object to avoid a concurrency issue.     * <//ol>     *//    public void setMapper(Mapper m) {        mapperInjectionPoint.setDelegate(m);    }    final class MapperInjectionPoint extends MapperDelegate {        public MapperInjectionPoint(Mapper wrapped) {            super(wrapped);        }        public Mapper getDelegate() {            return delegate;        }        public void setDelegate(Mapper m) {            delegate = m;        }    }    //**     * Adds an alias in case class names change.     *     * Unlike {@link #alias(String, Class)}, which uses the registered alias name for writing XML,     * this method registers an alias to be used only for the sake of reading from XML. This makes     * this method usable for the situation when class names change.     *     * @param oldClassName     *      Fully qualified name of the old class name.     * @param newClass     *      New class that's field-compatible with the given old class name.     * @since 1.416     *//    public void addCompatibilityAlias(String oldClassName, Class newClass) {        compatibilityAliases.put(oldClassName,newClass);    }    //**     * Prior to Hudson 1.106, XStream 1.1.x was used which encoded "$" in class names     * as "-" instead of "_-" that is used now.  Up through Hudson 1.348 compatibility     * for old serialized data was maintained via {@code XStream11XmlFriendlyMapper}.     * However, it was found (HUDSON-5768) that this caused fields with "__" to fail     * deserialization due to double decoding.  Now this class is used for compatibility.     *//    private class CompatibilityMapper extends MapperWrapper {        private CompatibilityMapper(Mapper wrapped) {            super(wrapped);        }        @Override        public Class realClass(String elementName) {            Class s = compatibilityAliases.get(elementName);            if (s!=null)    return s;            try {                return super.realClass(elementName);            } catch (CannotResolveClassException e) {                                if (elementName.indexOf('-') >= 0) try {                    Class c = super.realClass(elementName.replace('-', '$'));                    oldData.set(Boolean.TRUE);                    return c;                } catch (CannotResolveClassException e2) { }                                throw e;            }        }    }    //**     * If a class defines a nested {@code ConverterImpl} subclass, use that as a {@link Converter}.     * Its constructor may have XStream//XStream2 and//or Mapper parameters (or no params).     *//    private static final class AssociatedConverterImpl implements Converter {        private final XStream xstream;        private final ConcurrentHashMap<Class<?>,Converter> cache =                new ConcurrentHashMap<Class<?>,Converter>();        private AssociatedConverterImpl(XStream xstream) {            this.xstream = xstream;        }        private Converter findConverter(Class<?> t) {            Converter result = cache.get(t);            if (result != null)                                return result == this ? null : result;            try {                if(t==null || t.getClassLoader()==null)                    return null;                Class<?> cl = t.getClassLoader().loadClass(t.getName() + "$ConverterImpl");                Constructor<?> c = cl.getConstructors()[0];                Class<?>[] p = c.getParameterTypes();                Object[] args = new Object[p.length];                for (int i = 0; i < p.length; i++) {                    if(p[i]==XStream.class || p[i]==XStream2.class)                        args[i] = xstream;                    else if(p[i]== Mapper.class)                        args[i] = xstream.getMapper();                    else                        throw new InstantiationError("Unrecognized constructor parameter: "+p[i]);                }                ConverterMatcher cm = (ConverterMatcher)c.newInstance(args);                result = cm instanceof SingleValueConverter                        ? new SingleValueConverterWrapper((SingleValueConverter)cm)                        : (Converter)cm;                cache.put(t, result);                return result;            } catch (ClassNotFoundException e) {                cache.put(t, this);                  return null;            } catch (IllegalAccessException e) {                IllegalAccessError x = new IllegalAccessError();                x.initCause(e);                throw x;            } catch (InstantiationException e) {                InstantiationError x = new InstantiationError();                x.initCause(e);                throw x;            } catch (InvocationTargetException e) {                InstantiationError x = new InstantiationError();                x.initCause(e);                throw x;            }        }        public boolean canConvert(Class type) {            return findConverter(type)!=null;        }        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {            findConverter(source.getClass()).marshal(source,writer,context);        }        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {            return findConverter(context.getRequiredType()).unmarshal(reader,context);        }    }    //**     * Create a nested {@code ConverterImpl} subclass that extends this class to run some     * callback code just after a type is unmarshalled by RobustReflectionConverter.     * Example: <pre> public static class ConverterImpl extends XStream2.PassthruConverter&lt;MyType&gt; {     *   public ConverterImpl(XStream2 xstream) { super(xstream); }     *   {@literal @}Override protected void callback(MyType obj, UnmarshallingContext context) {     *     ...     * <//pre>     *//    public static abstract class PassthruConverter<T> implements Converter {        private Converter converter;        public PassthruConverter(XStream2 xstream) {            converter = xstream.reflectionConverter;        }        public boolean canConvert(Class type) {                        return false;        }        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {            converter.marshal(source, writer, context);        }        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {            Object obj = converter.unmarshal(reader, context);            callback((T)obj, context);            return obj;        }        protected abstract void callback(T obj, UnmarshallingContext context);    }    //**     * Marks serialized classes as being owned by particular components.     *//    interface ClassOwnership {        //**         * Looks up the owner of a class, if any.         * @param clazz a class which might be from a plugin         * @return an identifier such as plugin name, or null         *//        @CheckForNull String ownerOf(Class<?> clazz);    }        class PluginClassOwnership implements ClassOwnership {        private PluginManager pm;        @SuppressWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")         @Override public String ownerOf(Class<?> clazz) {            if (classOwnership != null) {                return classOwnership.ownerOf(clazz);            }            if (pm == null) {                Jenkins j = Jenkins.getInstance();                if (j != null) {                    pm = j.getPluginManager();                }            }            if (pm == null) {                return null;            }                        PluginWrapper p = pm.whichPlugin(clazz);            return p != null ? p.getShortName() + '@' + trimVersion(p.getVersion()) : null;        }    }    private static class BlacklistedTypesConverter implements Converter {        @Override        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {            throw new UnsupportedOperationException("Refusing to marshal " + source.getClass().getName() + " for security reasons");        }        @Override        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {            throw new ConversionException("Refusing to unmarshal " + reader.getNodeName() + " for security reasons");        }        @Override        public boolean canConvert(Class type) {            if (type == null) {                return false;            }            try {                ClassFilter.DEFAULT.check(type);                ClassFilter.DEFAULT.check(type.getName());            } catch (SecurityException se) {                                return true;            }            return false;        }    }}}}


Fixed version (ground truth):
denyTypes(new Class[] { void.class, Void.class });