# Buggy code
def _get_lines(self, rows=None):
    source = self.data
    lines = self.buf
    new_rows = None

    # already fetched some number
    if rows is not None:
        # we already have the lines in the buffer
        if len(self.buf) >= rows:
            new_rows, self.buf = self.buf[:rows], self.buf[rows:]

        # need some lines
        else:
            rows -= len(self.buf)

    if new_rows is None:
        if isinstance(source, list):
            if self.pos > len(source):
                raise StopIteration
            if rows is None:
                new_rows = source[self.pos :]
                new_pos = len(source)
            else:
                new_rows = source[self.pos : self.pos + rows]
                new_pos = self.pos + rows

            # Check for stop rows. n.b.: self.skiprows is a set.
            if self.skiprows:
                new_rows = [
                    row
                    for i, row in enumerate(new_rows)
                    if not self.skipfunc(i + self.pos)
                ]

            lines.extend(new_rows)
            self.pos = new_pos

        else:
            new_rows = []
            try:
                if rows is not None:
                    for _ in range(rows):
                        new_rows.append(next(source))
                    lines.extend(new_rows)
                else:
                    rows = 0
                    while True:
                        try:
                            new_rows.append(next(source))
                            rows += 1
                        except csv.Error as inst:
                            if "newline inside string" in str(inst):
                                row_num = str(self.pos + rows)
                                msg = "EOF inside string starting with line " + row_num
                                raise Exception(msg)
                            raise
            except StopIteration:
                if self.skiprows:
                    new_rows = [
                        row
                        for i, row in enumerate(new_rows)
                        if not self.skipfunc(i + self.pos)
                    ]
                lines.extend(new_rows)
                if len(lines) == 0:
                    raise
            self.pos += len(new_rows)

        self.buf = []
    else:
        lines = new_rows

    if self.skipfooter:
        lines = lines[: -self.skipfooter]

    lines = self._check_comments(lines)
    if self.skip_blank_lines:
        lines = self._check_empty(lines)
    lines = self._check_thousands(lines)
    return self._check_decimal(lines)


# Traceback (ValueError)
from pandas.compat import StringIO

pd.read_csv(StringIO('''Date,Value
1/1/2012,100.00
1/2/2012,102.00
"a quoted junk row"morejunk'''),  skipfooter=1)

Out[21]
ERROR:root:An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line string', (1, 20))

---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-34-d8dff6b9f4a7> in <module>()
2 1/1/2012,100.00
3 1/2/2012,102.00
----> 4 "a quoted junk row" '''),  skipfooter=1)

C:\Users\chris.bartak\Documents\python-dev\pandas\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, skip_footer, doublequote, delim_whitespace, as_recarray, compact_ints, use_unsigned, low_memory, buffer_lines, memory_map, float_precision)
651                     skip_blank_lines=skip_blank_lines)
652
--> 653         return _read(filepath_or_buffer, kwds)
654
655     parser_f.__name__ = name

C:\Users\chris.bartak\Documents\python-dev\pandas\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
404
405     try:
--> 406         data = parser.read()
407     finally:
408         parser.close()

C:\Users\chris.bartak\Documents\python-dev\pandas\pandas\io\parsers.py in read(self, nrows)
977                 raise ValueError('skipfooter not supported for iteration')
978
--> 979         ret = self._engine.read(nrows)
980
981         if self.options.get('as_recarray'):

C:\Users\chris.bartak\Documents\python-dev\pandas\pandas\io\parsers.py in read(self, rows)
2066     def read(self, rows=None):
2067         try:
-> 2068             content = self._get_lines(rows)
2069         except StopIteration:
2070             if self._first_chunk:

C:\Users\chris.bartak\Documents\python-dev\pandas\pandas\io\parsers.py in _get_lines(self, rows)
2717                         while True:
2718                             try:
-> 2719                                 new_rows.append(next(source))
2720                                 rows += 1
2721                             except csv.Error as inst:

Error: ',' expected after '"'

# Fixed code
def _get_lines(self, rows=None):
    lines = self.buf
    new_rows = None

    # already fetched some number
    if rows is not None:
        # we already have the lines in the buffer
        if len(self.buf) >= rows:
            new_rows, self.buf = self.buf[:rows], self.buf[rows:]

        # need some lines
        else:
            rows -= len(self.buf)

    if new_rows is None:
        if isinstance(self.data, list):
            if self.pos > len(self.data):
                raise StopIteration
            if rows is None:
                new_rows = self.data[self.pos :]
                new_pos = len(self.data)
            else:
                new_rows = self.data[self.pos : self.pos + rows]
                new_pos = self.pos + rows

            # Check for stop rows. n.b.: self.skiprows is a set.
            if self.skiprows:
                new_rows = [
                    row
                    for i, row in enumerate(new_rows)
                    if not self.skipfunc(i + self.pos)
                ]

            lines.extend(new_rows)
            self.pos = new_pos

        else:
            new_rows = []
            try:
                if rows is not None:
                    for _ in range(rows):
                        new_rows.append(next(self.data))
                    lines.extend(new_rows)
                else:
                    rows = 0

                    while True:
                        new_row = self._next_iter_line(row_num=self.pos + rows)
                        new_rows.append(new_row)
                        rows += 1

            except StopIteration:
                if self.skiprows:
                    new_rows = [
                        row
                        for i, row in enumerate(new_rows)
                        if not self.skipfunc(i + self.pos)
                    ]
                lines.extend(new_rows)
                if len(lines) == 0:
                    raise
            self.pos += len(new_rows)

        self.buf = []
    else:
        lines = new_rows

    if self.skipfooter:
        lines = lines[: -self.skipfooter]

    lines = self._check_comments(lines)
    if self.skip_blank_lines:
        lines = self._check_empty(lines)
    lines = self._check_thousands(lines)
    return self._check_decimal(lines)