barty/D4J-Repair huggingface dataset:
File: src/main/java/org/jsoup/parser/CharacterReader.java
Issue: StringIndexOutOfBoundsException as of jsoup 1.11.1
Example:
Jsoup.parse(new URL("https://gist.githubusercontent.com/valodzka/91ed27043628e9023009e503d41f1aad/raw/a15f68671e6f0517e48fdac812983b85fea27c16/test.html"), 10_000);

Buggy code:
private static String cacheString(final char[] charBuf, final String[] stringCache, final int start, final int count) {
    // limit (no cache):
    if (count > maxStringCacheLen)
        return new String(charBuf, start, count);

    // calculate hash:
    int hash = 0;
    int offset = start;
    for (int i = 0; i < count; i++) {
        hash = 31 * hash + charBuf[offset++];
    }

    // get from cache
    final int index = hash & stringCache.length - 1;
    String cached = stringCache[index];

    if (cached == null) { // miss, add
        cached = new String(charBuf, start, count);
        stringCache[index] = cached;
    } else { // hashcode hit, check equality
        if (rangeEquals(charBuf, start, count, cached)) { // hit
            return cached;
        } else { // hashcode conflict
            cached = new String(charBuf, start, count);
            stringCache[index] = cached; // update the cache, as recently used strings are more likely to show up again
        }
    }
    return cached;
}

Fixed code:
private static String cacheString(final char[] charBuf, final String[] stringCache, final int start, final int count) {
    // limit (no cache):
    if (count > maxStringCacheLen)
        return new String(charBuf, start, count);
    if (count < 1)
        return "";

    // calculate hash:
    int hash = 0;
    int offset = start;
    for (int i = 0; i < count; i++) {
        hash = 31 * hash + charBuf[offset++];
    }

    // get from cache
    final int index = hash & stringCache.length - 1;
    String cached = stringCache[index];

    if (cached == null) { // miss, add
        cached = new String(charBuf, start, count);
        stringCache[index] = cached;
    } else { // hashcode hit, check equality
        if (rangeEquals(charBuf, start, count, cached)) { // hit
            return cached;
        } else { // hashcode conflict
            cached = new String(charBuf, start, count);
            stringCache[index] = cached; // update the cache, as recently used strings are more likely to show up again
        }
    }
    return cached;
}
File: src/main/java/org/jsoup/nodes/Attributes.java
Issue: Regression - Boolean attributes not collapsed when using HTML syntax
Hello,
First off, thanks for a really useful library.
So, upgrading from 1.10.2 to 1.11.2 we see that boolean attributes are no longer collapsed when using html syntax. Example test case:
    @Test
    public void test() {
        Document document = Jsoup.parse(
                "<html><head></head><body><hr size=\"1\" noshade=\"\"></body></html>");
        assertEquals("<html>\n" +
                     " <head></head>\n" +
                     " <body>\n" +
                     "  <hr size=\"1\" noshade>\n" +
                     " </body>\n" +
                     "</html>",
                     document.outerHtml());
    }

Tracked it down to commit "Refactored Attributes to be an array pair vs LinkedHashSet " ea1fb65. The Attibutes.html(final Appendable accum, final Document.OutputSettings out) method no longer uses Attribute and fails to check the value of the attribute for an empty string(line 320).
If I may also suggest to use Attribute.shouldCollapseAttribute(String key, String val, Document.OutputSettings out) instead as a single source of truth as the boolean expression is complex enough and easy to make a mistake. Not sure if this would have an impact in performance though but I am guessing that optimizer will inline the call at some point anyways?

Buggy code:
final void html(final Appendable accum, final Document.OutputSettings out) throws IOException {
    final int sz = size;
    for (int i = 0; i < sz; i++) {
        // inlined from Attribute.html()
        final String key = keys[i];
        final String val = vals[i];
        accum.append(' ').append(key);

        // collapse checked=null, checked="", checked=checked; write out others
        if (!(out.syntax() == Document.OutputSettings.Syntax.html
            && (val == null || val.equals(key) && Attribute.isBooleanAttribute(key)))) {
            accum.append("=\"");
            Entities.escape(accum, val == null ? EmptyString : val, out, true, false, false);
            accum.append('"');
        }
    }
}

Fixed code:
final void html(final Appendable accum, final Document.OutputSettings out) throws IOException {
    final int sz = size;
    for (int i = 0; i < sz; i++) {
        // inlined from Attribute.html()
        final String key = keys[i];
        final String val = vals[i];
        accum.append(' ').append(key);

        // collapse checked=null, checked="", checked=checked; write out others
        if (!Attribute.shouldCollapseAttribute(key, val, out)) {
            accum.append("=\"");
            Entities.escape(accum, val == null ? EmptyString : val, out, true, false, false);
            accum.append('"');
        }
    }
}
File: src/main/java/org/jsoup/parser/XmlTreeBuilder.java
Issue: xmlParser() with ParseSettings.htmlDefault does not put end tag to lower case
@Test public void test() {
    Parser parser = Parser.xmlParser().settings(ParseSettings.htmlDefault);
    Document document = Jsoup.parse("<div>test</DIV><p></p>", "", parser);
    assertEquals("<div>\n test\n</div>\n<p></p>", document.toString()); // fail -> toString() = "<div>\n test\n <p></p>\n</div>"
}

@Test public void test1() {
    Parser parser = Parser.xmlParser().settings(ParseSettings.htmlDefault);
    Document document = Jsoup.parse("<DIV>test</div><p></p>", "", parser);
    assertEquals("<div>\n test\n</div>\n<p></p>", document.toString()); // pass
}

Buggy code:
private void popStackToClose(Token.EndTag endTag) {
    String elName = endTag.name();
    Element firstFound = null;

    for (int pos = stack.size() -1; pos >= 0; pos--) {
        Element next = stack.get(pos);
        if (next.nodeName().equals(elName)) {
            firstFound = next;
            break;
        }
    }
    if (firstFound == null)
        return; // not found, skip

    for (int pos = stack.size() -1; pos >= 0; pos--) {
        Element next = stack.get(pos);
        stack.remove(pos);
        if (next == firstFound)
            break;
    }
}

Fixed code:
private void popStackToClose(Token.EndTag endTag) {
    String elName = endTag.normalName();
    Element firstFound = null;

    for (int pos = stack.size() -1; pos >= 0; pos--) {
        Element next = stack.get(pos);
        if (next.nodeName().equals(elName)) {
            firstFound = next;
            break;
        }
    }
    if (firstFound == null)
        return; // not found, skip

    for (int pos = stack.size() -1; pos >= 0; pos--) {
        Element next = stack.get(pos);
        stack.remove(pos);
        if (next == firstFound)
            break;
    }
}
File: src/main/java/org/jsoup/parser/XmlTreeBuilder.java
Issue: Faulty Xml Causes IndexOutOfBoundsException
@Test
public void parseFaultyXml() {
    String xml = "<?xml version='1.0'><val>One</val>";
    Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
}
Results in:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

	at java.util.ArrayList.rangeCheck(ArrayList.java:657)
	at java.util.ArrayList.get(ArrayList.java:433)
	at org.jsoup.nodes.Element.child(Element.java:254)
	at org.jsoup.parser.XmlTreeBuilder.insert(XmlTreeBuilder.java:91)
	at org.jsoup.parser.XmlTreeBuilder.process(XmlTreeBuilder.java:49)
	at org.jsoup.parser.TreeBuilder.runParser(TreeBuilder.java:52)
	at org.jsoup.parser.TreeBuilder.parse(TreeBuilder.java:45)
	at org.jsoup.parser.Parser.parseInput(Parser.java:34)
	at org.jsoup.Jsoup.parse(Jsoup.java:45)

Buggy code:
void insert(Token.Comment commentToken) {
    Comment comment = new Comment(commentToken.getData());
    Node insert = comment;
    if (commentToken.bogus) { // xml declarations are emitted as bogus comments (which is right for html, but not xml)
        // so we do a bit of a hack and parse the data as an element to pull the attributes out
        String data = comment.getData();
        if (data.length() > 1 && (data.startsWith("!") || data.startsWith("?"))) {
            Document doc = Jsoup.parse("<" + data.substring(1, data.length() -1) + ">", baseUri, Parser.xmlParser());
                Element el = doc.child(0);
                insert = new XmlDeclaration(settings.normalizeTag(el.tagName()), data.startsWith("!"));
                insert.attributes().addAll(el.attributes());
        }
    }
    insertNode(insert);
}

Fixed code:
void insert(Token.Comment commentToken) {
    Comment comment = new Comment(commentToken.getData());
    Node insert = comment;
    if (commentToken.bogus) { // xml declarations are emitted as bogus comments (which is right for html, but not xml)
        // so we do a bit of a hack and parse the data as an element to pull the attributes out
        String data = comment.getData();
        if (data.length() > 1 && (data.startsWith("!") || data.startsWith("?"))) {
            Document doc = Jsoup.parse("<" + data.substring(1, data.length() -1) + ">", baseUri, Parser.xmlParser());
            if (doc.childNodeSize() > 0) {
                Element el = doc.child(0);
                insert = new XmlDeclaration(settings.normalizeTag(el.tagName()), data.startsWith("!"));
                insert.attributes().addAll(el.attributes());
            } // else, we couldn't parse it as a decl, so leave as a comment
        }
    }
    insertNode(insert);
}
File: src/main/java/org/jsoup/nodes/Attribute.java
Issue: Attribute.java line 45 variable key scope error, it seems should be "this.key"
Attribute.java Line 45, it should be:
Validate.notEmpty(this.key);
rather than
Validate.notEmpty(key);
This issue only happens when key is blank or empty, in reality this would rarely happen, but in the syntax context it is still an issue, so better fix this.

Buggy code:
public Attribute(String key, String val, Attributes parent) {
    Validate.notNull(key);
    this.key = key.trim();
    Validate.notEmpty(key); // trimming could potentially make empty, so validate here
    this.val = val;
    this.parent = parent;
}

Fixed code:
public Attribute(String key, String val, Attributes parent) {
    Validate.notNull(key);
    key = key.trim();
    Validate.notEmpty(key); // trimming could potentially make empty, so validate here
    this.key = key;
    this.val = val;
    this.parent = parent;
}
File: src/main/java/org/jsoup/nodes/Comment.java
Issue: Jsoup 1.11.3: IndexOutOfBoundsException
Hi, I am using Jsoup 1.11.3. While trying to parse HTML content, I'm getting IndexOutOfBoundsException.
I am using such Jsoup call as this is the only way to parse iframe content.
Jsoup call:
Jsoup.parse(html, "", Parser.xmlParser())
HTML is here:  https://files.fm/u/v43yemgb. I can't add it to the body as it's huge.

Buggy code:
public XmlDeclaration asXmlDeclaration() {
    String data = getData();
    Document doc = Jsoup.parse("<" + data.substring(1, data.length() -1) + ">", baseUri(), Parser.xmlParser());
    XmlDeclaration decl = null;
    if (doc.childNodeSize() > 0) {
        Element el = doc.child(0);
        decl = new XmlDeclaration(NodeUtils.parser(doc).settings().normalizeTag(el.tagName()), data.startsWith("!"));
        decl.attributes().addAll(el.attributes());
    }
    return decl;
}

Fixed code:
public XmlDeclaration asXmlDeclaration() {
    String data = getData();
    Document doc = Jsoup.parse("<" + data.substring(1, data.length() -1) + ">", baseUri(), Parser.xmlParser());
    XmlDeclaration decl = null;
    if (doc.children().size() > 0) {
        Element el = doc.child(0);
        decl = new XmlDeclaration(NodeUtils.parser(doc).settings().normalizeTag(el.tagName()), data.startsWith("!"));
        decl.attributes().addAll(el.attributes());
    }
    return decl;
}
File: src/main/java/org/jsoup/nodes/Attribute.java
Issue: Attribute.getValue() broken for empty attributes since 1.11.1
Document doc = Jsoup.parse("<div hidden>");
        Attributes attributes = doc.body().child(0).attributes();
        System.out.println(String.format("Attr: '%s', value: '%s'", "hidden",
                attributes.get("hidden")));

        Attribute first = attributes.iterator().next();
        System.out.println(String.format("Attr: '%s', value: '%s'",
                first.getKey(), first.getValue()));

Expected output, as in 1.10.x
Attr: 'hidden', value: ''
Attr: 'hidden', value: ''

Output in 1.11.1-1.11.3:
Attr: 'hidden', value: ''
Attr: 'hidden', value: 'null'

Buggy code:
public String getValue() {
    return val;
}

Fixed code:
public String getValue() {
    return Attributes.checkNotNull(val);
}
File: src/main/java/org/jsoup/nodes/Attribute.java
Issue: NPE in Attribute.setValue() for attribute without parent
public String setValue(String val) {
        String oldVal = parent.get(this.key);
        if (parent != null) {
            int i = parent.indexOfKey(this.key);
            if (i != Attributes.NotFound)
                parent.vals[i] = val;
        }
        this.val = val;
        return oldVal;
    }

Its useless to check parent for null after it has been dereferenced. I guess this is a copy-paste-bug:
    public void setKey(String key) {
        Validate.notNull(key);
        key = key.trim();
        Validate.notEmpty(key); // trimming could potentially make empty, so validate here
        if (parent != null) {
            int i = parent.indexOfKey(this.key);
            if (i != Attributes.NotFound)
                parent.keys[i] = key;
        }
        this.key = key;
    }

Buggy code:
public String setValue(String val) {
    String oldVal = parent.get(this.key);
    if (parent != null) {
        int i = parent.indexOfKey(this.key);
        if (i != Attributes.NotFound)
            parent.vals[i] = val;
    }
    this.val = val;
    return Attributes.checkNotNull(oldVal);
}

Fixed code:
public String setValue(String val) {
    String oldVal = this.val;
    if (parent != null) {
        oldVal = parent.get(this.key); // trust the container more
        int i = parent.indexOfKey(this.key);
        if (i != Attributes.NotFound)
            parent.vals[i] = val;
    }
    this.val = val;
    return Attributes.checkNotNull(oldVal);
}
File: src/main/java/org/jsoup/helper/HttpConnection.java
Issue: ArrayIndexOutOfBoundsException when parsing with some URL
error
Caused by: java.lang.ArrayIndexOutOfBoundsException: 11
	at org.jsoup.helper.HttpConnection$Base.looksLikeUtf8(HttpConnection.java:437)
	at org.jsoup.helper.HttpConnection$Base.fixHeaderEncoding(HttpConnection.java:400)
	at org.jsoup.helper.HttpConnection$Base.addHeader(HttpConnection.java:386)
	at org.jsoup.helper.HttpConnection$Response.processResponseHeaders(HttpConnection.java:1075)
	at org.jsoup.helper.HttpConnection$Response.setupFromConnection(HttpConnection.java:1019)
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:752)
	at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:722)
	at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:306)

code
try {
            String url = "https://www.colisprive.com/moncolis/pages/detailColis.aspx?numColis=P4000000037777930";
            Connection connection = Jsoup.connect(url).referrer(url).
                    userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36")
                    .ignoreContentType(true).timeout(20000);

            connection.method(Method.GET);
            return connection.execute().parse();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

Buggy code:
private static boolean looksLikeUtf8(byte[] input) {
    int i = 0;
    // BOM:
    if (input.length >= 3 && (input[0] & 0xFF) == 0xEF
        && (input[1] & 0xFF) == 0xBB & (input[2] & 0xFF) == 0xBF) {
        i = 3;
    }

    int end;
    for (int j = input.length; i < j; ++i) {
        int o = input[i];
        if ((o & 0x80) == 0) {
            continue; // ASCII
        }

        // UTF-8 leading:
        if ((o & 0xE0) == 0xC0) {
            end = i + 1;
        } else if ((o & 0xF0) == 0xE0) {
            end = i + 2;
        } else if ((o & 0xF8) == 0xF0) {
            end = i + 3;
        } else {
            return false;
        }


        while (i < end) {
            i++;
            o = input[i];
            if ((o & 0xC0) != 0x80) {
                return false;
            }
        }
    }
    return true;
}

Fixed code:
private static boolean looksLikeUtf8(byte[] input) {
    int i = 0;
    // BOM:
    if (input.length >= 3 && (input[0] & 0xFF) == 0xEF
        && (input[1] & 0xFF) == 0xBB & (input[2] & 0xFF) == 0xBF) {
        i = 3;
    }

    int end;
    for (int j = input.length; i < j; ++i) {
        int o = input[i];
        if ((o & 0x80) == 0) {
            continue; // ASCII
        }

        // UTF-8 leading:
        if ((o & 0xE0) == 0xC0) {
            end = i + 1;
        } else if ((o & 0xF0) == 0xE0) {
            end = i + 2;
        } else if ((o & 0xF8) == 0xF0) {
            end = i + 3;
        } else {
            return false;
        }

        if (end >= input.length)
            return false;

        while (i < end) {
            i++;
            o = input[i];
            if ((o & 0xC0) != 0x80) {
                return false;
            }
        }
    }
    return true;
}
File: src/java/org/apache/commons/jxpath/ri/compiler/CoreOperationRelationalExpression.java
Issue: Binary operators behaviour involving node-sets is incorrect
According to XPath specification:
"If both objects to be compared are node-sets, then the comparison will be true if and only if there is a node in the first node-set and a node in the second node-set such that the result of performing the comparison on the string-values of the two nodes is true. If one object to be compared is a node-set and the other is a number, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the number to be compared and on the result of converting the string-value of that node to a number using the number function is true."
But following example illustrates, that this is not a JXPath behaviour:
        JXPathContext pathContext = JXPathContext
                .newContext(DocumentBuilderFactory.newInstance()
                        .newDocumentBuilder().parse(
                                new InputSource(new StringReader(
                                        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
                                                + "<doc/>"))));
        Boolean result = (Boolean) pathContext.getValue("2.0 > child1",
                Boolean.class);
        assertFalse(result.booleanValue());
"child1" is not found - right operand node set is empty, but result is TRUE, instead of FALSE.
Please, check greaterThan(), lesserThan(), etc methods of org.apache.xpath.objects.XObject for possible solution

Buggy code:
public final Object computeValue(EvalContext context) {
    return compute(args[0].computeValue(context), args[1].computeValue(context)) 
            ? Boolean.TRUE : Boolean.FALSE;
}

Fixed code:
public final Object computeValue(EvalContext context) {
    return compute(args[0].compute(context), args[1].compute(context))
            ? Boolean.TRUE : Boolean.FALSE;
}
File: src/java/org/apache/commons/jxpath/ri/axes/UnionContext.java
Issue: Core union operation does not sort result nodes according to document order
Source document:
<MAIN><A>avalue</A><B>bvalue</B></MAIN>

According to string() function defintion:
"A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned."

Following XPath calculated incorrectly:
 string(/MAIN/B | /MAIN/A)

Expected result: "avalue"
Actual value: "bvalue"

Reason:
sorting of result nodes is missing from CoreOperationUnion

Buggy code:
public boolean setPosition(int position) {
        if (!prepared) {
            prepared = true;
            BasicNodeSet nodeSet = (BasicNodeSet) getNodeSet();
            ArrayList pointers = new ArrayList();
            for (int i = 0; i < contexts.length; i++) {
                EvalContext ctx = (EvalContext) contexts[i];
                while (ctx.nextSet()) {
                    while (ctx.nextNode()) {
                        NodePointer ptr = ctx.getCurrentNodePointer();
                        if (!pointers.contains(ptr)) {
                            nodeSet.add(ptr);
                            pointers.add(ptr);
                        }
                    }
                }
            }
        }
        return super.setPosition(position);
    }

Fixed code:
public boolean setPosition(int position) {
        if (!prepared) {
            prepared = true;
            BasicNodeSet nodeSet = (BasicNodeSet) getNodeSet();
            ArrayList pointers = new ArrayList();
            for (int i = 0; i < contexts.length; i++) {
                EvalContext ctx = (EvalContext) contexts[i];
                while (ctx.nextSet()) {
                    while (ctx.nextNode()) {
                        NodePointer ptr = ctx.getCurrentNodePointer();
                        if (!pointers.contains(ptr)) {
                            pointers.add(ptr);
                        }
                    }
                }
            }
            sortPointers(pointers);

            for (Iterator it = pointers.iterator(); it.hasNext();) {
                nodeSet.add((Pointer) it.next());
            }
        }
        return super.setPosition(position);
    }
File: src/java/org/apache/commons/jxpath/ri/axes/AttributeContext.java
Issue: Issue with attribute::
Checking test (Issue172_CountAttributeNode) I came with the following fix for the code in AttributeContext  line 72
from 
-----
if (!(nodeTest instanceof NodeNameTest)) {
                return false;
            }
            QName name = ((NodeNameTest) nodeTest).getNodeName();
            
------
'
to 
--- (outside method)
private static final QName WILDCARD = new QName("", "*");
--- (in method)
    
final QName name ;
if (nodeTest instanceof NodeTypeTest)
{
	 if (((NodeTypeTest) nodeTest).getNodeType() == Compiler.NODE_TYPE_NODE)
		 name = WILDCARD;
	 else return false;
}
else if (nodeTest instanceof NodeNameTest) {
	name = ((NodeNameTest) nodeTest).getNodeName();
}
else
{
	return false;
}




Buggy code:
public boolean nextNode() {
        super.setPosition(getCurrentPosition() + 1);
        if (!setStarted) {
            setStarted = true;
            if (!(nodeTest instanceof NodeNameTest)) {
                return false;
            }
            QName name = ((NodeNameTest) nodeTest).getNodeName();
            iterator =
                parentContext.getCurrentNodePointer().attributeIterator(name);
        }
        if (iterator == null) {
            return false;
        }
        if (!iterator.setPosition(iterator.getPosition() + 1)) {
            return false;
        }
        currentNodePointer = iterator.getNodePointer();
        return true;
    }

Fixed code:
public boolean nextNode() {
        super.setPosition(getCurrentPosition() + 1);
        if (!setStarted) {
            setStarted = true;
            NodeNameTest nodeNameTest = null;
            if (nodeTest instanceof NodeTypeTest) {
                if (((NodeTypeTest) nodeTest).getNodeType() == Compiler.NODE_TYPE_NODE) {
                    nodeNameTest = WILDCARD_TEST;
                }
            }
            else if (nodeTest instanceof NodeNameTest) {
                nodeNameTest = (NodeNameTest) nodeTest;
            }
            if (nodeNameTest == null) {
                return false;
            }
            iterator = parentContext.getCurrentNodePointer().attributeIterator(
                    nodeNameTest.getNodeName());
        }
        if (iterator == null) {
            return false;
        }
        if (!iterator.setPosition(iterator.getPosition() + 1)) {
            return false;
        }
        currentNodePointer = iterator.getNodePointer();
        return true;
    }