Esempio n. 1
0
def exec_(interp, cmd, r_output=None, r_return_var=None):
    space = interp.space
    if not cmd:
        raise ExitFunctionWithError('Cannot execute a blank command')
    if r_output is not None:
        if not space.is_array(r_output.deref_temp()):
            r_output.store(space.new_array_from_list([]))
        w_output = r_output.deref_unique()
    else:
        w_output = None
    try:
        pfile = create_popen_file(cmd, 'r')
    except OSError:
        raise ExitFunctionWithError('Unable to fork [%s]' % cmd, w_Null)
    last_line = ''
    while True:
        line = pfile.readline()
        if not line:
            break
        last_line = line.rstrip()
        if w_output:
            w_output.appenditem_inplace(space, space.newstr(last_line))
    exitcode = pfile.close()
    if r_return_var is not None:
        r_return_var.store(space.wrap(exitcode))
    return space.newstr(last_line)
Esempio n. 2
0
def getfullinfo_charp(re, extra, flag):
    p_result = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
    rc = _pcre.pcre_fullinfo(re, extra, flag, p_result)
    result = p_result[0]
    lltype.free(p_result, flavor='raw')
    if rc < 0:
        raise ExitFunctionWithError("Internal pcre_fullinfo() error %d" % rc)
    return result
Esempio n. 3
0
def getfullinfo_int(re, extra, flag):
    p_result = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
    rc = _pcre.pcre_fullinfo(re, extra, flag, p_result)
    result = p_result[0]
    lltype.free(p_result, flavor='raw')
    if rc < 0:
        raise ExitFunctionWithError("Internal pcre_fullinfo() error %d" % rc)
    return rffi.cast(lltype.Signed, result)
Esempio n. 4
0
def passthru(interp, cmd, r_return_var=None):
    space = interp.space
    if not cmd:
        raise ExitFunctionWithError('Cannot execute a blank command')
    try:
        pfile = create_popen_file(cmd, 'r')
    except OSError:
        raise ExitFunctionWithError('Unable to fork [%s]' % cmd, w_Null)
    last_line = ''
    while True:
        line = pfile.read()
        if not line:
            break
        interp.writestr(line, buffer=False)
    exitcode = pfile.close()
    if r_return_var is not None:
        r_return_var.store(space.wrap(exitcode))
    return space.newstr(last_line)
Esempio n. 5
0
def preg_match(interp, pattern, subject, w_matches=None, flags=0, offset=0):
    pce = get_compiled_regex_cache(interp, pattern)
    offset_capture = (flags & PREG_OFFSET_CAPTURE) != 0
    if flags & 0xff:
        raise ExitFunctionWithError("Invalid flags specified")
    return match_impl(interp,
                      pce,
                      subject,
                      w_matches,
                      offset,
                      mode=MODE_MATCH,
                      limit=1,
                      flags=PREG_SPLIT_OFFSET_CAPTURE if offset_capture else 0)
Esempio n. 6
0
def make_subpats_table(capturecount, re, extra):
    num_subpats = capturecount + 1
    subpat_names = [None] * num_subpats

    name_cnt = getfullinfo_int(re, extra, _pcre.PCRE_INFO_NAMECOUNT)
    if name_cnt > 0:
        name_table = getfullinfo_charp(re, extra, _pcre.PCRE_INFO_NAMETABLE)
        name_size = getfullinfo_int(re, extra, _pcre.PCRE_INFO_NAMEENTRYSIZE)
        for i in range(name_cnt):
            name_idx = 0xff * ord(name_table[0]) + ord(name_table[1])
            name = rffi.charp2str(rffi.ptradd(name_table, 2))
            try:
                int(name)
            except ValueError:
                pass
            else:
                raise ExitFunctionWithError("Numeric named subpatterns "
                                            "are not allowed")
            subpat_names[name_idx] = name
            name_table = rffi.ptradd(name_table, name_size)
    return subpat_names
Esempio n. 7
0
def get_compiled_regex_cache(interp, regex):
    pce = interp.space.regex_cache.get(regex)
    if pce is not None:
        return pce

    if '\x00' in regex:
        raise ExitFunctionWithError("Null byte in regex")

    # Parse through the leading whitespace, and display a warning if we
    # get to the end without encountering a delimiter.
    i = 0
    while i < len(regex) and regex[i].isspace():
        i += 1
    if i == len(regex):
        raise ExitFunctionWithError("Empty regular expression")

    # Get the delimiter and display a warning if it is alphanumeric
    # or a backslash.
    delimiter = regex[i]
    if delimiter.isalnum() or delimiter == '\\':
        raise ExitFunctionWithError("Delimiter must not be alphanumeric "
                                    "or backslash")
    i += 1
    pattern_start = i
    start_delimiter = delimiter
    if delimiter == '(': delimiter = ')'
    elif delimiter == '[': delimiter = ']'
    elif delimiter == '{': delimiter = '}'
    elif delimiter == '<': delimiter = '>'
    end_delimiter = delimiter

    if start_delimiter == end_delimiter:
        # We need to iterate through the pattern, searching for the
        # ending delimiter, but skipping the backslashed delimiters.
        # If the ending delimiter is not found, display a warning.
        while i < len(regex):
            if regex[i] == '\\':
                i += 1
            elif regex[i] == end_delimiter:
                break
            i += 1
        else:
            raise ExitFunctionWithError("No ending delimiter '%s' found" %
                                        delimiter[:])
    else:
        # We iterate through the pattern, searching for the matching
        # ending delimiter. For each matching starting delimiter, we
        # increment nesting level, and decrement it for each matching
        # ending delimiter. If we reach the end of the pattern without
        # matching, display a warning.
        brackets = 1  # brackets nesting level
        while i < len(regex):
            if regex[i] == '\\':
                i += 1
            elif regex[i] == end_delimiter:
                brackets -= 1
                if brackets == 0:
                    break
            elif regex[i] == start_delimiter:
                brackets += 1
            i += 1
        else:
            raise ExitFunctionWithError("No ending matching delimiter '%s' "
                                        "found" % delimiter[:])
    # Move on to the options
    pattern_end = i
    i += 1

    # Parse through the options, setting appropriate flags.  Display
    # a warning if we encounter an unknown modifier.
    coptions = 0
    poptions = 0
    do_study = False
    while i < len(regex):
        option = regex[i]
        i += 1
        # Perl compatible options
        if option == 'i': coptions |= _pcre.PCRE_CASELESS
        elif option == 'm': coptions |= _pcre.PCRE_MULTILINE
        elif option == 's': coptions |= _pcre.PCRE_DOTALL
        elif option == 'x':
            coptions |= _pcre.PCRE_EXTENDED
            # PCRE specific options
        elif option == 'A':
            coptions |= _pcre.PCRE_ANCHORED
        elif option == 'D':
            coptions |= _pcre.PCRE_DOLLAR_ENDONLY
        elif option == 'S':
            do_study = True
        elif option == 'U':
            coptions |= _pcre.PCRE_UNGREEDY
        elif option == 'X':
            coptions |= _pcre.PCRE_EXTRA
        elif option == 'u':
            coptions |= _pcre.PCRE_UTF8
            if _pcre.PCRE_UCP is not None:
                coptions |= _pcre.PCRE_UCP
        # Custom preg options
        elif option == 'e':
            poptions |= PREG_REPLACE_EVAL
            raise ExitFunctionWithError("The deprecated /e modifier is not "
                                        "supported by hippy")

        elif option == ' ':
            pass
        elif option == '\n':
            pass
        else:
            raise ExitFunctionWithError("Unknown modifier '%s'" % option[:])

    # XXX missing:
    #if HAVE_SETLOCALE
    #  if (strcmp(locale, "C"))
    #      tables = pcre_maketables();
    #endif

    # Make a copy of the actual pattern.
    length = pattern_end - pattern_start
    pattern = lltype.malloc(rffi.CCHARP.TO, length + 1, flavor='raw')
    copy_string_to_raw(llstr(regex), pattern, pattern_start, length)
    pattern[length] = '\x00'

    # Compile pattern and display a warning if compilation failed.
    p_error = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw', zero=True)
    p_erroffset = lltype.malloc(rffi.INTP.TO, 1, flavor='raw', zero=True)
    tables = lltype.nullptr(rffi.CCHARP.TO)

    re = _pcre.pcre_compile(pattern, coptions, p_error, p_erroffset, tables)

    error = p_error[0]
    erroffset = rffi.cast(lltype.Signed, p_erroffset[0])
    lltype.free(p_erroffset, flavor='raw')
    lltype.free(p_error, flavor='raw')
    lltype.free(pattern, flavor='raw')
    # All three raw mallocs above are now freed

    if not re:
        raise ExitFunctionWithError("Compilation failed: %s at offset %d" %
                                    (rffi.charp2str(error), erroffset))

    # If study option was specified, study the pattern and
    # store the result in extra for passing to pcre_exec.
    extra = lltype.nullptr(_pcre.pcre_extra)
    if do_study:
        soptions = 0
        #if _pcre.PCRE_STUDY_JIT_COMPILE is not None:
        #    soptions |= _pcre.PCRE_STUDY_JIT_COMPILE
        p_error = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw', zero=True)
        extra = _pcre.pcre_study(re, soptions, p_error)
        error = p_error[0]
        lltype.free(p_error, flavor='raw')
        if error:
            interp.warn("Error while studying pattern")
    if not extra:
        extra = _pcre.hippy_pcre_extra_malloc()
    rffi.setintfield(
        extra, 'c_flags',
        rffi.getintfield(extra, 'c_flags') | _pcre.PCRE_EXTRA_MATCH_LIMIT
        | _pcre.PCRE_EXTRA_MATCH_LIMIT_RECURSION)

    capturecount = getfullinfo_int(re, extra, _pcre.PCRE_INFO_CAPTURECOUNT)
    assert capturecount >= 0

    subpat_names = make_subpats_table(capturecount, re, extra)

    pce = PCE(
        re,
        extra,
        poptions,
        coptions,  # XXX also locale and tables
        capturecount,
        subpat_names)

    interp.space.regex_cache.set(regex, pce)
    return pce
Esempio n. 8
0
def _get_hash_algo(algo):
    try:
        return _hash_algos[algo]()
    except KeyError:
        raise ExitFunctionWithError("Unknown hashing algorithm: %s" % algo,
                                    return_value=w_False)