/**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   * @throws CloneNotSupportedException DOCUMENT ME!
   */
  @Override
  protected Object clone() throws CloneNotSupportedException {
    final MagicMatcher clone = new MagicMatcher();

    clone.setMatch((MagicMatch) this.match.clone());

    final Iterator<MagicMatcher> i = this.subMatchers.iterator();
    final ArrayList<MagicMatcher> sub = new ArrayList<MagicMatcher>();

    while (i.hasNext()) {
      final MagicMatcher m = i.next();
      sub.add((MagicMatcher) m.clone());
    }

    clone.setSubMatchers(sub);

    return clone;
  }
Example #2
0
  /**
   * DOCUMENT ME!
   *
   * @param uri DOCUMENT ME!
   * @param localName DOCUMENT ME!
   * @param qname DOCUMENT ME!
   * @throws SAXException DOCUMENT ME!
   */
  public void endElement(String uri, String localName, String qname) throws SAXException {
    log.debug("endElement()");
    log.debug("endElement(): localName is '" + localName + "'");

    // determine which tag these chars are for and save them
    if (isMimeType) {
      isMimeType = false;
      match.setMimeType(finalValue);
      log.debug("characters(): setting mimetype to '" + finalValue + "'");
    } else if (isExtension) {
      isExtension = false;
      match.setExtension(finalValue);
      log.debug("characters(): setting extension to '" + finalValue + "'");
    } else if (isDescription) {
      isDescription = false;
      match.setDescription(finalValue);
      log.debug("characters(): setting description to '" + finalValue + "'");
    } else if (isTest) {
      isTest = false;
      match.setTest(convertOctals(finalValue));
      log.debug("characters(): setting test to '" + convertOctals(finalValue) + "'");
    } else {
      // do nothing
    }

    finalValue = "";

    // need to save the current matcher here if it is filled out enough and
    // we have an /matcher
    if (localName.equals("match")) {
      // FIXME - make sure the MagicMatcher isValid() test works
      if (matcher.isValid()) {
        // set the collected properties on this matcher
        match.setProperties(properties);

        // add root match
        if (stack.size() == 0) {
          log.debug("endElement(): adding root matcher");
          matchers.add(matcher);
        } else {
          // we need to add the match to it's parent which is on the
          // stack
          log.debug("endElement(): adding sub matcher");

          MagicMatcher m = (MagicMatcher) stack.get(stack.size() - 1);
          m.addSubMatcher(matcher);
        }
      } else {
        // don't add invalid matchers
        log.info("endElement(): not adding invalid matcher '" + match.getDescription() + "'");
      }

      matcher = null;
      properties = null;

      // restore matcher from the stack if we have an /matcher-list
    } else if (localName.equals("match-list")) {
      if (stack.size() > 0) {
        log.debug("endElement(): popping from the stack");
        matcher = (MagicMatcher) stack.get(stack.size() - 1);
        // pop from the stack
        stack.remove(matcher);
      }
    } else if (localName.equals("mimetype")) {
      isMimeType = false;
    } else if (localName.equals("extension")) {
      isExtension = false;
    } else if (localName.equals("description")) {
      isDescription = false;
    } else if (localName.equals("test")) {
      isTest = false;
    }
  }
Example #3
0
  /**
   * DOCUMENT ME!
   *
   * @param uri DOCUMENT ME!
   * @param localName DOCUMENT ME!
   * @param qname DOCUMENT ME!
   * @param attributes DOCUMENT ME!
   * @throws SAXException DOCUMENT ME!
   */
  public void startElement(String uri, String localName, String qname, Attributes attributes)
      throws SAXException {
    log.debug("startElement()");
    log.debug("startElement(): localName is '" + localName + "'");

    // create a new matcher
    if (localName.equals("match")) {
      log.debug("startElement(): creating new matcher");
      // match to hold data
      match = new MagicMatch();
      // our matcher
      matcher = new MagicMatcher();
      matcher.setMatch(match);
    }

    // these are subelements of matcher, but also occur elsewhere
    if (matcher != null) {
      if (localName.equals("mimetype")) {
        isMimeType = true;
      } else if (localName.equals("extension")) {
        isExtension = true;
      } else if (localName.equals("description")) {
        isDescription = true;
      } else if (localName.equals("test")) {
        isTest = true;

        int length = attributes.getLength();

        for (int i = 0; i < length; i++) {
          String attrLocalName = attributes.getLocalName(i);
          String attrValue = attributes.getValue(i);

          if (attrLocalName.equals("offset")) {
            if (!attrValue.equals("")) {
              match.setOffset(new Integer(attrValue).intValue());
              log.debug("startElement():   setting offset to '" + attrValue + "'");
            }
          } else if (attrLocalName.equals("length")) {
            if (!attrValue.equals("")) {
              match.setLength(new Integer(attrValue).intValue());
              log.debug("startElement():   setting length to '" + attrValue + "'");
            }
          } else if (attrLocalName.equals("type")) {
            match.setType(attrValue);
            log.debug("startElement():   setting type to '" + attrValue + "'");
          } else if (attrLocalName.equals("bitmask")) {
            if (!attrValue.equals("")) {
              match.setBitmask(attrValue);
              log.debug("startElement():   setting bitmask to '" + attrValue + "'");
            }
          } else if (attrLocalName.equals("comparator")) {
            match.setComparator(attrValue);
            log.debug("startElement():   setting comparator to '" + attrValue + "'");
          }
        }
      } else if (localName.equals("property")) {
        int length = attributes.getLength();
        String name = null;
        String value = null;

        for (int i = 0; i < length; i++) {
          String attrLocalName = attributes.getLocalName(i);
          String attrValue = attributes.getValue(i);

          if (attrLocalName.equals("name")) {
            if (!attrValue.equals("")) {
              name = attrValue;
            }
          } else if (attrLocalName.equals("value")) {
            if (!attrValue.equals("")) {
              value = attrValue;
            }
          }
        }

        // save the property to our map
        if ((name != null) && (value != null)) {
          if (properties == null) {
            properties = new HashMap();
          }

          if (!properties.containsKey(name)) {
            properties.put(name, value);
            log.debug("startElement():   setting property '" + name + "'='" + value + "'");
          } else {
            log.debug("startElement():   not setting property '" + name + "', duplicate key");
          }
        }
      } else if (localName.equals("match-list")) {
        log.debug("startElement(): found submatcher list");

        // this means we are processing a child match, so we need to push
        // the existing match on the stack
        log.debug("startElement(): pushing current matcher to stack");
        stack.add(matcher);
      } else {
        // we don't care about this type
      }
    }
  }
  /**
   * test to see if this match or any submatches match
   *
   * @param data the data that should be used to test the match
   * @param onlyMimeMatch DOCUMENT ME!
   * @return the deepest magic match object that matched
   * @throws IOException DOCUMENT ME!
   * @throws UnsupportedTypeException DOCUMENT ME!
   */
  public MagicMatch test(final byte[] data, final boolean onlyMimeMatch)
      throws IOException, UnsupportedTypeException {

    final int offset = this.match.getOffset();
    this.match.getDescription();
    final String type = this.match.getType();
    this.match.getMimeType();

    int length = 0;

    if (type.equals("byte")) { // $NON-NLS-1$
      length = 1;
    } else if (type.equals("short")
        || type.equals("leshort")
        || type.equals("beshort")) { // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      length = 4;
    } else if (type.equals("long")
        || type.equals("lelong")
        || type.equals("belong")) { // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      length = 8;
    } else if (type.equals("string")) { // $NON-NLS-1$
      length = this.match.getTest().capacity();
    } else if (type.equals("regex")) { // $NON-NLS-1$
      // FIXME - something wrong here, shouldn't have to subtract 1???
      length = data.length - offset - 1;

      if (length < 0) {
        length = 0;
      }
    } else if (type.equals("detector")) { // $NON-NLS-1$
      // FIXME - something wrong here, shouldn't have to subtract 1???
      length = data.length - offset - 1;

      if (length < 0) {
        length = 0;
      }
    } else {
      throw new UnsupportedTypeException("unsupported test type " + type); // $NON-NLS-1$
    }

    final byte[] buf = new byte[length];

    if (offset + length < data.length) {
      System.arraycopy(data, offset, buf, 0, length);

      MagicMatch match1 = null;
      MagicMatch submatch = null;

      if (testInternal(buf)) {
        // set the top level match to this one
        match1 = getMatch();

        // set the data on this match
        if (onlyMimeMatch == false && this.subMatchers != null && this.subMatchers.size() > 0) {

          for (int i = 0; i < this.subMatchers.size(); i++) {

            final MagicMatcher m = this.subMatchers.get(i);

            if ((submatch = m.test(data, false)) != null) {
              match1.addSubMatch(submatch);
            }
          }
        }
      }

      return match1;
    }
    return null;
  }
  /**
   * test to see if this match or any submatches match
   *
   * @param f the file that should be used to test the match
   * @param onlyMimeMatch DOCUMENT ME!
   * @return the deepest magic match object that matched
   * @throws IOException DOCUMENT ME!
   * @throws UnsupportedTypeException DOCUMENT ME!
   */
  public MagicMatch test(final File f, final boolean onlyMimeMatch)
      throws IOException, UnsupportedTypeException {

    final int offset = this.match.getOffset();
    this.match.getDescription();
    final String type = this.match.getType();
    this.match.getMimeType();

    final RandomAccessFile file = new RandomAccessFile(f, "r"); // $NON-NLS-1$

    int length = 0;

    if (type.equals("byte")) { // $NON-NLS-1$
      length = 1;
    } else if (type.equals("short")
        || type.equals("leshort")
        || type.equals("beshort")) { // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      length = 4;
    } else if (type.equals("long")
        || type.equals("lelong")
        || type.equals("belong")) { // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      length = 8;
    } else if (type.equals("string")) { // $NON-NLS-1$
      length = this.match.getTest().capacity();
    } else if (type.equals("regex")) { // $NON-NLS-1$
      length = (int) file.length() - offset;

      if (length < 0) {
        length = 0;
      }
    } else if (type.equals("detector")) { // $NON-NLS-1$
      length = (int) file.length() - offset;

      if (length < 0) {
        length = 0;
      }
    } else {
      file.close();
      throw new UnsupportedTypeException(
          "unsupported test type '" + type + "'"); // $NON-NLS-1$ //$NON-NLS-2$
    }

    // we know this match won't work since there isn't enough data for the test
    if (length > file.length() - offset) {
      file.close();
      return null;
    }

    final byte[] buf = new byte[length];
    file.seek(offset);

    int bytesRead = 0;
    int size = 0;
    boolean done = false;

    while (!done) {
      size = file.read(buf, 0, length - bytesRead);

      if (size == -1) {
        file.close();
        throw new IOException("reached end of file before all bytes were read"); // $NON-NLS-1$
      }

      bytesRead += size;

      if (bytesRead == length) {
        done = true;
      }
    }

    MagicMatch match1 = null;
    MagicMatch submatch = null;

    if (testInternal(buf)) {
      // set the top level match to this one
      match1 = getMatch();

      // set the data on this match
      if (onlyMimeMatch == false && this.subMatchers != null && this.subMatchers.size() > 0) {

        for (int i = 0; i < this.subMatchers.size(); i++) {

          final MagicMatcher m = this.subMatchers.get(i);

          if ((submatch = m.test(f, false)) != null) {
            match1.addSubMatch(submatch);
          }
        }
      }
    }
    file.close();
    return match1;
  }