Exemplo n.º 1
0
nsresult FBMLContentSink::AddComment(const nsIParserNode& aNode) {
  PRInt32 tagId = aNode.GetNodeType();

#ifdef VERBOSE_LOGGING
  printf("AddComment: %d\n", tagId);
  string text;
  nsString stext(aNode.GetText());
  UTF16ToStdString(text, stext);
  printf("\tComment Text: [%s]\n", text.c_str());
#endif

  if (mPreserveComment) {
    OpenContainer(aNode);
    PRInt32 lineNo = aNode.GetSourceLineNumber();
    fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo);
    string text;
    nsString stext(aNode.GetText());
    UTF16ToStdString(text, stext);
    node->text = strdup(text.c_str());

    CloseContainer((nsHTMLTag)tagId);
  }
  return NS_OK;
}
Exemplo n.º 2
0
nsresult FBMLContentSink::OpenContainer(const nsIParserNode& aNode) {
  PRInt32 tagId = aNode.GetNodeType();
  bool attrSpecial = false;
  contexts *back_contexts;
  PRInt32 attrId;
#ifdef VERBOSE_LOGGING
  printf("OpenContainer: %d [%s]\n", tagId,
         GetTagName((nsHTMLTag)tagId).c_str());
#endif
  if (mRuleStack.empty()) {
    back_contexts = NULL;
  } else {
    back_contexts = mRuleStack.back();
  }
  if (tagId == eHTMLTag_userdefined) {
    string text;
    nsString stext(aNode.GetText());
    UTF16ToStdString(text, stext);

    PRInt32 lineNo = aNode.GetSourceLineNumber();
    char errorMsg[512];
    snprintf(errorMsg, sizeof(errorMsg),
             "FBML Error (line %d): unknown tag \"%s\"\n",
             (int)lineNo, text.c_str());
    mError += errorMsg;
  } else if (!mSkipSchemaChecking && mCurrent && back_contexts) {
    // check illegal children

    vector<vector<char> > &rules = back_contexts->tag_rules;
    if (tagId >= 0 && tagId < rules.size()) {
      for (fbml_node *p = mCurrent; p; p = p->parent) {
        unsigned short parentTagId = p->eHTMLTag;
        if (parentTagId >= rules.size() || rules[tagId][parentTagId]) {
          PRInt32 lineNo = aNode.GetSourceLineNumber();
          char errorMsg[512];
          snprintf(errorMsg, sizeof(errorMsg),
                   "FBML Error (line %d): illegal tag \"%s\" under \"%s\"\n",
                   (int)lineNo,
                   GetTagName((nsHTMLTag)tagId).c_str(),
                   GetTagName((nsHTMLTag)parentTagId).c_str());
          mError += errorMsg;
          tagId = eHTMLTag_userdefined; // nuke it
        }
      }
    }
  }

  PRInt32 lineNo = aNode.GetSourceLineNumber();
  fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo);
  if (node) {
    int count = aNode.GetAttributeCount();
    for (int i = 0; i < count; i++) {
      string n; nsString sn(aNode.GetKeyAt(i));   UTF16ToStdString(n, sn);
      string v; nsString sv(aNode.GetValueAt(i)); UTF16ToUTF8String(v, sv);
      attrId = nsHTMLAttrs::LookupAttr(sn);
      char attrFlag = GetAttrFlag(attrId);
      // If we are in internal page skip all these checks
      if (mSkipSchemaChecking) {
        fbml_node_add_attribute(node, (char*)n.c_str(), (char*)v.c_str(), attrFlag, 1);
        continue;
      }


      bool fail = false;
      for (char *p = (char*)n.c_str(); *p; p++) {
        if (*p >= 'A' && *p <= 'Z') *p |= 0x20;
        // make sure attrs are well formed
        if (*p != ':' && *p !='_' && *p != '-' && (*p<'a' || *p>'z') && (*p<'0' || *p>'9') ) {
          fail = true;
          break;
        }

      }
      if (fail) {
        PRInt32 lineNo = aNode.GetSourceLineNumber();
        char errorMsg[512];
        snprintf(errorMsg, sizeof(errorMsg),
                 "FBML Error (line %d): illegal attr \"%s\" in tag \"%s\". Attribute names can only contain alphanumeric characters, underscores, and hyphens.",
                 (int)lineNo,
                 n.c_str(),
                 GetTagName((nsHTMLTag)tagId).c_str()
                 );
        mError += errorMsg;

      }
      // check schema
      else if (back_contexts && attrId >= 0 &&
          attrId < back_contexts->attr_rules.size() &&
          back_contexts->attr_rules[attrId]) {
        PRInt32 lineNo = aNode.GetSourceLineNumber();
        char errorMsg[512];
        snprintf(errorMsg, sizeof(errorMsg),
                 "FBML Error (line %d): illegal attr \"%s\" in tag \"%s\" under \"%s\"\n",
                 (int)lineNo,
                 n.c_str(),
                 GetTagName((nsHTMLTag)tagId).c_str(),
                 back_contexts->tag_name.c_str());
        mError += errorMsg;
      }  else if (mCSSSanitizer && (attrFlag & FB_FLAG_ATTR_STYLE)) {
        char *sanitized_css = NULL;
        char *error = NULL;
        int ret = fbml_sanitize_css((char*)v.c_str(), 1, lineNo,
                                    mCSSSanitizer, &sanitized_css, &error);
        if (sanitized_css) {
          fbml_node_add_attribute(node, (char*)n.c_str(), sanitized_css, attrFlag, 0);
        }
        if (error) {
          mError += error;
          free(error);
        }
      } else if (mJSSanitizer && (attrFlag & FB_FLAG_ATTR_SCRIPT)) {
        char *sanitized_js = NULL;
        char *error = NULL;
        int ret = fbml_sanitize_js((char*)v.c_str(), v.length(), 1, lineNo,
                                   mJSSanitizer, &sanitized_js, &error);
        if (sanitized_js) {

          if (mJSSanitizer->pfunc_eh_translator) {
            char *translated = mJSSanitizer->pfunc_eh_translator
              (sanitized_js, mJSSanitizer->eh_translate_data);
            free(sanitized_js);
            sanitized_js = translated;
          }


          fbml_node_add_attribute(node, (char*)n.c_str(), sanitized_js, attrFlag, 0);
        }
        if (error) {
          mError += error;
          free(error);
        }
      } else if (mRewriter && mRewriter->pfunc_rewriter && (attrFlag & FB_FLAG_ATTR_REWRITE)){
        char *rewritten_attr =
          mRewriter->pfunc_rewriter((char *)GetTagName((nsHTMLTag)tagId).c_str(),
                                    (char *)n.c_str(),
                                    (char *)v.c_str(), mRewriter->rewrite_data);
        fbml_node_add_attribute(node, (char*)n.c_str(), rewritten_attr, attrFlag, 0);

      } else {
        if (attrFlag & FB_FLAG_ATTR_SPECIAL) {
          attrSpecial = true;
        }
        fbml_node_add_attribute(node, (char*)n.c_str(), (char*)v.c_str(), attrFlag, 1);
      }
    }

    if (attrSpecial) {
      fbml_node_add_flags(node, FB_FLAG_HAS_SPECIAL_ATTR);
    }
    mCurrent = node;

    if (!mSkipSchemaChecking && tagId >= 0 && tagId < m_context_rules.size()) {
      contexts *rule = &m_context_rules[tagId];
      if (rule &&
          (!rule->tag_rules.empty() || !rule->attr_rules.empty())) {
        mRuleStack.push_back(rule);
      } else if (mRuleStack.empty()) {
        mRuleStack.push_back(NULL);
      } else {
        mRuleStack.push_back(mRuleStack.back());
      }
    } else {
      mRuleStack.push_back(NULL);
    }
  }
  return NS_OK;
}
Exemplo n.º 3
0
nsresult FBMLContentSink::AddLeaf(const nsIParserNode& aNode) {
  PRInt32 tagId = aNode.GetNodeType();

#ifdef VERBOSE_LOGGING
  printf("AddLeaf: %d [%s] Attribute Count: [%d]\n", tagId,
         GetTagName((nsHTMLTag)tagId).c_str(), aNode.GetAttributeCount());
  string text;
  nsString stext(aNode.GetText());
  UTF16ToStdString(text, stext);
  printf("\tLeaf Text: [%s]\n", text.c_str());
#endif
  if (tagId == eHTMLTag_title || tagId == eHTMLTag_script ||
      (GetFlag(tagId) & FB_FLAG_STYLE)) {
    nsCOMPtr<nsIDTD> dtd;
    mParser->GetDTD(getter_AddRefs(dtd));
    nsAutoString script;
    PRInt32 lineNo = 0;
    dtd->CollectSkippedContent(tagId, script, lineNo);
    string text;
    UTF16ToStdString(text, script);
#ifdef VERBOSE_LOGGING
    printf("\tCollected Content:: [%s]\n", text.c_str());
#endif

    OpenContainer(aNode);
    fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo);

    if (mCSSSanitizer && (GetFlag(tagId) & FB_FLAG_STYLE)) {
      char *sanitized_css = NULL;
      char *error = NULL;
      int ret = fbml_sanitize_css((char*)text.c_str(), 0, lineNo,
                                  mCSSSanitizer, &sanitized_css, &error);
      if (sanitized_css) {
        node->text = sanitized_css;
      }
      if (error) {
        mError += error;
        free(error);
      }
    } else if (mJSSanitizer && tagId == eHTMLTag_script) {
      char *sanitized_js = NULL;
      char *error = NULL;
      int ret = fbml_sanitize_js((char*)text.c_str(), text.length(), 0,
                                 lineNo, mJSSanitizer, &sanitized_js,
                                 &error);
      if (sanitized_js) {
        node->text = sanitized_js;
      }
      if (error) {
        mError += error;
        free(error);
      }
    } else {
      node->text = strdup(text.c_str());
    }

    CloseContainer((nsHTMLTag)tagId);
    return NS_OK;
  }


  switch (aNode.GetTokenType()) {
  case eToken_start:
    OpenContainer(aNode);
    CloseContainer((nsHTMLTag)tagId);
    break;
  case eToken_text:
  case eToken_whitespace:
  case eToken_newline:
    {
      PRInt32 lineNo = aNode.GetSourceLineNumber();
      fbml_node *node = fbml_node_add_child(mCurrent, tagId, GetFlag(tagId), lineNo);
      string text;
      nsString stext(aNode.GetText());
      UTF16ToStdString(text, stext);
      node->text = strdup(text.c_str());
    }
    break;
  }
  return NS_OK;
}