barty/D4J-Repair huggingface dataset:
File: source/org/jfree/chart/renderer/category/AbstractCategoryItemRenderer.java
Issue: #983 Potential NPE in AbstractCategoryItemRender.getLegendItems()
Setting up a working copy of the current JFreeChart trunk in Eclipse I got a warning about a null pointer access in this bit of code from AbstractCategoryItemRender.java:
public LegendItemCollection getLegendItems() {
LegendItemCollection result = new LegendItemCollection();
if (this.plot == null) {
return result;
}
int index = this.plot.getIndexOf(this);
CategoryDataset dataset = this.plot.getDataset(index);
if (dataset != null) {
return result;
}
int seriesCount = dataset.getRowCount();
...
}
The warning is in the last code line where seriesCount is assigned. The variable dataset is guaranteed to be null in this location, I suppose that the check before that should actually read "if (dataset == null)", not "if (dataset != null)".
This is trunk as of 2010-02-08.

Buggy code:
public LegendItemCollection getLegendItems() {
    LegendItemCollection result = new LegendItemCollection();
    if (this.plot == null) {
        return result;
    }
    int index = this.plot.getIndexOf(this);
    CategoryDataset dataset = this.plot.getDataset(index);
    if (dataset != null) {
        return result;
    }
    int seriesCount = dataset.getRowCount();
    if (plot.getRowRenderingOrder().equals(SortOrder.ASCENDING)) {
        for (int i = 0; i < seriesCount; i++) {
            if (isSeriesVisibleInLegend(i)) {
                LegendItem item = getLegendItem(index, i);
                if (item != null) {
                    result.add(item);
                }
            }
        }
    }
    else {
        for (int i = seriesCount - 1; i >= 0; i--) {
            if (isSeriesVisibleInLegend(i)) {
                LegendItem item = getLegendItem(index, i);
                if (item != null) {
                    result.add(item);
                }
            }
        }
    }
    return result;
}

Fixed code:
public LegendItemCollection getLegendItems() {
    LegendItemCollection result = new LegendItemCollection();
    if (this.plot == null) {
        return result;
    }
    int index = this.plot.getIndexOf(this);
    CategoryDataset dataset = this.plot.getDataset(index);
    if (dataset == null) {
        return result;
    }
    int seriesCount = dataset.getRowCount();
    if (plot.getRowRenderingOrder().equals(SortOrder.ASCENDING)) {
        for (int i = 0; i < seriesCount; i++) {
            if (isSeriesVisibleInLegend(i)) {
                LegendItem item = getLegendItem(index, i);
                if (item != null) {
                    result.add(item);
                }
            }
        }
    }
    else {
        for (int i = seriesCount - 1; i >= 0; i--) {
            if (isSeriesVisibleInLegend(i)) {
                LegendItem item = getLegendItem(index, i);
                if (item != null) {
                    result.add(item);
                }
            }
        }
    }
    return result;
}
File: source/org/jfree/chart/imagemap/StandardToolTipTagFragmentGenerator.java

Buggy code:
public String generateToolTipFragment(String toolTipText) {
    return " title=\"" + toolTipText
        + "\" alt=\"\"";
}

Fixed code:
public String generateToolTipFragment(String toolTipText) {
    return " title=\"" + ImageMapUtilities.htmlEscape(toolTipText) 
        + "\" alt=\"\"";
}
File: source/org/jfree/chart/util/ShapeUtilities.java
Issue: #868 JCommon 1.0.12 ShapeUtilities.equal(path1,path2)
The comparison of two GeneralPath objects uses the same PathIterator for both objects. equal(GeneralPath path1, GeneralPath path2) will thus return true for any pair of non-null GeneralPath instances having the same windingRule.

Buggy code:
public static boolean equal(GeneralPath p1, GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p1.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}

Fixed code:
public static boolean equal(GeneralPath p1, GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p2.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}
File: source/org/jfree/chart/plot/MultiplePiePlot.java
Issue: #213 Fix for MultiplePiePlot
When dataset is passed into constructor for MultiplePiePlot, the dataset is not wired to a listener, as it would be if setDataset is called.

Buggy code:
public MultiplePiePlot(CategoryDataset dataset) {
    super();
    this.dataset = dataset;
    PiePlot piePlot = new PiePlot(null);
    this.pieChart = new JFreeChart(piePlot);
    this.pieChart.removeLegend();
    this.dataExtractOrder = TableOrder.BY_COLUMN;
    this.pieChart.setBackgroundPaint(null);
    TextTitle seriesTitle = new TextTitle("Series Title",
            new Font("SansSerif", Font.BOLD, 12));
    seriesTitle.setPosition(RectangleEdge.BOTTOM);
    this.pieChart.setTitle(seriesTitle);
    this.aggregatedItemsKey = "Other";
    this.aggregatedItemsPaint = Color.lightGray;
    this.sectionPaints = new HashMap();
}

Fixed code:
public MultiplePiePlot(CategoryDataset dataset) {
    super();
    setDataset(dataset);
    PiePlot piePlot = new PiePlot(null);
    this.pieChart = new JFreeChart(piePlot);
    this.pieChart.removeLegend();
    this.dataExtractOrder = TableOrder.BY_COLUMN;
    this.pieChart.setBackgroundPaint(null);
    TextTitle seriesTitle = new TextTitle("Series Title",
            new Font("SansSerif", Font.BOLD, 12));
    seriesTitle.setPosition(RectangleEdge.BOTTOM);
    this.pieChart.setTitle(seriesTitle);
    this.aggregatedItemsKey = "Other";
    this.aggregatedItemsPaint = Color.lightGray;
    this.sectionPaints = new HashMap();
}
File: source/org/jfree/data/time/TimeSeries.java
Issue: #803 cloning of TimeSeries
It's just a minor bug!
When I clone a TimeSeries which has no items, I get an IllegalArgumentException ("Requires start <= end").
But I don't think the user should be responsible for checking whether the TimeSeries has any items or not.

Buggy code:
public Object clone() throws CloneNotSupportedException {
    Object clone = createCopy(0, getItemCount() - 1);
    return clone;
}

Fixed code:
public Object clone() throws CloneNotSupportedException {
    TimeSeries clone = (TimeSeries) super.clone();
    clone.data = (List) ObjectUtilities.deepClone(this.data);
    return clone;
}
File: source/org/jfree/chart/plot/ValueMarker.java

Buggy code:
public ValueMarker(double value, Paint paint, Stroke stroke, 
                   Paint outlinePaint, Stroke outlineStroke, float alpha) {
    super(paint, stroke, paint, stroke, alpha);
    this.value = value;
}

Fixed code:
public ValueMarker(double value, Paint paint, Stroke stroke, 
                   Paint outlinePaint, Stroke outlineStroke, float alpha) {
    super(paint, stroke, outlinePaint, outlineStroke, alpha);
    this.value = value;
}
File: source/org/jfree/chart/renderer/GrayPaintScale.java

Buggy code:
public Paint getPaint(double value) {
    double v = Math.max(value, this.lowerBound);
    v = Math.min(v, this.upperBound);
    int g = (int) ((value - this.lowerBound) / (this.upperBound 
            - this.lowerBound) * 255.0);
    return new Color(g, g, g);
}

Fixed code:
public Paint getPaint(double value) {
    double v = Math.max(value, this.lowerBound);
    v = Math.min(v, this.upperBound);
    int g = (int) ((v - this.lowerBound) / (this.upperBound 
            - this.lowerBound) * 255.0);
    return new Color(g, g, g);
}
File: source/org/jfree/data/time/TimeSeries.java

Buggy code:
public TimeSeries createCopy(int start, int end)
        throws CloneNotSupportedException {
    if (start < 0) {
        throw new IllegalArgumentException("Requires start >= 0.");
    }
    if (end < start) {
        throw new IllegalArgumentException("Requires start <= end.");
    }
    TimeSeries copy = (TimeSeries) super.clone();
    copy.data = new java.util.ArrayList();
    if (this.data.size() > 0) {
        for (int index = start; index <= end; index++) {
            TimeSeriesDataItem item
                    = (TimeSeriesDataItem) this.data.get(index);
            TimeSeriesDataItem clone = (TimeSeriesDataItem) item.clone();
            try {
                copy.add(clone);
            }
            catch (SeriesException e) {
                e.printStackTrace();
            }
        }
    }
    return copy;
}

Fixed code:
public TimeSeries createCopy(int start, int end)
        throws CloneNotSupportedException {
    if (start < 0) {
        throw new IllegalArgumentException("Requires start >= 0.");
    }
    if (end < start) {
        throw new IllegalArgumentException("Requires start <= end.");
    }
    TimeSeries copy = (TimeSeries) super.clone();
    copy.minY = Double.NaN;
    copy.maxY = Double.NaN;
    copy.data = new java.util.ArrayList();
    if (this.data.size() > 0) {
        for (int index = start; index <= end; index++) {
            TimeSeriesDataItem item
                    = (TimeSeriesDataItem) this.data.get(index);
            TimeSeriesDataItem clone = (TimeSeriesDataItem) item.clone();
            try {
                copy.add(clone);
            }
            catch (SeriesException e) {
                e.printStackTrace();
            }
        }
    }
    return copy;
}
File: source/org/jfree/chart/util/ShapeList.java

Buggy code:
public boolean equals(Object obj) {

    if (obj == this) {
        return true;
    }
    if (!(obj instanceof ShapeList)) {
        return false;
    }
    return super.equals(obj);

}

Fixed code:
public boolean equals(Object obj) {

    if (obj == this) {
        return true;
    }
    if (!(obj instanceof ShapeList)) {
        return false;
    }
    ShapeList that = (ShapeList) obj;
    int listSize = size();
    for (int i = 0; i < listSize; i++) {
       if (!ShapeUtilities.equal((Shape) get(i), (Shape) that.get(i))) {
           return false;
       }
    }
    return true;

}
File: source/org/jfree/data/time/Week.java

Buggy code:
public Week(Date time, TimeZone zone) {
    // defer argument checking...
    this(time, RegularTimePeriod.DEFAULT_TIME_ZONE, Locale.getDefault());
}

Fixed code:
public Week(Date time, TimeZone zone) {
    // defer argument checking...
    this(time, zone, Locale.getDefault());
}
File: src/java/org/apache/commons/cli/Parser.java
Issue: Missing required options not throwing MissingOptionException
When an Options object is used to parse a second set of command arguments it won't throw a MissingOptionException.

{code:java}
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

public class Example
{
	public static void main(String[] args) throws ParseException
	{
		brokenExample();
		workingExample();
	}

	// throws exception as expected
	private static void workingExample() throws ParseException
	{
		String[] args = {};

		Options opts = new Options();
		opts.addOption(OptionBuilder.isRequired().create('v'));

		GnuParser parser = new GnuParser();
		CommandLine secondCL = parser.parse(opts, args);

		System.out.println("Done workingExample");
	}

	// fails to throw exception on second invocation of parse
	private static void brokenExample() throws ParseException
	{
		String[] firstArgs = { "-v" };
		String[] secondArgs = {};

		Options opts = new Options();
		opts.addOption(OptionBuilder.isRequired().create('v'));

		GnuParser parser = new GnuParser();
		CommandLine firstCL = parser.parse(opts, firstArgs);
		CommandLine secondCL = parser.parse(opts, secondArgs);

		System.out.println("Done brokenExample");
	}
}
{code}

This is a result of the Options object returning the reference to its own list and the parsers modifying that list. The first call is removing the required options as they are found and subsequent calls get back an empty list.

Buggy code:
protected void setOptions(final Options options) {
        this.options = options;
        this.requiredOptions = options.getRequiredOptions();
    }

Fixed code:
protected void setOptions(final Options options) {
        this.options = options;
        this.requiredOptions = new ArrayList(options.getRequiredOptions());
    }
File: src/java/org/apache/commons/cli/PosixParser.java
Issue: PosixParser keeps bursting tokens even if a non option character is found
PosixParser doesn't stop the bursting process of a token if stopAtNonOption is enabled and a non option character is encountered.
For example if the options a and b are defined, with stopAtNonOption=true the following command line:

-azb

is turned into:

-a zb -b

the right output should be:

-a zb

Buggy code:
protected void burstToken(String token, boolean stopAtNonOption)
{
    for (int i = 1; i < token.length(); i++)
    {
        String ch = String.valueOf(token.charAt(i));

        if (options.hasOption(ch))
        {
            tokens.add("-" + ch);
            currentOption = options.getOption(ch);

            if (currentOption.hasArg() && (token.length() != (i + 1)))
            {
                tokens.add(token.substring(i + 1));

                break;
            }
        }
        else if (stopAtNonOption)
        {
            process(token.substring(i));
        }
        else
        {
            tokens.add(token);
            break;
        }
    }
}

Fixed code:
protected void burstToken(String token, boolean stopAtNonOption)
{
    for (int i = 1; i < token.length(); i++)
    {
        String ch = String.valueOf(token.charAt(i));

        if (options.hasOption(ch))
        {
            tokens.add("-" + ch);
            currentOption = options.getOption(ch);

            if (currentOption.hasArg() && (token.length() != (i + 1)))
            {
                tokens.add(token.substring(i + 1));

                break;
            }
        }
        else if (stopAtNonOption)
        {
            process(token.substring(i));
            break;
        }
        else
        {
            tokens.add(token);
            break;
        }
    }
}
File: src/java/org/apache/commons/cli/PosixParser.java
Issue: PosixParser ignores unrecognized tokens starting with '-'
PosixParser doesn't handle properly unrecognized tokens starting with '-' when stopAtNonOption is enabled, the token is simply ignored.
For example, if the option 'a' is defined, the following command line:

-z -a foo

is interpreted as:

-a foo

Buggy code:
private void processOptionToken(String token, boolean stopAtNonOption)
{
    if (options.hasOption(token))
    {
        currentOption = options.getOption(token);
        tokens.add(token);
    }
    else if (stopAtNonOption)
    {
        eatTheRest = true;
        tokens.add(token);
    }
}

Fixed code:
private void processOptionToken(String token, boolean stopAtNonOption)
{
    if (options.hasOption(token))
    {
        currentOption = options.getOption(token);
    }
    else if (stopAtNonOption)
    {
        eatTheRest = true;
    }

    tokens.add(token);
}
File: src/java/org/apache/commons/cli/PosixParser.java
Issue: [cli] Parameter value "-something" misinterpreted as a parameter
If a parameter value is passed that contains a hyphen as the (delimited) first 
character, CLI parses this a parameter. For example using the call
java myclass -t "-something"
Results in the parser creating the invalid parameter -o (noting that it is 
skipping the 's')

My code is using the Posix parser as follows
Options options = buildCommandLineOptions();
CommandLineParser parser = new PosixParser();
CommandLine commandLine = null;
try {
			
	commandLine = parser.parse(options, args);
}
catch (ParseException e) {
			
	System.out.println("Invalid parameters. " + e.getMessage() + NEW_LINE);
	System.exit(EXIT_CODE_ERROR);
}

This has been tested against the nightly build dated 20050503.

Buggy code:
protected void burstToken(String token, boolean stopAtNonOption)
    {
        int tokenLength = token.length();

        for (int i = 1; i < tokenLength; i++)
        {
            String ch = String.valueOf(token.charAt(i));
            boolean hasOption = options.hasOption(ch);

            if (hasOption)
            {
                tokens.add("-" + ch);
                currentOption = options.getOption(ch);

                if (currentOption.hasArg() && (token.length() != (i + 1)))
                {
                    tokens.add(token.substring(i + 1));

                    break;
                }
            }
            else if (stopAtNonOption)
            {
                process(token.substring(i));
            }
            else
            {
                tokens.add("-" + ch);
            }
        }
    }

Fixed code:
protected void burstToken(String token, boolean stopAtNonOption)
    {
        int tokenLength = token.length();

        for (int i = 1; i < tokenLength; i++)
        {
            String ch = String.valueOf(token.charAt(i));
            boolean hasOption = options.hasOption(ch);

            if (hasOption)
            {
                tokens.add("-" + ch);
                currentOption = options.getOption(ch);

                if (currentOption.hasArg() && (token.length() != (i + 1)))
                {
                    tokens.add(token.substring(i + 1));

                    break;
                }
            }
            else if (stopAtNonOption)
            {
                process(token.substring(i));
            }
            else
            {
                tokens.add(token);
                break;
            }
        }
    }
File: src/java/org/apache/commons/cli/HelpFormatter.java
Issue: infinite loop in the wrapping code of HelpFormatter
If there is not enough space to display a word on a single line, HelpFormatter goes into a infinite loops until the JVM crashes with an OutOfMemoryError.
Test case:

Options options = new Options();
options.addOption("h", "help", false, "This is a looooong description");

HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(20);
formatter.printHelp("app", options); // hang & crash

An helpful exception indicating the insufficient width would be more appropriate than an OutOfMemoryError.

Buggy code:
protected StringBuffer renderWrappedText(StringBuffer sb, int width, 
                                         int nextLineTabStop, String text)
{
    int pos = findWrapPos(text, width, 0);

    if (pos == -1)
    {
        sb.append(rtrim(text));

        return sb;
    }
    sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);

    // all following lines must be padded with nextLineTabStop space 
    // characters
    final String padding = createPadding(nextLineTabStop);

    while (true)
    {
        int lastPos = pos;
        text = padding + text.substring(pos).trim();
        pos = findWrapPos(text, width, 0);

        if (pos == -1)
        {
            sb.append(text);

            return sb;
        } else
        if (pos == lastPos)
        {
            throw new RuntimeException("Text too long for line - throwing exception to avoid infinite loop [CLI-162]: " + text);
        }

        sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
    }
}

Fixed code:
protected StringBuffer renderWrappedText(StringBuffer sb, int width, 
                                         int nextLineTabStop, String text)
{
    int pos = findWrapPos(text, width, 0);

    if (pos == -1)
    {
        sb.append(rtrim(text));

        return sb;
    }
    sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);

    // all following lines must be padded with nextLineTabStop space 
    // characters
    final String padding = createPadding(nextLineTabStop);

    while (true)
    {
        text = padding + text.substring(pos).trim();
        pos = findWrapPos(text, width, 0);

        if (pos == -1)
        {
            sb.append(text);

            return sb;
        }
        
        if ( (text.length() > width) && (pos == nextLineTabStop - 1) ) {
            sb.append(text);

            return sb;
        }

        sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine);
    }
}