示例#1
0
TEST(ng_charreach, set) {
    CharReach cr;

    ASSERT_EQ(0U, cr.count());
    ASSERT_TRUE(cr.none());
    ASSERT_FALSE(cr.all());
    cr.set('q');
    ASSERT_EQ(1U, cr.count());
    cr.setall();
    ASSERT_EQ(cr.size(), cr.count());
    ASSERT_TRUE(cr.all());
}
示例#2
0
TEST(ng_charreach, dot) {
    CharReach dot = CharReach::dot();
    ASSERT_EQ(256, dot.count());
    ASSERT_TRUE(dot.all());
    for (size_t i = 0; i < 256; i++) {
        ASSERT_TRUE(dot.test(i));
    }
}
示例#3
0
TEST(ng_charreach, init) {
    CharReach cr;

    ASSERT_EQ(0U, cr.count());
    ASSERT_TRUE(cr.none());
    ASSERT_FALSE(cr.all());
    ASSERT_EQ(256U, cr.size());
}
示例#4
0
TEST(ng_charreach, flip) {
    CharReach cr;

    ASSERT_EQ(0U, cr.count());
    ASSERT_TRUE(cr.none());
    cr.flip();
    ASSERT_EQ(cr.size(), cr.count());
    ASSERT_TRUE(cr.all());
    cr.flip();
    ASSERT_EQ(0U, cr.count());
    ASSERT_TRUE(cr.none());
    cr.flip(25);
    ASSERT_FALSE(cr.none());
    ASSERT_FALSE(cr.all());
    ASSERT_EQ(1U, cr.count());
    cr.flip();
    ASSERT_EQ(cr.size() - 1, cr.count());
}
示例#5
0
TEST(ng_charreach, clear) {
    CharReach cr;

    ASSERT_EQ(0U, cr.count());
    ASSERT_TRUE(cr.none());
    ASSERT_FALSE(cr.all());
    cr.set('q');
    cr.set('u');
    cr.set('a');
    cr.set('r');
    cr.set('k');
    ASSERT_EQ(5U, cr.count());
    cr.clear('r');
    ASSERT_EQ(4U, cr.count());
    ASSERT_FALSE(cr.test('r'));
    cr.setall();
    ASSERT_EQ(cr.size(), cr.count());
    ASSERT_TRUE(cr.all());
    cr.clear(0xff);
    ASSERT_FALSE(cr.all());
}
示例#6
0
static
aligned_unique_ptr<NFA> buildLbrDot(const CharReach &cr, const depth &repeatMin,
                                    const depth &repeatMax, u32 minPeriod,
                                    bool is_reset, ReportID report) {
    if (!cr.all()) {
        return nullptr;
    }

    enum RepeatType rtype = chooseRepeatType(repeatMin, repeatMax, minPeriod,
                                             is_reset);
    aligned_unique_ptr<NFA> nfa
        = makeLbrNfa<lbr_dot>(LBR_NFA_Dot, rtype, repeatMax);
    struct lbr_dot *ld = (struct lbr_dot *)getMutableImplNfa(nfa.get());

    fillNfa<lbr_dot>(nfa.get(), &ld->common, report, repeatMin, repeatMax,
                     minPeriod, rtype);

    DEBUG_PRINTF("built dot lbr\n");
    return nfa;
}
示例#7
0
/**
 * Builds a squash mask based on the pdom tree of v and the given char reach.
 * The built squash mask is a bit conservative for non-dot cases and could
 * be improved with a bit of thought.
 */
static
void buildSquashMask(NFAStateSet &mask, const NGHolder &g, NFAVertex v,
                     const CharReach &cr, const NFAStateSet &init,
                     const vector<NFAVertex> &vByIndex, const PostDomTree &tree,
                     som_type som, const vector<DepthMinMax> &som_depths,
                     const ue2::unordered_map<NFAVertex, u32> &region_map,
                     smgb_cache &cache) {
    DEBUG_PRINTF("build base squash mask for vertex %u)\n",
                 g[v].index);

    vector<NFAVertex> q;

    PostDomTree::const_iterator it = tree.find(v);
    if (it != tree.end()) {
        q.insert(q.end(), it->second.begin(), it->second.end());
    }

    const u32 v_index = g[v].index;

    while (!q.empty()) {
        NFAVertex u = q.back();
        q.pop_back();
        const CharReach &cru = g[u].char_reach;

        if ((cru & ~cr).any()) {
            /* bail: bad cr on vertex u */
            /* TODO: this could be better
             *
             * we still need to ensure that we record any paths leading to u.
             * Hence all vertices R which can reach u must be excluded from the
             * squash mask. Note: R != pdom(u) and there may exist an x in (R -
             * pdom(u)) which is in pdom(y) where y is in q. Clear ?
             */
            mask.set();
            return;
        }

        const u32 u_index = g[u].index;

        if (som) {
            /* We cannot add a state u to the squash mask of v if it may have an
             * earlier start of match offset. ie for us to add a state u to v
             * maxSomDist(u) <= minSomDist(v)
             */
            const depth &max_som_dist_u = som_depths[u_index].max;
            const depth &min_som_dist_v = som_depths[v_index].min;

            if (max_som_dist_u.is_infinite()) {
                /* it is hard to tell due to the INF if u can actually store an
                 * earlier SOM than w (state we are building the squash mask
                 * for) - need to think more deeply
                 */

                if (mustBeSetBefore(u, v, g, cache)
                    && !somMayGoBackwards(u, g, region_map, cache)) {
                    DEBUG_PRINTF("u %u v %u\n", u_index, v_index);
                    goto squash_ok;
                }
            }

           if (max_som_dist_u > min_som_dist_v) {
                /* u can't be squashed as it may be storing an earlier SOM */
                goto add_children_to_queue;
            }

        }

    squash_ok:
        mask.set(u_index);
        DEBUG_PRINTF("pdom'ed %u\n", u_index);
    add_children_to_queue:
        it = tree.find(u);
        if (it != tree.end()) {
            q.insert(q.end(), it->second.begin(), it->second.end());
        }
    }

    if (cr.all()) {
        /* the init states aren't in the pdom tree. If all their succ states
         * are set (or v), we can consider them post dominated */

        /* Note: init states will always result in a later som */
        for (size_t i = init.find_first(); i != init.npos;
             i = init.find_next(i)) {
            /* Yes vacuous patterns do exist */
            NFAVertex iv = vByIndex[i];
            for (auto w : adjacent_vertices_range(iv, g)) {
                if (w == g.accept || w == g.acceptEod) {
                    DEBUG_PRINTF("skipping %zu due to vacuous accept\n", i);
                    goto next_init_state;
                }

                u32 vert_id = g[w].index;
                if (w != iv && w != v && !mask.test(vert_id)) {
                    DEBUG_PRINTF("skipping %zu due to %u\n", i, vert_id);
                    goto next_init_state;
                }
            }
            DEBUG_PRINTF("pdom'ed %zu\n", i);
            mask.set(i);
        next_init_state:;
        }
    }

    mask.flip();
}