Program: 45321
Project: 45321
Buggy source:
/** 
 * This is a major clean up to strip out all the extra stuff you get when you save as web page from Word 2000. It doesn't yet know what to do with VML tags, but these will appear as errors unless you declare them as new tags, such as o:p which needs to be declared as inline.
 * @param lexer Lexer
 * @param node node to clean up
 */
public void cleanWord2000(Lexer lexer,Node node){
  Node list=null;
  while (node != null) {
    if (node.is(TagId.HTML)) {
      if ((node.getAttrByName("String_Node_Str") == null)) {
        return;
      }
      lexer.configuration.tt.freeAttrs(node);
    }
    if (node.is(TagId.P)) {
      if (noMargins(node)) {
        Node pre;
        Node next;
        Node.coerceNode(lexer,node,TagId.PRE,false,true);
        purgeWord2000Attributes(node);
        if (node.content != null) {
          cleanWord2000(lexer,node.content);
        }
        pre=node;
        node=node.next;
        while (node.is(TagId.P) && noMargins(node)) {
          next=node.next;
          node.removeNode();
          pre.insertNodeAtEnd(lexer.newLineNode());
          pre.insertNodeAtEnd(node);
          stripSpan(lexer,node);
          node=next;
        }
        if (node == null) {
          break;
        }
      }
    }
    if (node.tag != null && TidyUtils.toBoolean(node.tag.model & Dict.CM_BLOCK) && singleSpace(lexer,node)) {
      node=stripSpan(lexer,node);
      continue;
    }
    if (node.is(TagId.STYLE) || node.is(TagId.META) || node.type == NodeType.CommentTag) {
      node=Node.discardElement(node);
      continue;
    }
    if (node.is(TagId.SPAN) || node.is(TagId.FONT)) {
      node=stripSpan(lexer,node);
      continue;
    }
    if (node.is(TagId.LINK)) {
      AttVal attr=node.getAttrByName("String_Node_Str");
      if (attr != null && attr.value != null && attr.value.equals("String_Node_Str")) {
        node=Node.discardElement(node);
        continue;
      }
    }
    if (node.tag != null && "String_Node_Str".equals(node.tag.name)) {
      Node[] next=new Node[1];
      discardContainer(node,next);
      node=next[0];
      continue;
    }
    if (node.content == null && node.is(TagId.P)) {
      node=Node.discardElement(node);
      continue;
    }
    if (node.is(TagId.P)) {
      AttVal attr=node.getAttrByName("String_Node_Str");
      AttVal atrStyle=node.getAttrByName("String_Node_Str");
      if (attr != null && attr.value != null && ((attr.value.equals("String_Node_Str") || attr.value.equals("String_Node_Str")) || (atrStyle != null && (atrStyle.value.indexOf("String_Node_Str") != -1)))) {
        TagId listType=TagId.UL;
        if (attr.value.equals("String_Node_Str")) {
          listType=TagId.OL;
        }
        Node.coerceNode(lexer,node,TagId.LI,false,true);
        if (list == null || !list.is(listType)) {
          list=lexer.inferredTag(listType);
          Node.insertNodeBeforeElement(node,list);
        }
        purgeWord2000Attributes(node);
        if (node.content != null) {
          cleanWord2000(lexer,node.content);
        }
        node.removeNode();
        list.insertNodeAtEnd(node);
        node=list;
      }
 else       if (attr != null && attr.value != null && attr.value.equals("String_Node_Str")) {
        Node br=lexer.newLineNode();
        normalizeSpaces(lexer,node);
        if (list == null || !list.is(TagId.PRE)) {
          list=lexer.inferredTag(TagId.PRE);
          Node.insertNodeBeforeElement(node,list);
        }
        node.removeNode();
        list.insertNodeAtEnd(node);
        stripSpan(lexer,node);
        list.insertNodeAtEnd(br);
        node=list.next;
      }
 else {
        list=null;
      }
    }
 else {
      list=null;
    }
    if (node.type == NodeType.StartTag || node.type == NodeType.StartEndTag) {
      purgeWord2000Attributes(node);
    }
    if (node.content != null) {
      cleanWord2000(lexer,node.content);
    }
    node=node.next;
  }
}

Fixed version (ground truth):
/** 
 * This is a major clean up to strip out all the extra stuff you get when you save as web page from Word 2000. It doesn't yet know what to do with VML tags, but these will appear as errors unless you declare them as new tags, such as o:p which needs to be declared as inline.
 * @param lexer Lexer
 * @param node node to clean up
 */
public void cleanWord2000(Lexer lexer,Node node){
  Node list=null;
  while (node != null) {
    if (node.is(TagId.HTML)) {
      if ((node.getAttrByName("String_Node_Str") == null)) {
        return;
      }
      lexer.configuration.tt.freeAttrs(node);
    }
    if (node.is(TagId.P)) {
      if (noMargins(node)) {
        Node pre;
        Node next;
        Node.coerceNode(lexer,node,TagId.PRE,false,true);
        purgeWord2000Attributes(node);
        if (node.content != null) {
          cleanWord2000(lexer,node.content);
        }
        pre=node;
        node=node.next;
        while (node != null && node.is(TagId.P) && noMargins(node)) {
          next=node.next;
          node.removeNode();
          pre.insertNodeAtEnd(lexer.newLineNode());
          pre.insertNodeAtEnd(node);
          stripSpan(lexer,node);
          node=next;
        }
        if (node == null) {
          break;
        }
      }
    }
    if (node.tag != null && TidyUtils.toBoolean(node.tag.model & Dict.CM_BLOCK) && singleSpace(lexer,node)) {
      node=stripSpan(lexer,node);
      continue;
    }
    if (node.is(TagId.STYLE) || node.is(TagId.META) || node.type == NodeType.CommentTag) {
      node=Node.discardElement(node);
      continue;
    }
    if (node.is(TagId.SPAN) || node.is(TagId.FONT)) {
      node=stripSpan(lexer,node);
      continue;
    }
    if (node.is(TagId.LINK)) {
      AttVal attr=node.getAttrByName("String_Node_Str");
      if (attr != null && attr.value != null && attr.value.equals("String_Node_Str")) {
        node=Node.discardElement(node);
        continue;
      }
    }
    if (node.tag != null && "String_Node_Str".equals(node.tag.name)) {
      Node[] next=new Node[1];
      discardContainer(node,next);
      node=next[0];
      continue;
    }
    if (node.content == null && node.is(TagId.P)) {
      node=Node.discardElement(node);
      continue;
    }
    if (node.is(TagId.P)) {
      AttVal attr=node.getAttrByName("String_Node_Str");
      AttVal atrStyle=node.getAttrByName("String_Node_Str");
      if (attr != null && attr.value != null && ((attr.value.equals("String_Node_Str") || attr.value.equals("String_Node_Str")) || (atrStyle != null && (atrStyle.value.indexOf("String_Node_Str") != -1)))) {
        TagId listType=TagId.UL;
        if (attr.value.equals("String_Node_Str")) {
          listType=TagId.OL;
        }
        Node.coerceNode(lexer,node,TagId.LI,false,true);
        if (list == null || !list.is(listType)) {
          list=lexer.inferredTag(listType);
          Node.insertNodeBeforeElement(node,list);
        }
        purgeWord2000Attributes(node);
        if (node.content != null) {
          cleanWord2000(lexer,node.content);
        }
        node.removeNode();
        list.insertNodeAtEnd(node);
        node=list;
      }
 else       if (attr != null && attr.value != null && attr.value.equals("String_Node_Str")) {
        Node br=lexer.newLineNode();
        normalizeSpaces(lexer,node);
        if (list == null || !list.is(TagId.PRE)) {
          list=lexer.inferredTag(TagId.PRE);
          Node.insertNodeBeforeElement(node,list);
        }
        node.removeNode();
        list.insertNodeAtEnd(node);
        stripSpan(lexer,node);
        list.insertNodeAtEnd(br);
        node=list.next;
      }
 else {
        list=null;
      }
    }
 else {
      list=null;
    }
    if (node.type == NodeType.StartTag || node.type == NodeType.StartEndTag) {
      purgeWord2000Attributes(node);
    }
    if (node.content != null) {
      cleanWord2000(lexer,node.content);
    }
    node=node.next;
  }
}