コード例 #1
0
    def test_simple(self):
        indexed_sourcemap = sourcemap_to_index(sourcemap)

        result = find_source(indexed_sourcemap, 1, 56)

        assert result == SourceMap(dst_line=0,
                                   dst_col=50,
                                   src='file2.js',
                                   src_line=0,
                                   src_col=9,
                                   name='multiply')
コード例 #2
0
ファイル: fetch_source.py プロジェクト: xssworm/sentry
def fetch_sourcemap(url):
    result = fetch_url(url)
    if result == BAD_SOURCE:
        return

    body = result.body
    # According to spec (https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.h7yy76c5il9v)
    # A SourceMap may be prepended with ")]}'" to cause a Javascript error.
    # If the file starts with that string, ignore the entire first line.
    if body.startswith(")]}'"):
        body = body.split('\n', 1)[1]
    try:
        index = sourcemap_to_index(body)
    except (JSONDecodeError, ValueError):
        return
    else:
        return index
コード例 #3
0
ファイル: fetch_source.py プロジェクト: netoxico/sentry
def fetch_sourcemap(url):
    result = fetch_url(url)
    if result == BAD_SOURCE:
        return

    body = result.body
    # According to spec (https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.h7yy76c5il9v)
    # A SourceMap may be prepended with ")]}'" to cause a Javascript error.
    # If the file starts with that string, ignore the entire first line.
    if body.startswith(")]}'"):
        body = body.split("\n", 1)[1]
    try:
        index = sourcemap_to_index(body)
    except (JSONDecodeError, ValueError):
        return
    else:
        return index
コード例 #4
0
ファイル: fetch_source.py プロジェクト: Epictetus/sentry-1
def fetch_sourcemap(url, logger=None):
    result = fetch_url(url, logger=logger)
    if result == BAD_SOURCE:
        return

    body = result.body
    # According to spec (https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.h7yy76c5il9v)
    # A SourceMap may be prepended with ")]}'" to cause a Javascript error.
    # If the file starts with that string, ignore the entire first line.
    if body.startswith(")]}'"):
        body = body.split('\n', 1)[1]
    try:
        index = sourcemap_to_index(body)
    except JSONDecodeError:
        if logger:
            logger.warning('Failed parsing sourcemap JSON: %r', body[:15], exc_info=True)
    else:
        return index
コード例 #5
0
ファイル: fetch_source.py プロジェクト: launch73/sentry
def fetch_sourcemap(url, logger=None):
    result = fetch_url(url, logger=logger)
    if result == BAD_SOURCE:
        return

    body = result.body
    # According to spec (https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.h7yy76c5il9v)
    # A SourceMap may be prepended with ")]}'" to cause a Javascript error.
    # If the file starts with that string, ignore the entire first line.
    if body.startswith(")]}'"):
        body = body.split('\n', 1)[1]
    try:
        index = sourcemap_to_index(body)
    except JSONDecodeError:
        if logger:
            logger.warning('Failed parsing sourcemap JSON: %r',
                           body[:15],
                           exc_info=True)
    else:
        return index
コード例 #6
0
ファイル: fetch_source.py プロジェクト: hfeeki/sentry
def fetch_javascript_source(event, **kwargs):
    """
    Attempt to fetch source code for javascript frames.

    Frames must match the following requirements:

    - lineno >= 0
    - colno >= 0
    - abs_path is the HTTP URI to the source
    - context_line is empty
    """
    logger = fetch_javascript_source.get_logger()

    try:
        stacktrace = event.data["sentry.interfaces.Stacktrace"]
    except KeyError:
        logger.debug("No stacktrace for event %r", event.id)
        return

    # build list of frames that we can actually grab source for
    frames = [
        f
        for f in stacktrace["frames"]
        if f.get("lineno") is not None
        and f.get("context_line") is None
        and f.get("abs_path", "").startswith(("http://", "https://"))
    ]
    if not frames:
        logger.debug("Event %r has no frames with enough context to fetch remote source", event.id)
        return

    file_list = set()
    sourcemap_capable = set()
    source_code = {}
    sourcemaps = {}

    for f in frames:
        file_list.add(f["abs_path"])
        if f.get("colno") is not None:
            sourcemap_capable.add(f["abs_path"])

    while file_list:
        filename = file_list.pop()

        # TODO: respect cache-contro/max-age headers to some extent
        logger.debug("Fetching remote source %r", filename)
        result = fetch_url(filename)

        if result == BAD_SOURCE:
            continue

        # If we didn't have a colno, a sourcemap wont do us any good
        if filename not in sourcemap_capable:
            source_code[filename] = (result.body.splitlines(), None)
            continue

        # TODO: we're currently running splitlines twice
        sourcemap = discover_sourcemap(result, logger=logger)
        source_code[filename] = (result.body.splitlines(), sourcemap)
        if sourcemap:
            logger.debug("Found sourcemap %r for minified script %r", sourcemap, result.url)

        # pull down sourcemap
        if sourcemap and sourcemap not in sourcemaps:
            result = fetch_url(sourcemap, logger=logger)
            if result == BAD_SOURCE:
                continue

            index = sourcemap_to_index(result.body)
            sourcemaps[sourcemap] = index

            # queue up additional source files for download
            for source in index.sources:
                if source not in source_code:
                    file_list.add(urljoin(result.url, source))

    for frame in frames:
        try:
            source, sourcemap = source_code[frame["abs_path"]]
        except KeyError:
            # we must've failed pulling down the source
            continue

        if frame.get("colno") and sourcemap:
            state = find_source(sourcemaps[sourcemap], frame["lineno"], frame["colno"])
            # TODO: is this urljoin right? (is it relative to the sourcemap or the originating file)
            abs_path = urljoin(sourcemap, state.src)
            logger.debug("Mapping compressed source %r to mapping in %r", frame["abs_path"], abs_path)
            try:
                source, _ = source_code[abs_path]
            except KeyError:
                pass
            else:
                # Store original data in annotation
                frame["data"] = {
                    "orig_lineno": frame["lineno"],
                    "orig_colno": frame["colno"],
                    "orig_function": frame["function"],
                    "orig_abs_path": frame["abs_path"],
                    "orig_filename": frame["filename"],
                    "sourcemap": sourcemap,
                }

                # SourceMap's return zero-indexed lineno's
                frame["lineno"] = state.src_line + 1
                frame["colno"] = state.src_col
                frame["function"] = state.name
                frame["abs_path"] = abs_path
                frame["filename"] = state.src

        # TODO: theoretically a minified source could point to another mapped, minified source
        frame["pre_context"], frame["context_line"], frame["post_context"] = get_source_context(
            source=source, lineno=int(frame["lineno"])
        )

    event.update(data=event.data)
コード例 #7
0
ファイル: fetch_source.py プロジェクト: x100up/sentry
def fetch_javascript_source(event, **kwargs):
    """
    Attempt to fetch source code for javascript frames.

    Frames must match the following requirements:

    - lineno >= 0
    - colno >= 0
    - abs_path is the HTTP URI to the source
    - context_line is empty
    """
    import logging
    logger = fetch_javascript_source.get_logger()
    logger.setLevel(logging.INFO)
    logger.addHandler(logging.StreamHandler())

    try:
        stacktrace = event.data['sentry.interfaces.Stacktrace']
    except KeyError:
        logger.info('No stacktrace for event %r', event.id)
        return

    # build list of frames that we can actually grab source for
    frames = [f for f in stacktrace['frames']
        if f.get('lineno') is not None
            and f.get('colno') is not None
            and f.get('abs_path', '').startswith(('http://', 'https://'))
            and f.get('context_line') is None]
    if not frames:
        logger.info('Event %r has no frames with enough context to fetch remote source', event.id)
        return

    file_list = set((f['abs_path'] for f in frames))
    source_code = {}
    sourcemaps = {}

    while file_list:
        filename = file_list.pop()

        # TODO: respect cache-contro/max-age headers to some extent
        result = fetch_url(filename)

        if result == BAD_SOURCE:
            continue

        # TODO: we're currently running splitlines twice
        sourcemap = discover_sourcemap(result, logger=logger)
        source_code[filename] = (result.body.splitlines(), sourcemap)
        if sourcemap:
            logger.info('Found sourcemap %r for minified script %r', sourcemap, result.url)

        # pull down sourcemap
        if sourcemap and sourcemap not in sourcemaps:
            result = fetch_url(sourcemap, logger=logger)
            if result == BAD_SOURCE:
                continue

            index = sourcemap_to_index(result.body)
            sourcemaps[sourcemap] = index

            # queue up additional source files for download
            for source in index.sources:
                if source not in source_code:
                    file_list.add(urljoin(result.url, source))

    for frame in frames:
        try:
            source, sourcemap = source_code[frame['abs_path']]
        except KeyError:
            # we must've failed pulling down the source
            continue

        if sourcemap:
            state = find_source(sourcemaps[sourcemap], frame['lineno'], frame['colno'])
            # TODO: is this urljoin right? (is it relative to the sourcemap or the originating file)
            abs_path = urljoin(sourcemap, state.src)
            try:
                source, _ = source_code[abs_path]
            except KeyError:
                pass
            else:
                # SourceMap's return zero-indexed lineno's
                frame['lineno'] = state.src_line + 1
                frame['colno'] = state.src_col
                frame['name'] = state.name
                frame['abs_path'] = abs_path
                frame['filename'] = state.src

        # TODO: theoretically a minified source could point to another mapped, minified source
        frame['pre_context'], frame['context_line'], frame['post_context'] = get_source_context(
            source=source, lineno=int(frame['lineno']))

    event.save()
コード例 #8
0
ファイル: tests.py プロジェクト: 755/sentry
    def test_simple(self):
        indexed_sourcemap = sourcemap_to_index(sourcemap)

        result = find_source(indexed_sourcemap, 1, 56)

        assert result == SourceMap(dst_line=0, dst_col=50, src='file2.js', src_line=0, src_col=9, name='multiply')
コード例 #9
0
ファイル: fetch_source.py プロジェクト: TracyWebTech/sentry
def fetch_javascript_source(event, **kwargs):
    """
    Attempt to fetch source code for javascript frames.

    Frames must match the following requirements:

    - lineno >= 0
    - colno >= 0
    - abs_path is the HTTP URI to the source
    - context_line is empty
    """
    logger = fetch_javascript_source.get_logger()

    try:
        stacktrace = event.data['sentry.interfaces.Stacktrace']
    except KeyError:
        logger.debug('No stacktrace for event %r', event.id)
        return

    # build list of frames that we can actually grab source for
    frames = [f for f in stacktrace['frames']
        if f.get('lineno') is not None
            and f.get('context_line') is None
            and f.get('abs_path', '').startswith(('http://', 'https://'))]
    if not frames:
        logger.debug('Event %r has no frames with enough context to fetch remote source', event.id)
        return

    file_list = set()
    sourcemap_capable = set()
    source_code = {}
    sourcemaps = {}

    for f in frames:
        file_list.add(f['abs_path'])
        if f.get('colno') is not None:
            sourcemap_capable.add(f['abs_path'])

    while file_list:
        filename = file_list.pop()

        # TODO: respect cache-contro/max-age headers to some extent
        logger.debug('Fetching remote source %r', filename)
        result = fetch_url(filename)

        if result == BAD_SOURCE:
            continue

        # If we didn't have a colno, a sourcemap wont do us any good
        if filename not in sourcemap_capable:
            source_code[filename] = (result.body.splitlines(), None)
            continue

        # TODO: we're currently running splitlines twice
        sourcemap = discover_sourcemap(result, logger=logger)
        source_code[filename] = (result.body.splitlines(), sourcemap)
        if sourcemap:
            logger.debug('Found sourcemap %r for minified script %r', sourcemap, result.url)

        # pull down sourcemap
        if sourcemap and sourcemap not in sourcemaps:
            result = fetch_url(sourcemap, logger=logger)
            if result == BAD_SOURCE:
                continue

            body = result.body
            # According to spec (https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.h7yy76c5il9v)
            # A SouceMap may be prepended with ")]}'" to cause a Javascript error.
            # If the file starts with that string, ignore the entire first line.
            if body.startswith(")]}'"):
                body = body.split('\n', 1)[1]
            index = sourcemap_to_index(body)
            sourcemaps[sourcemap] = index

            # queue up additional source files for download
            for source in index.sources:
                if source not in source_code:
                    file_list.add(urljoin(result.url, source))

    has_changes = False
    for frame in frames:
        try:
            source, sourcemap = source_code[frame['abs_path']]
        except KeyError:
            # we must've failed pulling down the source
            continue

        if frame.get('colno') and sourcemap:
            state = find_source(sourcemaps[sourcemap], frame['lineno'], frame['colno'])
            # TODO: is this urljoin right? (is it relative to the sourcemap or the originating file)
            abs_path = urljoin(sourcemap, state.src)
            logger.debug('Mapping compressed source %r to mapping in %r', frame['abs_path'], abs_path)
            try:
                source, _ = source_code[abs_path]
            except KeyError:
                pass
            else:
                # Store original data in annotation
                frame['data'] = {
                    'orig_lineno': frame['lineno'],
                    'orig_colno': frame['colno'],
                    'orig_function': frame['function'],
                    'orig_abs_path': frame['abs_path'],
                    'orig_filename': frame['filename'],
                    'sourcemap': sourcemap,
                }

                # SourceMap's return zero-indexed lineno's
                frame['lineno'] = state.src_line + 1
                frame['colno'] = state.src_col
                frame['function'] = state.name
                frame['abs_path'] = abs_path
                frame['filename'] = state.src

        has_changes = True

        # TODO: theoretically a minified source could point to another mapped, minified source
        frame['pre_context'], frame['context_line'], frame['post_context'] = get_source_context(
            source=source, lineno=int(frame['lineno']))

    if has_changes:
        event.update(data=event.data)
コード例 #10
0
ファイル: fetch_source.py プロジェクト: Supy/sentry
def fetch_javascript_source(event, **kwargs):
    """
    Attempt to fetch source code for javascript frames.

    Frames must match the following requirements:

    - lineno >= 0
    - colno >= 0
    - abs_path is the HTTP URI to the source
    - context_line is empty
    """
    logger = fetch_javascript_source.get_logger()

    try:
        stacktrace = event.data['sentry.interfaces.Stacktrace']
    except KeyError:
        logger.debug('No stacktrace for event %r', event.id)
        return

    # build list of frames that we can actually grab source for
    frames = [
        f for f in stacktrace['frames']
        if f.get('lineno') is not None and f.get('context_line') is None
        and f.get('abs_path', '').startswith(('http://', 'https://'))
    ]
    if not frames:
        logger.debug(
            'Event %r has no frames with enough context to fetch remote source',
            event.id)
        return

    file_list = set()
    sourcemap_capable = set()
    source_code = {}
    sourcemaps = {}

    for f in frames:
        file_list.add(f['abs_path'])
        if f.get('colno') is not None:
            sourcemap_capable.add(f['abs_path'])

    while file_list:
        filename = file_list.pop()

        # TODO: respect cache-contro/max-age headers to some extent
        logger.debug('Fetching remote source %r', filename)
        result = fetch_url(filename)

        if result == BAD_SOURCE:
            continue

        # If we didn't have a colno, a sourcemap wont do us any good
        if filename not in sourcemap_capable:
            source_code[filename] = (result.body.splitlines(), None)
            continue

        # TODO: we're currently running splitlines twice
        sourcemap = discover_sourcemap(result, logger=logger)
        source_code[filename] = (result.body.splitlines(), sourcemap)
        if sourcemap:
            logger.debug('Found sourcemap %r for minified script %r',
                         sourcemap, result.url)

        # pull down sourcemap
        if sourcemap and sourcemap not in sourcemaps:
            result = fetch_url(sourcemap, logger=logger)
            if result == BAD_SOURCE:
                continue

            index = sourcemap_to_index(result.body)
            sourcemaps[sourcemap] = index

            # queue up additional source files for download
            for source in index.sources:
                if source not in source_code:
                    file_list.add(urljoin(result.url, source))

    has_changes = False
    for frame in frames:
        try:
            source, sourcemap = source_code[frame['abs_path']]
        except KeyError:
            # we must've failed pulling down the source
            continue

        if frame.get('colno') and sourcemap:
            state = find_source(sourcemaps[sourcemap], frame['lineno'],
                                frame['colno'])
            # TODO: is this urljoin right? (is it relative to the sourcemap or the originating file)
            abs_path = urljoin(sourcemap, state.src)
            logger.debug('Mapping compressed source %r to mapping in %r',
                         frame['abs_path'], abs_path)
            try:
                source, _ = source_code[abs_path]
            except KeyError:
                pass
            else:
                # Store original data in annotation
                frame['data'] = {
                    'orig_lineno': frame['lineno'],
                    'orig_colno': frame['colno'],
                    'orig_function': frame['function'],
                    'orig_abs_path': frame['abs_path'],
                    'orig_filename': frame['filename'],
                    'sourcemap': sourcemap,
                }

                # SourceMap's return zero-indexed lineno's
                frame['lineno'] = state.src_line + 1
                frame['colno'] = state.src_col
                frame['function'] = state.name
                frame['abs_path'] = abs_path
                frame['filename'] = state.src

        has_changes = True

        # TODO: theoretically a minified source could point to another mapped, minified source
        frame['pre_context'], frame['context_line'], frame[
            'post_context'] = get_source_context(source=source,
                                                 lineno=int(frame['lineno']))

    if has_changes:
        event.update(data=event.data)