`
edwardpro
  • 浏览: 310126 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

lexer html解析一个js过滤的改进

 
阅读更多

问题描述,使用htmlparser的lexer解析器进行页面解析时发现类似如下的页面会有问题:

 

 

<script>
for(i=0;i<a;i++){

}
</script>

解析后代码变成了:
<script>
for(i=0;i<a;i++){

}
></script>

 

 通过lexer代码发现,实际上只要js代码改成:

<script>
<!--
for(i=0;i<a;i++){

}
-->
</script>

 就不会有问题了,从代码中主要发现它的解析其实没有问题,主要是我们平时的页面规范做的不好,它在解析时会看到字符解析时发现<后面如果有字母就认为它是一个tag:

	protected Node parseString(int start, boolean quotesmart)
			throws ParserException {
		boolean done;
		char ch;
		char quote;

		done = false;
		quote = 0;
		while (!done) {
			ch = mPage.getCharacter(mCursor);
			if (Page.EOF == ch)
				done = true;
			else if (0x1b == ch) // escape
			{
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				else if ('$' == ch) {
					ch = mPage.getCharacter(mCursor);
					if (Page.EOF == ch)
						done = true;
					// JIS X 0208-1978 and JIS X 0208-1983
					else if ('@' == ch || 'B' == ch)
						scanJIS(mCursor);
					/*
					 * // JIS X 0212-1990 else if ('(' == ch) { ch =
					 * mPage.getCharacter (mCursor); if (Page.EOF == ch) done =
					 * true; else if ('D' == ch) scanJIS (mCursor); else {
					 * mPage.ungetCharacter (mCursor); mPage.ungetCharacter
					 * (mCursor); mPage.ungetCharacter (mCursor); } }
					 */
					else {
						mPage.ungetCharacter(mCursor);
						mPage.ungetCharacter(mCursor);
					}
				} else
					mPage.ungetCharacter(mCursor);
			} else if (quotesmart && (0 == quote)
					&& (('\'' == ch) || ('"' == ch)))
				quote = ch; // enter quoted state
			// patch from Gernot Fricke to handle escaped closing quote
			else if (quotesmart && (0 != quote) && ('\\' == ch)) {
				ch = mPage.getCharacter(mCursor); // try to consume escape
				if ((Page.EOF != ch) && ('\\' != ch) // escaped backslash
						&& (ch != quote)) // escaped quote character
					// ( reflects ["] or ['] whichever opened the quotation)
					mPage.ungetCharacter(mCursor); // unconsume char if char not
													// an escape
			} else if (quotesmart && (ch == quote))
				quote = 0; // exit quoted state
			else if (quotesmart && (0 == quote) && (ch == '/')) {
				// handle multiline and double slash comments (with a quote)
				// in script like:
				// I can't handle single quotations.
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				else if ('/' == ch) {
					do
						ch = mPage.getCharacter(mCursor);
					while ((Page.EOF != ch) && ('\n' != ch));
				} else if ('*' == ch) {
					do {
						do
							ch = mPage.getCharacter(mCursor);
						while ((Page.EOF != ch) && ('*' != ch));
						ch = mPage.getCharacter(mCursor);
						if (ch == '*')
							mPage.ungetCharacter(mCursor);
					} while ((Page.EOF != ch) && ('/' != ch));
				} else
					mPage.ungetCharacter(mCursor);
			} else if ((0 == quote) && ('<' == ch)) {
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				// the order of these tests might be optimized for speed:
				else if ('/' == ch
						|| Character.isLetter(ch)
						|| '!' == ch || '%' == ch || '?' == ch) {
					done = true;
					mPage.ungetCharacter(mCursor);
					mPage.ungetCharacter(mCursor);
				} else {
					// it's not a tag, so keep going, but check for quotes
					mPage.ungetCharacter(mCursor);
				}
			}
		}

		return (makeString(start, mCursor.getPosition()));
	}

 因此为了解决这个问题,现在要在上面做一个手脚:

首先在类中间增加了一个标记,script

这个标记是修改了nexNode方法,在返回前判断下是否前一个标签是<script> 或者</script>

然后在parseString中修改其解析方法就可以了,下面是完整的代码:

import java.net.URLConnection;

import org.htmlparser.Node;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.lexer.Page;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.util.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author edwardpro
 * 
 */
public class LexerFixed extends Lexer {
	private static final Logger logger = LoggerFactory
			.getLogger(LexerFixed.class);

	/**
	 * 
	 */
	private static final long serialVersionUID = 8425806017089419815L;

	//script标签标记,如果发现当前在script里就掠过所有的< >
	private int script=0;

	/**
	 * 
	 */
	public LexerFixed() {
		super();
	}

	/**
	 * @param page
	 */
	public LexerFixed(Page page) {
		super(page);
	}

	/**
	 * @param text
	 */
	public LexerFixed(String text) {
		super(text);
	}

	/**
	 * @param connection
	 * @throws ParserException
	 */
	public LexerFixed(URLConnection connection) throws ParserException {
		super(connection);
	}

	@Override
	public Node nextNode(boolean quotesmart) throws ParserException {
		Node ret = super.nextNode(quotesmart);
		checkTag(ret);
		return (ret);
	}

	/**
	 * checkTag用于修改tagNode的方法当有入参数时都会进行一次参数修正另外對內容進行一下escape操作並且會進行判斷是否存在已經escape的蹟象
	 * 
	 * @param node
	 */
	private void checkTag(Node node) {
		if (node != null && node instanceof TagNode
				&& !((TagNode) node).isEmptyXmlTag()) {
			String tagName = ((TagNode) node).getTagName();
			if("SCRIPT".equalsIgnoreCase(tagName)){
				if (!((TagNode) node).isEndTag() ) {
					this.script=1;
				} else{
					this.script=0;
				}
			}
		}
	}

	@Override
	protected Node parseString(int start, boolean quotesmart)
			throws ParserException {
		boolean done;
		char ch;
		char quote;

		done = false;
		quote = 0;
		while (!done) {
			ch = mPage.getCharacter(mCursor);
			if (Page.EOF == ch)
				done = true;
			else if (0x1b == ch) // escape
			{
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				else if ('$' == ch) {
					ch = mPage.getCharacter(mCursor);
					if (Page.EOF == ch)
						done = true;
					// JIS X 0208-1978 and JIS X 0208-1983
					else if ('@' == ch || 'B' == ch)
						scanJIS(mCursor);
					/*
					 * // JIS X 0212-1990 else if ('(' == ch) { ch =
					 * mPage.getCharacter (mCursor); if (Page.EOF == ch) done =
					 * true; else if ('D' == ch) scanJIS (mCursor); else {
					 * mPage.ungetCharacter (mCursor); mPage.ungetCharacter
					 * (mCursor); mPage.ungetCharacter (mCursor); } }
					 */
					else {
						mPage.ungetCharacter(mCursor);
						mPage.ungetCharacter(mCursor);
					}
				} else
					mPage.ungetCharacter(mCursor);
			} else if (quotesmart && (0 == quote)
					&& (('\'' == ch) || ('"' == ch)))
				quote = ch; // enter quoted state
			// patch from Gernot Fricke to handle escaped closing quote
			else if (quotesmart && (0 != quote) && ('\\' == ch)) {
				ch = mPage.getCharacter(mCursor); // try to consume escape
				if ((Page.EOF != ch) && ('\\' != ch) // escaped backslash
						&& (ch != quote)) // escaped quote character
					// ( reflects ["] or ['] whichever opened the quotation)
					mPage.ungetCharacter(mCursor); // unconsume char if char not
													// an escape
			} else if (quotesmart && (ch == quote))
				quote = 0; // exit quoted state
			else if (quotesmart && (0 == quote) && (ch == '/')) {
				// handle multiline and double slash comments (with a quote)
				// in script like:
				// I can't handle single quotations.
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				else if ('/' == ch) {
					do
						ch = mPage.getCharacter(mCursor);
					while ((Page.EOF != ch) && ('\n' != ch));
				} else if ('*' == ch) {
					do {
						do
							ch = mPage.getCharacter(mCursor);
						while ((Page.EOF != ch) && ('*' != ch));
						ch = mPage.getCharacter(mCursor);
						if (ch == '*')
							mPage.ungetCharacter(mCursor);
					} while ((Page.EOF != ch) && ('/' != ch));
				} else
					mPage.ungetCharacter(mCursor);
			} else if ((0 == quote) && ('<' == ch)) {
				ch = mPage.getCharacter(mCursor);
				if (Page.EOF == ch)
					done = true;
				// the order of these tests might be optimized for speed:
				else if ('/' == ch
						|| (Character.isLetter(ch) && this.script==0)
						|| '!' == ch || '%' == ch || '?' == ch) {
					done = true;
					mPage.ungetCharacter(mCursor);
					mPage.ungetCharacter(mCursor);
				} else {
					// it's not a tag, so keep going, but check for quotes
					mPage.ungetCharacter(mCursor);
				}
			}
		}

		return (makeString(start, mCursor.getPosition()));
	}
}
 
分享到:
评论

相关推荐

    雷克沙u盘加密客户端linux端

    雷克沙U盘加密客户端,即Lexar DataShield,是一款专为雷克沙U盘设计的加密软件。它采用了先进的加密技术,如AES(Advanced Encryption Standard)256位加密,确保数据在传输和存储过程中的安全。Linux版本的客户端...

    雷克沙U盘u盘量产工具.zip

    本文将详细解析这个“雷克沙U盘量产工具”,包括其功能、操作步骤以及常见问题解答,旨在帮助用户深入了解并充分利用这一实用工具。 一、什么是U盘量产工具? U盘量产工具,全称为USB Disk Production Tool,主要...

    Lexar雷克沙U盘加密软件EncryptStick Lite官方版.rar

    本应用程序仅用于Lexar闪存盘。通过加密软件对U盘进行高达256位的AES加密来保护数据安全,创建唯一的密码保护,支持文件粉碎功能,让U盘中的数据更安全。保护你的文件不被未授权的人打开,避免数据误删和丢失,创建...

    LEXAR固态硬盘加密程序

    雷克沙固态硬盘加密程序

    雷克沙u盘加密软件

    它允许用户在U盘上创建一个专门的加密区域,所有在这个区域内保存的文件都将自动加密。这意味着即使U盘丢失或被盗,没有正确密码的任何人都无法读取这些文件,从而保障了数据的隐私性。 文件粉碎功能是另一个值得一...

    雷克沙萤火虫16GU盘量产工具.rar

    软件介绍: 坛友共享出来的16G的雷克沙萤火虫...所使用的软件版本分别是慧荣V2.03.67(支持更多SMI主控型号)和V2.03.47(仅支持SM3255ENA1芯片),如果你有此型号U盘,可以下载试一试。主程序为sm32Xtest,设置密码是320

    SMIMPTool2.5.30_v7雷克沙u盘量产工具.rar

    本文将详细介绍“SMIMPTool2.5.30_v7雷克沙U盘量产工具”,该工具是针对雷克沙品牌U盘设计的一款高效实用的工具,适用于U盘的初始化、性能优化以及故障排除。 首先,我们要理解什么是“量产”。在U盘制造过程中,...

    lexar_usb_tool.zip

    标题中的"lexar_usb_tool.zip"表明这是一款与Lexar品牌相关的USB工具,可能是用于...总的来说,"lexar_usb_tool.zip"提供了一个解决方案,帮助拥有旧U盘的用户利用这些设备来实现启动盘的功能,尽管它有一定的局限性。

    雷克沙u盘加密软件windows客户端

    雷克沙u盘加密软件windows客户端

    雷克沙u盘加密技术文档

    通过这款软件,用户可以轻松创建一个私密的安全区,并通过简单的拖拽操作将重要文件存入其中。安全区的访问受个人密码保护,文件自动进行加密处理。即使存储设备丢失或被盗,也能确保文件的安全性。 #### 二、支持...

    雷克沙优盘里自带的文件

    4. **格式化工具**:有时,优盘可能会附带一个用于格式化设备的工具,用户可以使用它来更改文件系统(例如,从FAT32转换为NTFS),或者在遇到问题时重置优盘。 5. **保修信息/注册文件**:为了便于用户注册产品以...

    图片恢复软件Lexar Image Rescue 2.0.rar

    Lexar Media Image Rescue: Image Recovery 2.0是一个专业的图片恢复工具;Image Recovery图片恢复;Card Test存储卡测试;Format Card存储卡内存卡;Secure Erase存储卡内存卡;可以恢复以下格式的图片:...

    低价不低质:阿尔法GR50无线路由器.pdf

    本文主要介绍了两款IT产品,一款是雷克沙(Lexar)推出的白金版二代存储卡,另一款是阿尔法(Alpha)的AFW-GR50无线路由器。 首先,雷克沙的白金版二代存储卡包括CF卡和SD卡,它们在原有40X速度的基础上提升到了80X...

    加密软件 U盘加密 实用程序

    加密操作简易 支持拖放加密,右键加密,主程序中加密。   三种加密强度 三种加密强度,可以满足各层次用户的需要   多种加密设置 新加入各种自定义设置,轻松打造满足您个人需要的加密文件夹 ...

    程序员考试刷题-SIP2017-Online-Quizzing-Website:PrekshaPandey制作的2017年暑期实习计划项目

    之所以推出在线考试,是因为需要一个对准备 JEE 和其他类似考试的学生有益的网站。 我们经常看到,线下检查很费时间,而且往往会延迟出结果。 通过这个网站,学生可以进行考试并查看他们的成绩。 因此,该站点的目的...

    U盘加密,移动硬盘加密

    可以方便地加密任意文件夹,并且支持U盘加密,移动硬盘加密。人性化设置,简单易用,即使是电脑新手,十秒就能掌握操作。加密速度极快,上百 G 的数据仅需1秒钟完成。 没有大小限制。本软件为绿色免费软件,无须安装,...

    mass storage bulk only

    《海量存储类,bulk only规格文档解析》 一、引言 在计算机科学与信息技术领域,海量存储(Mass Storage)设备扮演着至关重要的角色,它们是数据存储与传输的基石。其中,Bulk-Only Transport(BOT)作为一种高效的...

    U盘量产工具.rar

    【标题】"U盘量产工具.rar"是一款专用于U盘制作和修复的实用软件,它允许用户将USB闪存驱动器格式化并划分为多个分区,以满足不同的存储需求。这款工具特别适用于处理大容量U盘,使得U盘能够模拟光驱、硬盘或移动...

    慧荣方案U盘量产工具H1226汉化版

    这个过程通常由专业工具完成,如慧荣的这款H1226汉化版工具,它能够对使用慧荣芯片的U盘进行一系列定制操作。 3. **汉化版工具**:汉化版意味着该软件已经过翻译,将原本可能为英文的界面转换成中文,方便中文用户...

    照片回复软件Sandisk Rescuepro

    1. **深度扫描**:RescuePro v3采用先进的算法,能够深入扫描存储设备的每一个扇区,寻找并恢复已被删除或丢失的文件。这种深度扫描能力使得它在面对复杂的数据丢失情况时仍能表现出色。 2. **广泛支持的文件类型**...

Global site tag (gtag.js) - Google Analytics