bool LightgrepController::addScanner(PatternScanner& scanner) {
  LG_Error* lgErr = 0;

  unsigned int patBegin = numeric_limits<unsigned int>::max(),
               patEnd = 0;

  int idx = -1;

  for (vector<const Handler*>::const_iterator h(scanner.handlers().begin()); h != scanner.handlers().end(); ++h) {
    bool good = false;
    if (lg_parse_pattern(ParsedPattern, (*h)->RE.c_str(), &(*h)->Options, &lgErr)) {
      for (vector<string>::const_iterator enc((*h)->Encodings.begin()); enc != (*h)->Encodings.end(); ++enc) {
        idx = lg_add_pattern(Fsm, PatternInfo, ParsedPattern, enc->c_str(), &lgErr);
        if (idx >= 0) {
          lg_pattern_info(PatternInfo, idx)->UserData = const_cast<void*>(static_cast<const void*>(&((*h)->Callback)));
          patBegin = std::min(patBegin, static_cast<unsigned int>(idx));
          good = true;
        }
      }
    }
    if (!good) {
      if (scanner.handleParseError(**h, lgErr)) {
        lg_free_error(lgErr);
        lgErr = 0;
      }
      else {
        return false;
      }      
    }
  }
  patEnd = lg_pattern_map_size(PatternInfo);
  scanner.patternRange() = make_pair(patBegin, patEnd);
  Scanners.push_back(&scanner);
  return true;
}
Example #2
0
void readWindowTest(
  uint64_t doff,
  const char* enc,
  size_t hbeg,
  size_t hend,
  size_t pre,
  size_t post,
  const std::vector<byte>& data,
  const std::vector<int32_t>& ecp,
  const std::vector<size_t>& eoff)
{
  const LG_Window inner{doff + hbeg, doff + hend};
  int32_t* chars = nullptr;
  size_t* offsets = nullptr;
  size_t clen;

  LG_Error* err = nullptr;

  const unsigned int abad = lg_read_window(
    reinterpret_cast<const char*>(data.data()),
    reinterpret_cast<const char*>(data.data()) + data.size(),
    doff,
    &inner,
    enc,
    pre,
    post,
    &chars,
    &offsets,
    &clen,
    &err
  );

  if (err) {
    const std::string msg(err->Message);
    lg_free_error(err);
    throw std::runtime_error(msg);
  }

  std::unique_ptr<int32_t[],void(*)(int32_t*)> pchars(
    chars, &lg_free_window_characters
  );

  std::unique_ptr<size_t[],void(*)(size_t*)> poff(
    offsets, &lg_free_window_offsets
  );

  const size_t ebad = std::count_if(
    ecp.begin(), ecp.end()-1, [](int32_t v){ return v < 0; }
  );

  SCOPE_ASSERT_EQUAL(ebad, abad);

  std::vector<int32_t> acp(chars, chars+clen);
  SCOPE_ASSERT_EQUAL(ecp, acp);

  std::vector<size_t> aoff(offsets, offsets+clen);
  SCOPE_ASSERT_EQUAL(eoff, aoff);
}
Example #3
0
void hitContextTest(
  uint64_t doff,
  const char* enc,
  size_t hbeg,
  size_t hend,
  size_t window,
  uint32_t repl,
  const std::vector<byte>& data,
  const std::string& estr,
  uint32_t ebad,
  size_t wbeg,
  size_t wend)
{
  const LG_Window inner{doff + hbeg, doff + hend};
  LG_Window outer;
  const char* utf8 = nullptr;

  LG_Error* err = nullptr;

  const unsigned int abad = lg_hit_context(
    reinterpret_cast<const char*>(data.data()),
    reinterpret_cast<const char*>(data.data()) + data.size(),
    doff,
    &inner,
    enc,
    window,
    repl,
    &utf8,
    &outer,
    &err
  );

  if (err) {
    const std::string msg(err->Message);
    lg_free_error(err);
    throw std::runtime_error(msg);
  }

  std::unique_ptr<const char[],void(*)(const char*)> pchars(
    utf8, &lg_free_hit_context_string
  );

  SCOPE_ASSERT_EQUAL(ebad, abad);
  SCOPE_ASSERT_EQUAL(estr, utf8);

  SCOPE_ASSERT_EQUAL(doff + wbeg, outer.begin);
  SCOPE_ASSERT_EQUAL(doff + wend, outer.end);
}
bool LightgrepController::addUserPatterns(PatternScanner& scanner, CallbackFnType* callbackPtr, const FindOptsStruct& user) {
  unsigned int patBegin = lg_pattern_map_size(PatternInfo),
               patEnd = 0;

  LG_KeyOptions opts;
  opts.FixedString = 0;
  opts.CaseInsensitive = 0;

  LG_Error *err = 0;

  for (vector<string>::const_iterator itr(user.Files.begin()); itr != user.Files.end(); ++itr) {
    ifstream file(itr->c_str(), ios::in);
    if (!file.is_open()) {
      cerr << "Could not open pattern file '" << *itr << "'." << endl;
      return false;
    }
    string contents = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());

    const char* contentsCStr = contents.c_str();
    if (lg_add_pattern_list(Fsm, PatternInfo, contentsCStr, DefaultEncodingsCStrings, 2, &opts, &err) < 0) {

      vector<string> lines;
      istringstream input(contents);
      string line;
      while (input) {
        getline(input, line);
        lines.push_back(line);
      }
      LG_Error* cur(err);
      while (cur) {
        cerr << "Error in " << *itr << ", line " << cur->Index+1 << ", pattern '" << lines[cur->Index]
          << "': " << cur->Message << endl;
        cur = cur->Next;
      }
      lg_free_error(err);
      return false;
    }
  }
  for (vector<string>::const_iterator itr(user.Patterns.begin()); itr != user.Patterns.end(); ++itr) {
    bool good = false;
    if (lg_parse_pattern(ParsedPattern, itr->c_str(), &opts, &err)) {
      for (unsigned int i = 0; i < NumDefaultEncodings; ++i) {
        if (lg_add_pattern(Fsm, PatternInfo, ParsedPattern, DefaultEncodingsCStrings[i], &err) >= 0) {
          good = true;
        }
      }
    }
    if (!good) {
      cerr << "Error on '" << *itr << "': " << err->Message << endl;
      lg_free_error(err);
      return false;
    }
  }
  patEnd = lg_pattern_map_size(PatternInfo);
  for (unsigned int i = patBegin; i < patEnd; ++i) {
    lg_pattern_info(PatternInfo, i)->UserData = const_cast<void*>(static_cast<const void*>(callbackPtr));
  }
  scanner.patternRange() = make_pair(patBegin, patEnd);
  Scanners.push_back(&scanner);
  return true;
}
Example #5
0
void STest::init(const std::vector<Pattern>& pats) {
  std::unique_ptr<PatternHandle,void(*)(PatternHandle*)> pat(
    lg_create_pattern(),
    lg_destroy_pattern
  );

  PMap = std::unique_ptr<PatternMapHandle,void(*)(PatternMapHandle*)>(
    lg_create_pattern_map(pats.size()),
    lg_destroy_pattern_map
  );

  std::unique_ptr<FSMHandle,void(*)(FSMHandle*)> fsm(
    lg_create_fsm(0),
    lg_destroy_fsm
  );

  LG_KeyOptions keyOpts;

  size_t i = 0, numErrors = 0;
  for (const Pattern& p : pats) {
    LG_Error* err = nullptr;

    keyOpts.CaseInsensitive = p.CaseInsensitive;
    keyOpts.FixedString = p.FixedString;

    lg_parse_pattern(pat.get(), p.Expression.c_str(), &keyOpts, &err);

    if (!err) {
      lg_add_pattern(
        fsm.get(), PMap.get(), pat.get(), p.Encoding.c_str(), &err
      );

      if (!err) {
        // pack the user pattern number into the void*, oh the horror
        LG_PatternInfo* pinfo = lg_pattern_info(PMap.get(), i - numErrors);
        pinfo->UserData = reinterpret_cast<void*>(i);
      }
    }

    if (err) {
      lg_free_error(err);
      ++numErrors;
    }

    ++i;
  }

  LG_ProgramOptions progOpts{1};

  Prog = std::unique_ptr<ProgramHandle,void(*)(ProgramHandle*)>(
    lg_create_program(fsm.get(), &progOpts),
    lg_destroy_program
  );

  if (Prog) {
    LG_ContextOptions ctxOpts;

    Ctx = std::unique_ptr<ContextHandle,void(*)(ContextHandle*)>(
      lg_create_context(Prog.get(), &ctxOpts),
      lg_destroy_context
    );
  }
}