Update of /cvsroot/openantivirus/java/src/org/openantivirus/engine/censor/trie
In directory sc8-pr-cvs1:/tmp/cvs-serv4777/java/src/org/openantivirus/engine/censor/trie
Added Files:
Trie.java PositionFoundEvent.java TrieNode.java
PositionFoundListener.java TrieCensor.java StringFinder.java
Log Message:
Rewrite of the engine to use a virtual file system
Move to 'engine' subdirectory
Added bzip2 and tar decompressors
Switch from GPL to MPL
--- NEW FILE: Trie.java ---
/*
* $Id: Trie.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import java.util.*;
/**
* Trie
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public class Trie {
public final static int MINIMUM_LENGTH = 4;
private TrieNode nRoot = new TrieNode();
private int[] nodeDepthCount = new int[MINIMUM_LENGTH];
public void addString(byte[] abPattern, PositionFoundListener pfl) {
if (abPattern.length < MINIMUM_LENGTH) {
throw new IllegalArgumentException("String too short");
}
// start at rootnode
TrieNode nPos = nRoot;
// add nodes into the tree for the prefix with length MINIMUM_LENGTH
for (int i = 0; i < MINIMUM_LENGTH; i++) {
int iCharacter = (abPattern[i] + 256) & 0xff;
TrieNode next = nPos.isLastNode() ? null
: nPos.getTrans(iCharacter);
if (next == null) {
next = new TrieNode();
nPos.setTrans(iCharacter, next);
nodeDepthCount[i]++;
}
nPos = next;
}
nPos.addPositionFoundListener(pfl);
}
public TrieNode getRootNode() {
return nRoot;
}
/**
* Prepares the Trie for usage. This method has to be called before the
* trie can be used
*/
public void prepare() {
// initialize the root node
final LinkedList children = new LinkedList();
nRoot.setFailure(null); // null = top node; to end following
for (int i = 0; i < TrieNode.NUM_CHILDS; i++) {
final TrieNode child = nRoot.getTrans(i);
if (child == null) {
nRoot.setTrans(i, nRoot);
} else {
child.setFailure(nRoot);
children.addLast(child);
}
}
while (!children.isEmpty()) {
final TrieNode node = (TrieNode) children.removeFirst();
if (node.isLastNode()) {
continue;
}
for (int i = 0; i < TrieNode.NUM_CHILDS; i++) {
final TrieNode child = node.getTrans(i);
if (child == null) {
node.setTrans(i, node.getFailure().getTrans(i));
} else {
child.setFailure(node.getFailure().getTrans(i));
children.addLast(child);
}
}
}
}
public int[] getNodeDepths() {
return nodeDepthCount;
}
}
--- NEW FILE: PositionFoundEvent.java ---
/*
* $Id: PositionFoundEvent.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import org.openantivirus.engine.vfs.*;
/**
* Indication the position within the file where something has been found
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public class PositionFoundEvent {
public final byte[] buffer;
public final VfsEntry entry;
public final long fileOffset;
public final int bufferOffset, length, prefix, postfix;
/**
* @param entry the entry containing the position
* @param fileOffset offset within the file
* @param buffer the (ring) buffer containing the string found
* @param bufferOffset offset of the start of the string within the buffer
* @param length length of the string found
* @param prefixLength number of valid bytes before the offset byte
* @param postfixLength number of valid bytes after the offset byte
*/
public PositionFoundEvent(VfsEntry entry,
long fileOffset,
byte[] buffer, int bufferOffset, int length,
int prefix, int postfix) {
this.entry = entry;
this.fileOffset = fileOffset;
this.buffer = buffer;
this.bufferOffset = bufferOffset;
this.length = length;
this.prefix = prefix;
this.postfix = postfix;
}
}
--- NEW FILE: TrieNode.java ---
/*
* $Id: TrieNode.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import java.util.*;
/**
* A node in the trie
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public class TrieNode {
/**
* Number of children a node has; currently one for every possible byte
* value
*/
public final static int NUM_CHILDS = 256;
private TrieNode nFailure = null;
private static int iInstances = 0;
private boolean bIsLastNode = true;
private Collection colPositionFoundListener = null;
private TrieNode[] anTrans = null;
public TrieNode() {
iInstances++;
}
public void setTrans(int iByte, TrieNode n) {
if (anTrans == null) {
anTrans = new TrieNode[NUM_CHILDS];
bIsLastNode = false;
}
anTrans[iByte] = n;
}
public TrieNode getTrans(int index) {
return anTrans[index];
}
public boolean isLastNode() {
return bIsLastNode;
}
public void addPositionFoundListener(PositionFoundListener pfl) {
if (colPositionFoundListener == null) {
colPositionFoundListener = new LinkedList();
}
colPositionFoundListener.add(pfl);
}
public Collection getStringSearchListener() {
return colPositionFoundListener;
}
public void setFailure(TrieNode nFailure) {
this.nFailure = nFailure;
}
public TrieNode getFailure() {
return nFailure;
}
public static int getInstanceCount() {
return iInstances;
}
}
--- NEW FILE: PositionFoundListener.java ---
/*
* $Id: PositionFoundListener.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import org.openantivirus.engine.censor.*;
/**
* Listener for events meaning that something has been found
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public interface PositionFoundListener {
void positionFound(PositionFoundEvent pfe) throws MalwareFoundException;
}
--- NEW FILE: TrieCensor.java ---
/*
* $Id: TrieCensor.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import java.io.*;
import java.util.*;
import org.openantivirus.engine.censor.*;
import org.openantivirus.engine.vfs.*;
/**
* Uses a Trie to scan the file; this class is not thread-safe!
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public class TrieCensor implements Censor {
private static final int BUFFER_SIZE = 32768;
private TrieNode nRoot, nCurrent;
public TrieCensor(Trie trie) {
nRoot = trie.getRootNode();
}
public int censor(VfsEntry entry)
throws MalwareFoundException, ScanException {
nCurrent = nRoot;
try {
final InputStream is = new FileInputStream(entry.getFile());
try {
scanStream(entry, is);
} finally {
is.close();
}
return 0;
} catch (IOException ioe) {
throw new ScanException(ioe);
}
}
protected void scanStream(VfsEntry entry, InputStream is)
throws IOException, MalwareFoundException {
byte[] abBuffer = new byte[3 * BUFFER_SIZE];
int iLength = fillBuffer(is, abBuffer, 0, abBuffer.length);
if (iLength == -1) {
return;
} else if (iLength < abBuffer.length) {
update(entry, 0L, abBuffer, 0, iLength, 0, 0);
} else {
update(entry, 0L, abBuffer, 0, 2 * BUFFER_SIZE, 0, BUFFER_SIZE);
long fileOffset = 2 * BUFFER_SIZE;
int iBufferPos = 2 * BUFFER_SIZE;
int iReadAheadPos = 0;
do {
iLength = fillBuffer(is,
abBuffer,
iReadAheadPos,
BUFFER_SIZE);
update(entry,
fileOffset,
abBuffer,
iBufferPos,
BUFFER_SIZE,
BUFFER_SIZE,
iLength != -1 ? iLength : 0);
iBufferPos = iReadAheadPos;
iReadAheadPos += BUFFER_SIZE;
iReadAheadPos %= 3 * BUFFER_SIZE;
fileOffset += BUFFER_SIZE;
} while (iLength == BUFFER_SIZE);
if (iLength != -1) {
update(entry,
fileOffset,
abBuffer,
iBufferPos,
iLength,
BUFFER_SIZE,
0);
}
}
}
/**
* scans the next block of the stream for virii; blocks are expected to
* appear in the correct order
*/
protected void update(VfsEntry entry,
long fileOffset,
byte[] ab,
int iOffset,
int iLength,
int iPrefix,
int iPostfix) throws MalwareFoundException {
for (int i = iOffset; i < iOffset + iLength; i++) {
nCurrent = nCurrent.getTrans(ab[ i ] & 0xff);
if (nCurrent.isLastNode()) {
final int iPosition = i - Trie.MINIMUM_LENGTH + 1;
final PositionFoundEvent pfe = new PositionFoundEvent(
entry,
fileOffset + iPosition,
ab,
iPosition,
Trie.MINIMUM_LENGTH,
iPosition - iOffset + iPrefix,
iOffset + iLength - iPosition + iPostfix
- Trie.MINIMUM_LENGTH);
for (Iterator it =
nCurrent.getStringSearchListener().iterator();
it.hasNext(); ) {
((PositionFoundListener) it.next()).positionFound(pfe);
}
nCurrent = nCurrent.getFailure();
}
}
}
/**
* fills the buffer up to the end unless the end of data is reached, or
* an IOException occurs
*/
protected int fillBuffer(InputStream stream,
byte[] buffer,
int offset,
int length) throws IOException {
int iRead = 0;
do {
int iLength = stream.read(buffer, offset + iRead, length - iRead);
if (iLength == -1) {
return iRead == 0 ? -1 : iRead;
}
iRead += iLength;
} while (iRead < length);
return iRead;
}
}
--- NEW FILE: StringFinder.java ---
/*
* $Id: StringFinder.java,v 1.1 2003/12/14 11:08:26 kurti Exp $
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OAV.
*
* The Initial Developer of the Original Code is Kurt Huwig <[email protected]>.
* Portions created by the Initial Developer are Copyright (C) 2001-2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package org.openantivirus.engine.censor.trie;
import org.openantivirus.engine.censor.*;
/**
* Can add strings to the trie and adds itself as a listener to the trie
*
* Pattern-Roles:
* @author Kurt Huwig <[email protected]>
* @version $Revision: 1.1 $
*/
public class StringFinder {
private Trie trie;
public StringFinder(Trie trie) {
this.trie = trie;
}
public void addString(byte[] abPattern, PositionFoundListener pfl) {
trie.addString(abPattern,
new PartialStringFoundListener(abPattern, pfl));
}
private class PartialStringFoundListener implements PositionFoundListener {
private byte[] abPattern;
private PositionFoundListener pfl;
public PartialStringFoundListener(byte[] abPattern,
PositionFoundListener pfl) {
this.abPattern = abPattern;
this.pfl = pfl;
}
public void positionFound(PositionFoundEvent pfe)
throws MalwareFoundException {
byte[] abBuffer = pfe.buffer;
int iBufferPos = pfe.bufferOffset + pfe.length;
int iPostfixEnd = pfe.bufferOffset + pfe.length
+ pfe.postfix;
for (int i = pfe.length; i < abPattern.length; i++) {
iBufferPos %= abBuffer.length;
if (iBufferPos == iPostfixEnd) {
return;
}
if (abPattern[i] != abBuffer[iBufferPos]) {
return;
}
iBufferPos++;
}
pfl.positionFound(pfe);
}
}
}
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive? Does it
help you create better code? SHARE THE LOVE, and help us help
YOU! Click Here: http://sourceforge.net/donate/
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.