nsresult nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) { WriteTabs(mOutput,1+mLevel); nsAutoString tmp; PRInt32 ac = aNode.GetAttributeCount(); for (PRInt32 i = 0; i < ac; ++i) { char* key=nsnull; char* value=nsnull; const nsAString& k = aNode.GetKeyAt(i); const nsAString& v = aNode.GetValueAt(i); GetNewCString(k, &key); if(key) { PR_fprintf(mOutput, " <attr key=\"%s\" value=\"", key); nsMemory::Free(key); } tmp.Truncate(); tmp.Append(v); if(!tmp.IsEmpty()) { PRUnichar first = tmp.First(); if ((first == '"') || (first == '\'')) { if (tmp.Last() == first) { tmp.Cut(0, 1); PRInt32 pos = tmp.Length() - 1; if (pos >= 0) { tmp.Cut(pos, 1); } } else { // Mismatched quotes - leave them in } } GetNewCString(tmp, &value); if(value) { PR_fprintf(mOutput, "%s\"/>\n", value); WriteTabs(mOutput,1+mLevel); nsMemory::Free(value); } } } WriteTabs(mOutput,1+mLevel); return NS_OK; }
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; }