示例#1
0
文件: RefEncoder.C 项目: NovaWova/wt
void EncodeRefs(WString& text, WFlags<RefEncoderOption> options)
{
  if (text.empty())
    return;

  std::string result = "<span>" + text.toUTF8() + "</span>";
  char *ctext = const_cast<char *>(result.c_str()); // Shhht it's okay !

  WApplication *app = WApplication::instance();

  try {
    xml_document<> doc;
    doc.parse<parse_comment_nodes
      | parse_validate_closing_tags
      | parse_validate_utf8
      | parse_xhtml_entity_translation>(ctext);

    EncodeRefs(doc.first_node(), app, options);

    WStringStream out;
    print(out.back_inserter(), *doc.first_node(), print_no_indenting);

    result = out.str();
  } catch (parse_error& e) {
    LOG_ERROR("Error reading XHTML string: " << e.what());
    return;
  }

  if (result.length() < 13)
    result.clear();
  else
    result = result.substr(6, result.length() - 13);

  text = WString::fromUTF8(result);
}
示例#2
0
std::string WTemplate::encode(const std::string& text) const
{
  WApplication *app = WApplication::instance();

  if (app && (encodeInternalPaths_ || app->session()->hasSessionIdInUrl())) {
    WFlags<RefEncoderOption> options;
    if (encodeInternalPaths_)
      options |= EncodeInternalPaths;
    if (app->session()->hasSessionIdInUrl())
      options |= EncodeRedirectTrampoline;
    return EncodeRefs(WString::fromUTF8(text), options).toUTF8();
  } else
    return text;
}
示例#3
0
文件: WText.C 项目: LifeGo/wt
std::string WText::formattedText() const
{
  if (text_.format == PlainText)
    return escapeText(text_.text, true).toUTF8();
  else {
    WApplication *app = WApplication::instance();
    if (flags_.test(BIT_ENCODE_INTERNAL_PATHS)
	|| app->session()->hasSessionIdInUrl()) {
      WFlags<RefEncoderOption> options;
      if (flags_.test(BIT_ENCODE_INTERNAL_PATHS))
	options |= EncodeInternalPaths;
      if (app->session()->hasSessionIdInUrl())
	options |= EncodeRedirectTrampoline;
      return EncodeRefs(text_.text, options).toUTF8();
    } else
      return text_.text.toUTF8();
  }
}
示例#4
0
void WTemplate::renderTemplateText(std::ostream& result, const WString& templateText)
{
  std::string text;

  WApplication *app = WApplication::instance();

  if (app && (encodeInternalPaths_ || app->session()->hasSessionIdInUrl())) {
    WFlags<RefEncoderOption> options;
    if (encodeInternalPaths_)
      options |= EncodeInternalPaths;
    if (app->session()->hasSessionIdInUrl())
      options |= EncodeRedirectTrampoline;
    WString t = templateText;
    EncodeRefs(t, options);
    text = t.toUTF8();
  } else
    text = templateText.toUTF8();

  std::size_t lastPos = 0;
  std::vector<WString> args;
  std::vector<std::string> conditions;
  int suppressing = 0;

  for (std::size_t pos = text.find('$'); pos != std::string::npos;
       pos = text.find('$', pos)) {

    if (!suppressing)
      result << text.substr(lastPos, pos - lastPos);

    lastPos = pos;

    if (pos + 1 < text.length()) {
      if (text[pos + 1] == '$') { // $$ -> $
	if (!suppressing)
	  result << '$';

	lastPos += 2;
      } else if (text[pos + 1] == '{') {
	std::size_t startName = pos + 2;
	std::size_t endName = text.find_first_of(" \r\n\t}", startName);

	args.clear();
	std::size_t endVar = parseArgs(text, endName, args);

	if (endVar == std::string::npos) {
	  LOG_ERROR("variable syntax error near \"" << text.substr(pos)
		    << "\"");
	  return;
	}

	std::string name = text.substr(startName, endName - startName);
	std::size_t nl = name.length();

	if (nl > 2 && name[0] == '<' && name[nl - 1] == '>') {
	  if (name[1] != '/') {
	    std::string cond = name.substr(1, nl - 2);
	    conditions.push_back(cond);
	    if (suppressing || !conditionValue(cond))
	      ++suppressing;
	  } else {
	    std::string cond = name.substr(2, nl - 3);
	    if (conditions.back() != cond) {
	      LOG_ERROR("mismatching condition block end: " << cond);
	      return;
	    }
	    conditions.pop_back();

	    if (suppressing)
	      --suppressing;
	  }
	} else {
	  if (!suppressing) {
	    std::size_t colonPos = name.find(':');

	    bool handled = false;
	    if (colonPos != std::string::npos) {
	      std::string fname = name.substr(0, colonPos);
	      std::string arg0 = name.substr(colonPos + 1);
	      args.insert(args.begin(), WString::fromUTF8(arg0));
	      if (resolveFunction(fname, args, result))
		handled = true;
	      else
		args.erase(args.begin());
	    }

	    if (!handled)
	      resolveString(name, args, result);
	  }
	}

	lastPos = endVar + 1;
      } else {
	if (!suppressing)
	  result << '$'; // $. -> $.
	lastPos += 1;
      }
    } else {
      if (!suppressing)
	result << '$'; // $ at end of template -> $
      lastPos += 1;
    }

    pos = lastPos;
  }

  result << text.substr(lastPos);
}
示例#5
0
文件: RefEncoder.C 项目: NovaWova/wt
void EncodeRefs(xml_node<> *x_node, WApplication *app,
		WFlags<RefEncoderOption> options)
{
  xml_document<> *doc = x_node->document();

  if (strcmp(x_node->name(), "a") == 0) {
    xml_attribute<> *x_href = x_node->first_attribute("href");
    if (x_href) {
      std::string path = x_href->value();
      if ((options & EncodeInternalPaths)
	  && path.length() >= 2 && path.substr(0, 2) == "#/") {
	path = path.substr(1);
	std::string addClass, url;

	if (app->environment().ajax()) {
	  url = app->bookmarkUrl(path);

	  const char *name = "onclick";
	  char *value
	    = doc->allocate_string
	    ((WT_CLASS".navigateInternalPath(event, "
	      + WWebWidget::jsStringLiteral(path) + ");").c_str());

	  xml_attribute<> *x_click = doc->allocate_attribute(name, value);
	  x_node->insert_attribute(0, x_click);

	  addClass = "Wt-rr";
	} else {
	  if (app->environment().agentIsSpiderBot())
	    url = app->bookmarkUrl(path);
	  else
	    url = app->session()->mostRelativeUrl(path);

	  addClass = "Wt-ip";
	}

	xml_attribute<> *x_class = x_node->first_attribute("class");
	std::string styleClass = x_class ? x_class->value() : std::string();

	styleClass = Utils::addWord(styleClass, addClass);

	if (x_class)
	  x_class->value(doc->allocate_string(styleClass.c_str()));
	else {
	  x_class = doc->allocate_attribute
	    ("class", doc->allocate_string(styleClass.c_str()));
	  x_node->insert_attribute(0, x_class);
	}

	x_href->value
	  (doc->allocate_string(app->resolveRelativeUrl(url).c_str()));
      } else if (options & EncodeRedirectTrampoline) {
	if (path.find("://") != std::string::npos ||
	    boost::starts_with(path, "//")) {
	  path = app->encodeUntrustedUrl(path);
	  x_href->value(doc->allocate_string(path.c_str()));
	}
      }
    }
  }

  if (options & EncodeRedirectTrampoline) {
    xml_attribute<> *x_style = x_node->first_attribute("style");

    if (x_style) {
      std::string style = x_style->value();
      if (style.find("//") != std::string::npos) {
        style = replaceUrlInStyle(style, app);
        x_style->value(doc->allocate_string(style.c_str()));
      }
    }

    if (strcmp(x_node->name(), "img") == 0) {
      xml_attribute<> *x_scr = x_node->first_attribute("src");
      if (x_scr) {
        std::string path = x_scr->value();
        if (path.find("://") != std::string::npos ||
	    boost::starts_with(path, "//")) {
          path = app->encodeUntrustedUrl(path);
          x_scr->value(doc->allocate_string(path.c_str()));
        }
      }
    }
  }

  for (xml_node<> *x_child = x_node->first_node(); x_child;
       x_child = x_child->next_sibling())
    EncodeRefs(x_child, app, options);

  if (!x_node->first_node()
      && x_node->value_size() == 0
      && !DomElement::isSelfClosingTag(x_node->name())) {
    // We need to add an emtpy data node since <div /> is illegal HTML
    // (but valid XML / XHTML)
    xml_node<> *empty
      = x_node->document()->allocate_node(node_data, 0, 0, 0, 0);
    x_node->append_node(empty);
  }
}