예제 #1
0
 @Override
 public ParseTree optimizeDynamic(Target t, List<ParseTree> children, FileOptions fileOptions)
     throws ConfigCompileException, ConfigRuntimeException {
   // We can check 2 things here, one, that the statement isn't dynamic, and if not, then
   // 2, that the parameter count matches the ? count. No checks can be done for typing,
   // without making a connection to the db though, so we won't do that here.
   Construct queryData = children.get(1).getData();
   if (queryData instanceof CFunction) {
     // If it's a concat or sconcat, warn them that this is bad
     if ("sconcat".equals(queryData.val()) || "concat".equals(queryData.val())) {
       CHLog.GetLogger()
           .w(
               CHLog.Tags.COMPILER,
               "Use of concatenated query detected! This"
                   + " is very bad practice, and could lead to SQL injection vulnerabilities"
                   + " in your code. It is highly recommended that you use prepared queries,"
                   + " which ensure that your parameters are properly escaped.",
               t);
     }
   } else if (queryData instanceof CString) {
     // It's a hard coded query, so we can double check parameter lengths
     int count = 0;
     for (char c : queryData.val().toCharArray()) {
       if (c == '?') {
         count++;
       }
     }
     // -2 accounts for the profile data and query
     if (children.size() - 2 != count) {
       throw new ConfigCompileException(
           StringUtils.PluralTemplateHelper(
                   count, "%d parameter token was", "%d parameter tokens were")
               + " found in the query, but "
               + StringUtils.PluralTemplateHelper(
                   children.size() - 2, "%d parameter was", "%d parameters were")
               + " provided to query().",
           t);
     }
   }
   return null;
 }
예제 #2
0
 @Override
 public ParseTree optimizeDynamic(Target t, List<ParseTree> children, FileOptions fileOptions)
     throws ConfigCompileException, ConfigRuntimeException {
   if (children.size() < 5) {
     throw new ConfigRuntimeException(
         "bind accepts 5 or more parameters", ExceptionType.InsufficientArgumentsException, t);
   }
   if (!children.get(0).isConst()) {
     // This ability may be removed in the future, to allow for better compilation checks of
     // event type, once objects are added.
     // We'll add this warning to gauge impact.
     CHLog.GetLogger()
         .Log(
             CHLog.Tags.COMPILER,
             LogLevel.WARNING,
             "Use of dynamic bind. This may be removed in the future, please"
                 + " contact the developers to provide feedback if this affects you.",
             t);
   }
   return null;
 }
예제 #3
0
  public void sort(final SortType sort) {
    List<Construct> list = array;
    if (this.associative_mode) {
      list = new ArrayList(associative_array.values());
      this.associative_array.clear();
      this.associative_array = null;
      this.associative_mode = false;
      CHLog.GetLogger()
          .Log(
              CHLog.Tags.GENERAL,
              LogLevel.VERBOSE,
              "Attempting to sort an associative array; key values will be lost.",
              this.getTarget());
    }
    Collections.sort(
        array,
        new Comparator<Construct>() {
          @Override
          public int compare(Construct o1, Construct o2) {
            // o1 < o2 -> -1
            // o1 == o2 -> 0
            // o1 > o2 -> 1
            for (int i = 0; i < 2; i++) {
              Construct c;
              if (i == 0) {
                c = o1;
              } else {
                c = o2;
              }
              if (c instanceof CArray) {
                throw ConfigRuntimeException.BuildException(
                    "Cannot sort an array of arrays.",
                    ExceptionType.CastException,
                    CArray.this.getTarget());
              }
              if (!(c instanceof CBoolean
                  || c instanceof CString
                  || c instanceof CInt
                  || c instanceof CDouble
                  || c instanceof CNull)) {
                throw ConfigRuntimeException.BuildException(
                    "Unsupported type being sorted: " + c.getCType(),
                    ExceptionType.FormatException,
                    CArray.this.getTarget());
              }
            }
            if (o1 instanceof CNull || o2 instanceof CNull) {
              if (o1 instanceof CNull && o2 instanceof CNull) {
                return 0;
              } else if (o1 instanceof CNull) {
                return "".compareTo(o2.getValue());
              } else {
                return o1.val().compareTo("");
              }
            }
            if (o1 instanceof CBoolean || o2 instanceof CBoolean) {
              if (Static.getBoolean(o1) == Static.getBoolean(o2)) {
                return 0;
              } else {
                int oo1 = Static.getBoolean(o1) == true ? 1 : 0;
                int oo2 = Static.getBoolean(o2) == true ? 1 : 0;
                return (oo1 < oo2) ? -1 : 1;
              }
            }
            // At this point, things will either be numbers or strings
            switch (sort) {
              case REGULAR:
                return compareRegular(o1, o2);
              case NUMERIC:
                return compareNumeric(o1, o2);
              case STRING:
                return compareString(o1.val(), o2.val());
              case STRING_IC:
                return compareString(o1.val().toLowerCase(), o2.val().toLowerCase());
            }
            throw ConfigRuntimeException.CreateUncatchableException(
                "Missing implementation for " + sort.name(), Target.UNKNOWN);
          }

          public int compareRegular(Construct o1, Construct o2) {
            if (Static.getBoolean(new DataHandling.is_numeric().exec(Target.UNKNOWN, null, o1))
                && Static.getBoolean(
                    new DataHandling.is_numeric().exec(Target.UNKNOWN, null, o2))) {
              return compareNumeric(o1, o2);
            } else if (Static.getBoolean(
                new DataHandling.is_numeric().exec(Target.UNKNOWN, null, o1))) {
              // The first is a number, the second is a string
              return -1;
            } else if (Static.getBoolean(
                new DataHandling.is_numeric().exec(Target.UNKNOWN, null, o2))) {
              // The second is a number, the first is a string
              return 1;
            } else {
              // They are both strings
              return compareString(o1.val(), o2.val());
            }
          }

          public int compareNumeric(Construct o1, Construct o2) {
            double d1 = Static.getNumber(o1, o1.getTarget());
            double d2 = Static.getNumber(o2, o2.getTarget());
            return Double.compare(d1, d2);
          }

          public int compareString(String o1, String o2) {
            return o1.compareTo(o2);
          }
        });
    this.array = list;
    this.regenValue(new HashSet<CArray>());
  }