Ejemplo n.º 1
0
TEST(String, Regex)
{
    int flags, rc;
    const char *ptr;
    regex_t regex;

    string_regex_flags (NULL, 0, NULL);
    string_regex_flags ("", 0, NULL);

    string_regex_flags (NULL, 0, &flags);
    LONGS_EQUAL(0, flags);
    string_regex_flags ("", 0, &flags);
    LONGS_EQUAL(0, flags);
    string_regex_flags (NULL, REG_EXTENDED, &flags);
    LONGS_EQUAL(REG_EXTENDED, flags);
    string_regex_flags ("", REG_EXTENDED, &flags);
    LONGS_EQUAL(REG_EXTENDED, flags);

    ptr = string_regex_flags ("test", REG_EXTENDED, &flags);
    LONGS_EQUAL(REG_EXTENDED, flags);
    STRCMP_EQUAL("test", ptr);

    string_regex_flags ("(?e)test", 0, &flags);
    LONGS_EQUAL(REG_EXTENDED, flags);
    STRCMP_EQUAL("test", ptr);

    string_regex_flags ("(?ei)test", 0, &flags);
    LONGS_EQUAL(REG_EXTENDED | REG_ICASE, flags);
    STRCMP_EQUAL("test", ptr);

    string_regex_flags ("(?eins)test", 0, &flags);
    LONGS_EQUAL(REG_EXTENDED | REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
    STRCMP_EQUAL("test", ptr);

    string_regex_flags ("(?ins)test", REG_EXTENDED, &flags);
    LONGS_EQUAL(REG_EXTENDED | REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
    STRCMP_EQUAL("test", ptr);

    string_regex_flags ("(?ins-e)test", REG_EXTENDED, &flags);
    LONGS_EQUAL(REG_ICASE | REG_NEWLINE | REG_NOSUB, flags);
    STRCMP_EQUAL("test", ptr);

    /* compile regular expression */
    LONGS_EQUAL(-1, string_regcomp (&regex, NULL, 0));
    LONGS_EQUAL(0, string_regcomp (&regex, "", 0));
    regfree (&regex);
    LONGS_EQUAL(0, string_regcomp (&regex, "test", 0));
    regfree (&regex);
    LONGS_EQUAL(0, string_regcomp (&regex, "test", REG_EXTENDED));
    regfree (&regex);
    LONGS_EQUAL(0, string_regcomp (&regex, "(?ins)test", REG_EXTENDED));
    regfree (&regex);
}
Ejemplo n.º 2
0
char *
eval_compare (const char *expr1, int comparison, const char *expr2)
{
    int rc, string_compare, length1, length2;
    regex_t regex;
    long value1, value2;
    char *error;

    rc = 0;
    string_compare = 0;

    if (!expr1 || !expr2)
        goto end;

    if ((comparison == EVAL_COMPARE_REGEX_MATCHING)
        || (comparison == EVAL_COMPARE_REGEX_NOT_MATCHING))
    {
        if (string_regcomp (&regex, expr2,
                            REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
        {
            goto end;
        }
        rc = (regexec (&regex, expr1, 0, NULL, 0) == 0) ? 1 : 0;
        regfree (&regex);
        if (comparison == EVAL_COMPARE_REGEX_NOT_MATCHING)
            rc ^= 1;
        goto end;
    }

    length1 = strlen (expr1);
    length2 = strlen (expr2);

    /*
     * string comparison is forced if expr1 and expr2 have double quotes at
     * beginning/end
     */
    if (((length1 == 0) || ((expr1[0] == '"') && expr1[length1 - 1] == '"'))
        && ((length2 == 0) || ((expr2[0] == '"') && expr2[length2 - 1] == '"')))
    {
        string_compare = 1;
    }

    if (!string_compare)
    {
        value1 = strtol (expr1, &error, 10);
        if (!error || error[0])
            string_compare = 1;
        else
        {
            value2 = strtol (expr2, &error, 10);
            if (!error || error[0])
                string_compare = 1;
        }
    }

    if (string_compare)
        rc = strcmp (expr1, expr2);
    else
        rc = (value1 < value2) ? -1 : ((value1 > value2) ? 1 : 0);

    switch (comparison)
    {
        case EVAL_COMPARE_EQUAL:
            rc = (rc == 0);
            break;
        case EVAL_COMPARE_NOT_EQUAL:
            rc = (rc != 0);
            break;
        case EVAL_COMPARE_LESS_EQUAL:
            rc = (rc <= 0);
            break;
        case EVAL_COMPARE_LESS:
            rc = (rc < 0);
            break;
        case EVAL_COMPARE_GREATER_EQUAL:
            rc = (rc >= 0);
            break;
        case EVAL_COMPARE_GREATER:
            rc = (rc > 0);
            break;
        case EVAL_NUM_COMPARISONS:
            break;
    }

end:
    return strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
}
Ejemplo n.º 3
0
char *
eval_expression (const char *expr, struct t_hashtable *pointers,
                 struct t_hashtable *extra_vars, struct t_hashtable *options)
{
    int condition, extra_vars_eval, rc, pointers_allocated, regex_allocated;
    char *value;
    const char *prefix, *suffix;
    const char *default_prefix = EVAL_DEFAULT_PREFIX;
    const char *default_suffix = EVAL_DEFAULT_SUFFIX;
    const char *ptr_value, *regex_replace;
    struct t_gui_window *window;
    regex_t *regex;

    if (!expr)
        return NULL;

    condition = 0;
    extra_vars_eval = 0;
    pointers_allocated = 0;
    regex_allocated = 0;
    prefix = default_prefix;
    suffix = default_suffix;
    regex = NULL;
    regex_replace = NULL;

    if (pointers)
    {
        regex = (regex_t *)hashtable_get (pointers, "regex");
    }
    else
    {
        /* create hashtable pointers if it's NULL */
        pointers = hashtable_new (32,
                                  WEECHAT_HASHTABLE_STRING,
                                  WEECHAT_HASHTABLE_POINTER,
                                  NULL,
                                  NULL);
        if (!pointers)
            return NULL;
        pointers_allocated = 1;
    }

    /*
     * set window/buffer with pointer to current window/buffer
     * (if not already defined in the hashtable)
     */
    if (gui_current_window)
    {
        if (!hashtable_has_key (pointers, "window"))
            hashtable_set (pointers, "window", gui_current_window);
        if (!hashtable_has_key (pointers, "buffer"))
        {
            window = (struct t_gui_window *)hashtable_get (pointers, "window");
            if (window)
                hashtable_set (pointers, "buffer", window->buffer);
        }
    }

    /* read options */
    if (options)
    {
        /* check the type of evaluation */
        ptr_value = hashtable_get (options, "type");
        if (ptr_value && (strcmp (ptr_value, "condition") == 0))
            condition = 1;

        /* check if extra vars must be evaluated */
        ptr_value = hashtable_get (options, "extra");
        if (ptr_value && (strcmp (ptr_value, "eval") == 0))
            extra_vars_eval = 1;

        /* check for custom prefix */
        ptr_value = hashtable_get (options, "prefix");
        if (ptr_value && ptr_value[0])
            prefix = ptr_value;

        /* check for custom suffix */
        ptr_value = hashtable_get (options, "suffix");
        if (ptr_value && ptr_value[0])
            suffix = ptr_value;

        /* check for regex */
        ptr_value = hashtable_get (options, "regex");
        if (ptr_value)
        {
            regex = malloc (sizeof (*regex));
            if (string_regcomp (regex, ptr_value,
                                REG_EXTENDED | REG_ICASE) == 0)
            {
                regex_allocated = 1;
            }
            else
            {
                free (regex);
                regex = NULL;
            }
        }

        /* check for regex replacement (evaluated later) */
        ptr_value = hashtable_get (options, "regex_replace");
        if (ptr_value)
        {
            regex_replace = ptr_value;
        }
    }

    /* evaluate expression */
    if (condition)
    {
        /* evaluate as condition (return a boolean: "0" or "1") */
        value = eval_expression_condition (expr, pointers,
                                           extra_vars, extra_vars_eval,
                                           prefix, suffix);
        rc = eval_is_true (value);
        if (value)
            free (value);
        value = strdup ((rc) ? EVAL_STR_TRUE : EVAL_STR_FALSE);
    }
    else
    {
        if (regex && regex_replace)
        {
            /* replace with regex */
            value = eval_replace_regex (expr, regex, regex_replace,
                                        pointers, extra_vars, extra_vars_eval,
                                        prefix, suffix);
        }
        else
        {
            /* only replace variables in expression */
            value = eval_replace_vars (expr, pointers,
                                       extra_vars, extra_vars_eval,
                                       prefix, suffix, NULL);
        }
    }

    if (pointers_allocated)
        hashtable_free (pointers);
    if (regex && regex_allocated)
    {
        regfree (regex);
        free (regex);
    }

    return value;
}
Ejemplo n.º 4
0
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix;
    const char *ptr_start_regex, *pos_regex_message;

    if (!name || !buffer_name || !tags || !regex)
        return NULL;

    if (gui_filter_search_by_name (name))
        return NULL;

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;
    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix)
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                if (string_regcomp (regex1, regex_prefix,
                                    REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
                {
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        regex2 = malloc (sizeof (*regex2));
        if (regex2)
        {
            if (string_regcomp (regex2, pos_regex_message,
                                REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
            {
                if (regex_prefix)
                    free (regex_prefix);
                if (regex1)
                    free (regex1);
                free (regex2);
                return NULL;
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        if (tags)
        {
            new_filter->tags = (tags) ? strdup (tags) : NULL;
            new_filter->tags_array = string_split (tags, ",", 0, 0,
                                                   &new_filter->tags_count);
        }
        else
        {
            new_filter->tags = NULL;
            new_filter->tags_count = 0;
            new_filter->tags_array = NULL;
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        hook_signal_send ("filter_added",
                          WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }

    return new_filter;
}
Ejemplo n.º 5
0
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix, **tags_array, buf[512], str_error[512];
    const char *ptr_start_regex, *pos_regex_message;
    int i, rc;

    if (!name || !buffer_name || !tags || !regex)
    {
        gui_filter_new_error (name, _("not enough arguments"));
        return NULL;
    }

    if (gui_filter_search_by_name (name))
    {
        gui_filter_new_error (name,
                              _("a filter with same name already exists"));
        return NULL;
    }

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;

    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix && regex_prefix[0])
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                rc = string_regcomp (regex1, regex_prefix,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex1, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        if (pos_regex_message && pos_regex_message[0])
        {
            regex2 = malloc (sizeof (*regex2));
            if (regex2)
            {
                rc = string_regcomp (regex2, pos_regex_message,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex2, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    if (regex_prefix)
                        free (regex_prefix);
                    if (regex1)
                    {
                        regfree (regex1);
                        free (regex1);
                    }
                    free (regex2);
                    return NULL;
                }
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        new_filter->tags = (tags) ? strdup (tags) : NULL;
        new_filter->tags_count = 0;
        new_filter->tags_array = NULL;
        if (new_filter->tags)
        {
            tags_array = string_split (new_filter->tags, ",", 0, 0,
                                       &new_filter->tags_count);
            if (tags_array)
            {
                new_filter->tags_array = malloc (new_filter->tags_count *
                                                 sizeof (*new_filter->tags_array));
                if (new_filter->tags_array)
                {
                    for (i = 0; i < new_filter->tags_count; i++)
                    {
                        new_filter->tags_array[i] = string_split (tags_array[i],
                                                                  "+", 0, 0,
                                                                  NULL);
                    }
                }
                string_free_split (tags_array);
            }
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        (void) hook_signal_send ("filter_added",
                                 WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }
    else
    {
        gui_filter_new_error (name, _("not enough memory"));
    }

    return new_filter;
}
Ejemplo n.º 6
0
TEST(Eval, EvalReplaceRegex)
{
    struct t_hashtable *pointers, *extra_vars, *options;
    char *value;
    regex_t regex;

    pointers = hashtable_new (32,
                              WEECHAT_HASHTABLE_STRING,
                              WEECHAT_HASHTABLE_POINTER,
                              NULL, NULL);
    CHECK(pointers);

    extra_vars = hashtable_new (32,
                                WEECHAT_HASHTABLE_STRING,
                                WEECHAT_HASHTABLE_STRING,
                                NULL, NULL);
    CHECK(extra_vars);
    hashtable_set (extra_vars, "test", "value");

    options = hashtable_new (32,
                             WEECHAT_HASHTABLE_STRING,
                             WEECHAT_HASHTABLE_STRING,
                             NULL, NULL);
    CHECK(options);

    /* replace regex by empty string */
    hashtable_remove (pointers, "regex");
    hashtable_set (options, "regex", ".*");
    hashtable_set (options, "regex_replace", "");
    WEE_CHECK_EVAL("", "test");

    /* replace empty regex */
    hashtable_remove (pointers, "regex");
    hashtable_set (options, "regex", "");
    hashtable_set (options, "regex_replace", "abc");
    WEE_CHECK_EVAL("test", "test");

    /* replace empty regex by empty string */
    hashtable_remove (pointers, "regex");
    hashtable_set (options, "regex", "");
    hashtable_set (options, "regex_replace", "");
    WEE_CHECK_EVAL("test", "test");

    /* add brackets around URLs (regex as string) */
    hashtable_remove (pointers, "regex");
    hashtable_set (options, "regex", "\\w+://\\S+");
    hashtable_set (options, "regex_replace", "[ ${re:0} ]");
    WEE_CHECK_EVAL("test: [ https://weechat.org ]",
                   "test: https://weechat.org");

    /* add brackets around URLs (compiled regex) */
    LONGS_EQUAL(0, string_regcomp (&regex, "\\w+://\\S+",
                                   REG_EXTENDED | REG_ICASE));
    hashtable_set (pointers, "regex", &regex);
    hashtable_remove (options, "regex");
    hashtable_set (options, "regex_replace", "[ ${re:0} ]");
    WEE_CHECK_EVAL("test: [ https://weechat.org ]",
                   "test: https://weechat.org");
    regfree (&regex);

    /* hide passwords (regex as string) */
    hashtable_remove (pointers, "regex");
    hashtable_set (options, "regex", "(password=)(\\S+)");
    hashtable_set (options, "regex_replace", "${re:1}${hide:*,${re:2}}");
    WEE_CHECK_EVAL("password=*** password=***",
                   "password=abc password=def");

    /* hide passwords (compiled regex) */
    LONGS_EQUAL(0, string_regcomp (&regex, "(password=)(\\S+)",
                                   REG_EXTENDED | REG_ICASE));
    hashtable_set (pointers, "regex", &regex);
    hashtable_remove (options, "regex");
    hashtable_set (options, "regex_replace", "${re:1}${hide:*,${re:2}}");
    WEE_CHECK_EVAL("password=*** password=***",
                   "password=abc password=def");
    regfree (&regex);

    hashtable_free (pointers);
    hashtable_free (extra_vars);
    hashtable_free (options);
}