# Buggy code
def lint_string(
    self,
    in_str: str,
    fname: str = "<string input>",
    fix: bool = False,
    config: Optional[FluffConfig] = None,
) -> LintedFile:
    """Lint a string.

    Returns:
        :obj:`LintedFile`: an object representing that linted file.

    """
    # Sort out config, defaulting to the built in config if no override
    config = config or self.config

    # Using the new parser, read the file object.
    parsed = self.parse_string(in_str=in_str, fname=fname, config=config)
    time_dict = parsed.time_dict
    vs = parsed.violations
    tree = parsed.tree

    # Look for comment segments which might indicate lines to ignore.
    ignore_buff = []
    if tree:
        for comment in tree.recursive_crawl("comment"):
            if comment.name == "inline_comment":
                ignore_entry = self.extract_ignore_from_comment(comment)
                if isinstance(ignore_entry, SQLParseError):
                    vs.append(ignore_entry)
                elif ignore_entry:
                    ignore_buff.append(ignore_entry)
        if ignore_buff:
            linter_logger.info("Parsed noqa directives from file: %r", ignore_buff)

    if tree:
        t0 = time.monotonic()
        linter_logger.info("LINTING (%s)", fname)
        # If we're in fix mode, apply those fixes.
        # NB: We don't pass in the linting errors, because the fix function
        # regenerates them on each loop.
        if fix:
            tree, initial_linting_errors = self.fix(tree, config=config)
        else:
            initial_linting_errors = self.lint(tree, config=config)

        # Update the timing dict
        t1 = time.monotonic()
        time_dict["linting"] = t1 - t0

        # We're only going to return the *initial* errors, rather
        # than any generated during the fixing cycle.
        vs += initial_linting_errors

    # We process the ignore config here if appropriate
    if config:
        for violation in vs:
            violation.ignore_if_in(config.get("ignore"))

    linted_file = LintedFile(
        fname,
        vs,
        time_dict,
        tree,
        ignore_mask=ignore_buff,
        templated_file=parsed.templated_file,
    )

    # This is the main command line output from linting.
    if self.formatter:
        self.formatter.dispatch_file_violations(fname, linted_file, only_fixable=fix)

    # Safety flag for unset dialects
    if config.get("dialect") == "ansi" and linted_file.get_violations(
        fixable=True if fix else None, types=SQLParseError
    ):
        if self.formatter:
            self.formatter.dispatch_dialect_warning()

    return linted_file


# Traceback (IndexError)
Traceback (most recent call last):
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/bin/sqlfluff", line 11, in <module>
load_entry_point('sqlfluff', 'console_scripts', 'sqlfluff')()
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/lib/python3.6/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/lib/python3.6/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/niallwoodward/dev/pull_requests/dbt_sqlfluff_venv/lib/python3.6/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/cli/commands.py", line 323, in lint
ignore_files=not disregard_sqlfluffignores,
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/linter.py", line 1161, in lint_paths
ignore_files=ignore_files,
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/linter.py", line 1139, in lint_path
target_file.read(), fname=fname, fix=fix, config=config
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/linter.py", line 939, in lint_string
parsed = self.parse_string(in_str=in_str, fname=fname, config=config)
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/linter.py", line 723, in parse_string
tokens, lex_vs = lexer.lex(templated_file)
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/parser/lexer.py", line 343, in lex
return self.enrich_segments(segment_buff, raw), violations
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/parser/lexer.py", line 373, in enrich_segments
templated_slice
File "/Users/niallwoodward/dev/pull_requests/sqlfluff/src/sqlfluff/core/templaters/base.py", line 283, in templated_slice_to_source_slice
elif start_slices[0][0] == "literal":
IndexError: list index out of range

# Fixed code
def lint_string(
    self,
    in_str: str = "",
    fname: str = "<string input>",
    fix: bool = False,
    config: Optional[FluffConfig] = None,
) -> LintedFile:
    """Lint a string.

    Returns:
        :obj:`LintedFile`: an object representing that linted file.

    """
    # Sort out config, defaulting to the built in config if no override
    config = config or self.config

    # Using the new parser, read the file object.
    parsed = self.parse_string(in_str=in_str, fname=fname, config=config)
    time_dict = parsed.time_dict
    vs = parsed.violations
    tree = parsed.tree

    # Look for comment segments which might indicate lines to ignore.
    ignore_buff = []
    if tree:
        for comment in tree.recursive_crawl("comment"):
            if comment.name == "inline_comment":
                ignore_entry = self.extract_ignore_from_comment(comment)
                if isinstance(ignore_entry, SQLParseError):
                    vs.append(ignore_entry)
                elif ignore_entry:
                    ignore_buff.append(ignore_entry)
        if ignore_buff:
            linter_logger.info("Parsed noqa directives from file: %r", ignore_buff)

    if tree:
        t0 = time.monotonic()
        linter_logger.info("LINTING (%s)", fname)

        if fix:
            tree, initial_linting_errors = self.fix(tree, config=config)
        else:
            initial_linting_errors = self.lint(tree, config=config)

        # Update the timing dict
        t1 = time.monotonic()
        time_dict["linting"] = t1 - t0

        # We're only going to return the *initial* errors, rather
        # than any generated during the fixing cycle.
        vs += initial_linting_errors

    # We process the ignore config here if appropriate
    if config:
        for violation in vs:
            violation.ignore_if_in(config.get("ignore"))

    linted_file = LintedFile(
        fname,
        vs,
        time_dict,
        tree,
        ignore_mask=ignore_buff,
        templated_file=parsed.templated_file,
    )

    # This is the main command line output from linting.
    if self.formatter:
        self.formatter.dispatch_file_violations(fname, linted_file, only_fixable=fix)

    # Safety flag for unset dialects
    if config.get("dialect") == "ansi" and linted_file.get_violations(
        fixable=True if fix else None, types=SQLParseError
    ):
        if self.formatter:
            self.formatter.dispatch_dialect_warning()

    return linted_file