示例#1
0
def get_contextline_component(frame, platform, function, context):
    """Returns a contextline component.  The caller's responsibility is to
    make sure context lines are only used for platforms where we trust the
    quality of the sourcecode.  It does however protect against some bad
    JavaScript environments based on origin checks.
    """
    line = " ".join((frame.context_line or "").expandtabs(2).split())
    if not line:
        return GroupingComponent(id="context-line")

    component = GroupingComponent(
        id="context-line",
        values=[line],
        similarity_encoder=ident_encoder,
    )
    if line:
        if len(frame.context_line) > 120:
            component.update(hint="discarded because line too long",
                             contributes=False)
        elif get_behavior_family_for_platform(platform) == "javascript":
            if context["with_context_line_file_origin_bug"]:
                if has_url_origin(frame.abs_path, allow_file_origin=True):
                    component.update(hint="discarded because from URL origin",
                                     contributes=False)
            elif not function and has_url_origin(frame.abs_path):
                component.update(
                    hint="discarded because from URL origin and no function",
                    contributes=False)

    return component
示例#2
0
def get_filename_component(abs_path,
                           filename,
                           platform,
                           allow_file_origin=False):
    """Attempt to normalize filenames by detecting special filenames and by
    using the basename only.
    """
    if filename is None:
        return GroupingComponent(id="filename")

    # Only use the platform independent basename for grouping and
    # lowercase it
    filename = _basename_re.split(filename)[-1].lower()
    filename_component = GroupingComponent(id="filename", values=[filename])

    if has_url_origin(abs_path, allow_file_origin=allow_file_origin):
        filename_component.update(contributes=False,
                                  hint="ignored because frame points to a URL")
    elif filename == "<anonymous>":
        filename_component.update(contributes=False,
                                  hint="anonymous filename discarded")
    elif filename == "[native code]":
        filename_component.update(contributes=False,
                                  hint="native code indicated by filename")
    elif platform == "java":
        new_filename = _java_assist_enhancer_re.sub(r"\1<auto>", filename)
        if new_filename != filename:
            filename_component.update(values=[new_filename],
                                      hint="cleaned javassist parts")

    return filename_component
示例#3
0
def get_filename_component(
    abs_path: str,
    filename: Optional[str],
    platform: Optional[str],
    allow_file_origin: bool = False,
) -> GroupingComponent:
    """Attempt to normalize filenames by detecting special filenames and by
    using the basename only.
    """
    if filename is None:
        return GroupingComponent(id="filename")

    # Only use the platform independent basename for grouping and
    # lowercase it
    filename = _basename_re.split(filename)[-1].lower()
    filename_component = GroupingComponent(id="filename",
                                           values=[filename],
                                           similarity_encoder=ident_encoder)

    if has_url_origin(abs_path, allow_file_origin=allow_file_origin):
        filename_component.update(contributes=False,
                                  hint="ignored because frame points to a URL")
    elif filename == "<anonymous>":
        filename_component.update(contributes=False,
                                  hint="anonymous filename discarded")
    elif filename == "[native code]":
        filename_component.update(contributes=False,
                                  hint="native code indicated by filename")
    elif platform == "java":
        new_filename = _java_assist_enhancer_re.sub(r"\1<auto>", filename)
        if new_filename != filename:
            filename_component.update(values=[new_filename],
                                      hint="cleaned javassist parts")
            filename = new_filename

    # Best-effort to show a very short filename in the title. We truncate it to
    # basename so technically there can be two issues that differ in filename
    # paths but end up having the same title.
    filename_component.update(tree_label={"filebase": get_basename(filename)})

    return filename_component
示例#4
0
def get_filename_component(abs_path, filename, platform,
                           allow_file_origin=False):
    """Attempt to normalize filenames by detecing special filenames and by
    using the basename only.
    """
    if filename is None:
        return GroupingComponent(id='filename')

    # Only use the platform independent basename for grouping and
    # lowercase it
    filename = _basename_re.split(filename)[-1].lower()
    filename_component = GroupingComponent(
        id='filename',
        values=[filename],
    )

    if has_url_origin(abs_path, allow_file_origin=allow_file_origin):
        filename_component.update(
            contributes=False,
            hint='ignored because frame points to a URL',
        )
    elif filename == '<anonymous>':
        filename_component.update(
            contributes=False,
            hint='anonymous filename discarded'
        )
    elif filename == '[native code]':
        filename_component.update(
            contributes=False,
            hint='native code indicated by filename'
        )
    elif platform == 'java':
        new_filename = _java_assist_enhancer_re.sub(r'\1<auto>', filename)
        if new_filename != filename:
            filename_component.update(
                values=[new_filename],
                hint='cleaned javassist parts'
            )

    return filename_component
示例#5
0
def get_contextline_component(frame, platform):
    """Returns a contextline component.  The caller's responsibility is to
    make sure context lines are only used for platforms where we trust the
    quality of the sourcecode.  It does however protect against some bad
    JavaScript environments based on origin checks.
    """
    component = GroupingComponent(id='context-line')

    if not frame.context_line:
        return component

    line = ' '.join(frame.context_line.expandtabs(2).split())
    if line:
        if len(frame.context_line) > 120:
            component.update(hint='discarded because line too long')
        elif get_behavior_family_for_platform(platform) == 'javascript' \
                and has_url_origin(frame.abs_path, allow_file_origin=True):
            component.update(hint='discarded because from URL origin')
        else:
            component.update(values=[line])

    return component
示例#6
0
def get_contextline_component(frame, platform):
    """Returns a contextline component.  The caller's responsibility is to
    make sure context lines are only used for platforms where we trust the
    quality of the sourcecode.  It does however protect against some bad
    JavaScript environments based on origin checks.
    """
    component = GroupingComponent(id='context-line')

    if not frame.context_line:
        return component

    line = ' '.join(frame.context_line.expandtabs(2).split())
    if line:
        if len(frame.context_line) > 120:
            component.update(hint='discarded because line too long')
        elif get_behavior_family_for_platform(platform) == 'javascript' \
                and has_url_origin(frame.abs_path, allow_file_origin=True):
            component.update(hint='discarded because from URL origin')
        else:
            component.update(values=[line])

    return component
示例#7
0
def frame_legacy(frame, event, context, **meta):
    platform = frame.platform or event.platform

    # In certain situations we want to disregard the entire frame.
    contributes = None
    hint = None

    # this requires some explanation: older sentry versions did not have
    # raw_function but only function.  For some platforms like native
    # we now instead store a trimmed function name in frame.function so
    # and the original value moved to raw_function.  This requires us to
    # prioritize raw_function over function in the legacy grouping code to
    # avoid creating new groups.
    func = frame.raw_function or frame.function

    # Safari throws [native code] frames in for calls like ``forEach``
    # whereas Chrome ignores these. Let's remove it from the hashing algo
    # so that they're more likely to group together
    filename_component = GroupingComponent(id="filename",
                                           similarity_encoder=ident_encoder)
    if frame.filename == "<anonymous>":
        filename_component.update(contributes=False,
                                  values=[frame.filename],
                                  hint="anonymous filename discarded")
    elif frame.filename == "[native code]":
        contributes = False
        hint = "native code indicated by filename"
    elif frame.filename:
        if has_url_origin(frame.abs_path):
            filename_component.update(contributes=False,
                                      values=[frame.filename],
                                      hint="ignored because filename is a URL")
        # XXX(dcramer): dont compute hash using frames containing the 'Caused by'
        # text as it contains an exception value which may may contain dynamic
        # values (see raven-java#125)
        elif frame.filename.startswith("Caused by: "):
            filename_component.update(values=[frame.filename],
                                      contributes=False,
                                      hint="ignored because invalid")
        else:
            hashable_filename, hashable_filename_hint = remove_filename_outliers_legacy(
                frame.filename, platform)
            filename_component.update(values=[hashable_filename],
                                      hint=hashable_filename_hint)

    # if we have a module we use that for grouping.  This will always
    # take precedence over the filename, even if the module is
    # considered unhashable.
    module_component = GroupingComponent(id="module",
                                         similarity_encoder=ident_encoder)
    if frame.module:
        if is_unhashable_module_legacy(frame, platform):
            module_component.update(
                values=[
                    GroupingComponent(id="salt",
                                      values=["<module>"],
                                      hint="normalized generated module name")
                ],
                hint="ignored module",
            )

            # <module> still contributes, though it should not contribute to
            # similarity
            module_component.similarity_encoder = None
        else:
            module_name, module_hint = remove_module_outliers_legacy(
                frame.module, platform)
            module_component.update(values=[module_name], hint=module_hint)
        if frame.filename:
            filename_component.update(values=[frame.filename],
                                      contributes=False,
                                      hint="module takes precedence")

    # Context line when available is the primary contributor
    context_line_component = GroupingComponent(
        id="context-line", similarity_encoder=ident_encoder)
    if frame.context_line is not None:
        if len(frame.context_line) > 120:
            context_line_component.update(
                hint="discarded because line too long")
        elif has_url_origin(frame.abs_path) and not func:
            context_line_component.update(
                hint="discarded because from URL origin")
        else:
            context_line_component.update(values=[frame.context_line])

    symbol_component = GroupingComponent(id="symbol",
                                         similarity_encoder=ident_encoder)
    function_component = GroupingComponent(id="function",
                                           similarity_encoder=ident_encoder)
    lineno_component = GroupingComponent(id="lineno",
                                         similarity_encoder=ident_encoder)

    # The context line grouping information is the most reliable one.
    # If we did not manage to find some information there, we want to
    # see if we can come up with some extra information.  We only want
    # to do that if we managed to get a module of filename.
    if not context_line_component.contributes and (
            module_component.contributes or filename_component.contributes):
        if frame.symbol:
            symbol_component.update(values=[frame.symbol])
            if func:
                function_component.update(contributes=False,
                                          values=[func],
                                          hint="symbol takes precedence")
            if frame.lineno:
                lineno_component.update(contributes=False,
                                        values=[frame.lineno],
                                        hint="symbol takes precedence")
        elif func:
            if is_unhashable_function_legacy(func):
                function_component.update(values=[
                    GroupingComponent(id="salt",
                                      values=["<function>"],
                                      hint="normalized lambda function name")
                ])
                # <module> still contributes, though it should not contribute to
                # similarity
                function_component.similarity_encoder = None
            else:
                function, function_hint = remove_function_outliers_legacy(func)
                function_component.update(values=[function],
                                          hint=function_hint)
            if frame.lineno:
                lineno_component.update(contributes=False,
                                        values=[frame.lineno],
                                        hint="function takes precedence")
        elif frame.lineno:
            lineno_component.update(values=[frame.lineno])
    else:
        if context_line_component.contributes:
            fallback_hint = "is not used if context-line is available"
        else:
            fallback_hint = "is not used if module or filename are available"
        if frame.symbol:
            symbol_component.update(contributes=False,
                                    values=[frame.symbol],
                                    hint="symbol " + fallback_hint)
        if func:
            function_component.update(contributes=False,
                                      values=[func],
                                      hint="function name " + fallback_hint)
        if frame.lineno:
            lineno_component.update(contributes=False,
                                    values=[frame.lineno],
                                    hint="line number " + fallback_hint)

    return {
        context["variant"]:
        GroupingComponent(
            id="frame",
            values=[
                module_component,
                filename_component,
                context_line_component,
                symbol_component,
                function_component,
                lineno_component,
            ],
            contributes=contributes,
            hint=hint,
        )
    }
示例#8
0
def frame_legacy(frame, event, **meta):
    platform = frame.platform or event.platform

    # In certain situations we want to disregard the entire frame.
    contributes = None
    hint = None

    # this requires some explanation: older sentry versions did not have
    # raw_function but only function.  For some platforms like native
    # we now instead store a trimmed function name in frame.function so
    # and the original value moved to raw_function.  This requires us to
    # prioritize raw_function over function in the legacy grouping code to
    # avoid creating new groups.
    func = frame.raw_function or frame.function

    # Safari throws [native code] frames in for calls like ``forEach``
    # whereas Chrome ignores these. Let's remove it from the hashing algo
    # so that they're more likely to group together
    filename_component = GroupingComponent(id='filename')
    if frame.filename == '<anonymous>':
        filename_component.update(contributes=False,
                                  values=[frame.filename],
                                  hint='anonymous filename discarded')
    elif frame.filename == '[native code]':
        contributes = False
        hint = 'native code indicated by filename'
    elif frame.filename:
        if has_url_origin(frame.abs_path):
            filename_component.update(
                contributes=False,
                values=[frame.filename],
                hint='ignored because filename is a URL',
            )
        # XXX(dcramer): dont compute hash using frames containing the 'Caused by'
        # text as it contains an exception value which may may contain dynamic
        # values (see raven-java#125)
        elif frame.filename.startswith('Caused by: '):
            filename_component.update(values=[frame.filename],
                                      contributes=False,
                                      hint='ignored because invalid')
        else:
            hashable_filename, hashable_filename_hint = \
                remove_filename_outliers_legacy(frame.filename, platform)
            filename_component.update(values=[hashable_filename],
                                      hint=hashable_filename_hint)

    # if we have a module we use that for grouping.  This will always
    # take precedence over the filename, even if the module is
    # considered unhashable.
    module_component = GroupingComponent(id='module')
    if frame.module:
        if is_unhashable_module_legacy(frame, platform):
            module_component.update(
                values=[
                    GroupingComponent(id='salt',
                                      values=['<module>'],
                                      hint='normalized generated module name')
                ],
                hint='ignored module',
            )
        else:
            module_name, module_hint = \
                remove_module_outliers_legacy(frame.module, platform)
            module_component.update(values=[module_name], hint=module_hint)
        if frame.filename:
            filename_component.update(values=[frame.filename],
                                      contributes=False,
                                      hint='module takes precedence')

    # Context line when available is the primary contributor
    context_line_component = GroupingComponent(id='context-line')
    if frame.context_line is not None:
        if len(frame.context_line) > 120:
            context_line_component.update(
                hint='discarded because line too long')
        elif has_url_origin(frame.abs_path) and not func:
            context_line_component.update(
                hint='discarded because from URL origin')
        else:
            context_line_component.update(values=[frame.context_line])

    symbol_component = GroupingComponent(id='symbol')
    function_component = GroupingComponent(id='function')
    lineno_component = GroupingComponent(id='lineno')

    # The context line grouping information is the most reliable one.
    # If we did not manage to find some information there, we want to
    # see if we can come up with some extra information.  We only want
    # to do that if we managed to get a module of filename.
    if not context_line_component.contributes and \
       (module_component.contributes or filename_component.contributes):
        if frame.symbol:
            symbol_component.update(values=[frame.symbol])
            if func:
                function_component.update(contributes=False,
                                          values=[func],
                                          hint='symbol takes precedence')
            if frame.lineno:
                lineno_component.update(contributes=False,
                                        values=[frame.lineno],
                                        hint='symbol takes precedence')
        elif func:
            if is_unhashable_function_legacy(func):
                function_component.update(values=[
                    GroupingComponent(id='salt',
                                      values=['<function>'],
                                      hint='normalized lambda function name')
                ])
            else:
                function, function_hint = remove_function_outliers_legacy(func)
                function_component.update(values=[function],
                                          hint=function_hint)
            if frame.lineno:
                lineno_component.update(contributes=False,
                                        values=[frame.lineno],
                                        hint='function takes precedence')
        elif frame.lineno:
            lineno_component.update(values=[frame.lineno])
    else:
        if frame.symbol:
            symbol_component.update(
                contributes=False,
                values=[frame.symbol],
                hint='symbol is used only if module or filename are available')
        if func:
            function_component.update(
                contributes=False,
                values=[func],
                hint=
                'function name is used only if module or filename are available'
            )
        if frame.lineno:
            lineno_component.update(
                contributes=False,
                values=[frame.lineno],
                hint=
                'line number is used only if module or filename are available')

    return GroupingComponent(
        id='frame',
        values=[
            module_component,
            filename_component,
            context_line_component,
            symbol_component,
            function_component,
            lineno_component,
        ],
        contributes=contributes,
        hint=hint,
    )
示例#9
0
def frame_legacy(frame, event, **meta):
    platform = frame.platform or event.platform

    # In certain situations we want to disregard the entire frame.
    contributes = None
    hint = None

    # this requires some explanation: older sentry versions did not have
    # raw_function but only function.  For some platforms like native
    # we now instead store a trimmed function name in frame.function so
    # and the original value moved to raw_function.  This requires us to
    # prioritize raw_function over function in the legacy grouping code to
    # avoid creating new groups.
    func = frame.raw_function or frame.function

    # Safari throws [native code] frames in for calls like ``forEach``
    # whereas Chrome ignores these. Let's remove it from the hashing algo
    # so that they're more likely to group together
    filename_component = GroupingComponent(id='filename')
    if frame.filename == '<anonymous>':
        filename_component.update(
            contributes=False,
            values=[frame.filename],
            hint='anonymous filename discarded'
        )
    elif frame.filename == '[native code]':
        contributes = False
        hint = 'native code indicated by filename'
    elif frame.filename:
        if has_url_origin(frame.abs_path):
            filename_component.update(
                contributes=False,
                values=[frame.filename],
                hint='ignored because filename is a URL',
            )
        # XXX(dcramer): dont compute hash using frames containing the 'Caused by'
        # text as it contains an exception value which may may contain dynamic
        # values (see raven-java#125)
        elif frame.filename.startswith('Caused by: '):
            filename_component.update(
                values=[frame.filename],
                contributes=False,
                hint='ignored because invalid'
            )
        else:
            hashable_filename, hashable_filename_hint = \
                remove_filename_outliers_legacy(frame.filename, platform)
            filename_component.update(
                values=[hashable_filename],
                hint=hashable_filename_hint
            )

    # if we have a module we use that for grouping.  This will always
    # take precedence over the filename, even if the module is
    # considered unhashable.
    module_component = GroupingComponent(id='module')
    if frame.module:
        if is_unhashable_module_legacy(frame, platform):
            module_component.update(
                values=[GroupingComponent(
                    id='salt',
                    values=['<module>'],
                    hint='normalized generated module name'
                )],
                hint='ignored module',
            )
        else:
            module_name, module_hint = \
                remove_module_outliers_legacy(frame.module, platform)
            module_component.update(
                values=[module_name],
                hint=module_hint
            )
        if frame.filename:
            filename_component.update(
                values=[frame.filename],
                contributes=False,
                hint='module takes precedence'
            )

    # Context line when available is the primary contributor
    context_line_component = GroupingComponent(id='context-line')
    if frame.context_line is not None:
        if len(frame.context_line) > 120:
            context_line_component.update(hint='discarded because line too long')
        elif has_url_origin(frame.abs_path) and not func:
            context_line_component.update(hint='discarded because from URL origin')
        else:
            context_line_component.update(values=[frame.context_line])

    symbol_component = GroupingComponent(id='symbol')
    function_component = GroupingComponent(id='function')
    lineno_component = GroupingComponent(id='lineno')

    # The context line grouping information is the most reliable one.
    # If we did not manage to find some information there, we want to
    # see if we can come up with some extra information.  We only want
    # to do that if we managed to get a module of filename.
    if not context_line_component.contributes and \
       (module_component.contributes or filename_component.contributes):
        if frame.symbol:
            symbol_component.update(values=[frame.symbol])
            if func:
                function_component.update(
                    contributes=False,
                    values=[func],
                    hint='symbol takes precedence'
                )
            if frame.lineno:
                lineno_component.update(
                    contributes=False,
                    values=[frame.lineno],
                    hint='symbol takes precedence'
                )
        elif func:
            if is_unhashable_function_legacy(func):
                function_component.update(values=[
                    GroupingComponent(
                        id='salt',
                        values=['<function>'],
                        hint='normalized lambda function name'
                    )
                ])
            else:
                function, function_hint = remove_function_outliers_legacy(func)
                function_component.update(
                    values=[function],
                    hint=function_hint
                )
            if frame.lineno:
                lineno_component.update(
                    contributes=False,
                    values=[frame.lineno],
                    hint='function takes precedence'
                )
        elif frame.lineno:
            lineno_component.update(values=[frame.lineno])
    else:
        if frame.symbol:
            symbol_component.update(
                contributes=False,
                values=[frame.symbol],
                hint='symbol is used only if module or filename are available'
            )
        if func:
            function_component.update(
                contributes=False,
                values=[func],
                hint='function name is used only if module or filename are available'
            )
        if frame.lineno:
            lineno_component.update(
                contributes=False,
                values=[frame.lineno],
                hint='line number is used only if module or filename are available'
            )

    return GroupingComponent(
        id='frame',
        values=[
            module_component,
            filename_component,
            context_line_component,
            symbol_component,
            function_component,
            lineno_component,
        ],
        contributes=contributes,
        hint=hint,
    )