All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.core.client.JsonUtils Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.core.client;

/**
 * Provides JSON-related utility methods.
 */
public class JsonUtils {
  private static JavaScriptObject escapeTable = initEscapeTable();

  private static final boolean hasJsonParse = hasJsonParse();

  /**
   * Escapes characters within a JSON string than cannot be passed directly to
   * eval(). Control characters, quotes and backslashes are not affected.
   */
  public static native String escapeJsonForEval(String toEscape) /*-{
    var s = toEscape.replace(/[\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb]/g, function(x) {
      return @com.google.gwt.core.client.JsonUtils::escapeChar(Ljava/lang/String;)(x);
    });
    return s;
  }-*/;

  /**
   * Returns a quoted, escaped JSON String.
   */
  public static native String escapeValue(String toEscape) /*-{
    var s = toEscape.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202e\u2060-\u2063\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g, function(x) {
      return @com.google.gwt.core.client.JsonUtils::escapeChar(Ljava/lang/String;)(x);
    });
    return "\"" + s + "\"";
  }-*/;

  /**
   * Evaluates a JSON expression safely. The payload must evaluate to an Object
   * or an Array (not a primitive or a String).
   * 
   * @param  The type of JavaScriptObject that should be returned
   * @param json The source JSON text
   * @return The evaluated object
   * 
   * @throws IllegalArgumentException if the input is not valid JSON
   */
  public static native  T safeEval(String json) /*-{
    var v;
    if (@com.google.gwt.core.client.JsonUtils::hasJsonParse) {
      try {
        return JSON.parse(json);
      } catch (e) {
        return @com.google.gwt.core.client.JsonUtils::throwIllegalArgumentException(*)("Error parsing JSON: " + e, json);
      }
    } else {
      if ([email protected]::safeToEval(Ljava/lang/String;)(json)) {
        return @com.google.gwt.core.client.JsonUtils::throwIllegalArgumentException(*)("Illegal character in JSON string", json);
      }
      json = @com.google.gwt.core.client.JsonUtils::escapeJsonForEval(Ljava/lang/String;)(json);
      try {
        return eval('(' + json + ')');
      } catch (e) {
        return @com.google.gwt.core.client.JsonUtils::throwIllegalArgumentException(*)("Error parsing JSON: " + e, json);
      }
    }
  }-*/;
  
  /**
   * Returns true if the given JSON string may be safely evaluated by {@code
   * eval()} without undersired side effects or security risks. Note that a true
   * result from this method does not guarantee that the input string is valid
   * JSON.  This method does not consider the contents of quoted strings; it
   * may still be necessary to perform escaping prior to evaluation for correct
   * results.
   * 
   * 

The technique used is taken from RFC 4627. */ public static native boolean safeToEval(String text) /*-{ // Remove quoted strings and disallow anything except: // // 1) symbols and brackets ,:{}[] // 2) numbers: digits 0-9, ., -, +, e, and E // 3) literal values: 'null', 'true' and 'false' = [aeflnr-u] // 4) whitespace: ' ', '\n', '\r', and '\t' return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, ''))); }-*/; /** * Evaluates a JSON expression using {@code eval()}. This method does not * validate the JSON text and should only be used on JSON from trusted * sources. The payload must evaluate to an Object or an Array (not a * primitive or a String). * * @param The type of JavaScriptObject that should be returned * @param json The source JSON text * @return The evaluated object */ public static native T unsafeEval(String json) /*-{ var escaped = @com.google.gwt.core.client.JsonUtils::escapeJsonForEval(Ljava/lang/String;)(json); try { return eval('(' + escaped + ')'); } catch (e) { return @com.google.gwt.core.client.JsonUtils::throwIllegalArgumentException(*)("Error parsing JSON: " + e, json); } }-*/; static void throwIllegalArgumentException(String message, String data) { throw new IllegalArgumentException(message + "\n" + data); } private static native String escapeChar(String c) /*-{ var lookedUp = @com.google.gwt.core.client.JsonUtils::escapeTable[c.charCodeAt(0)]; return (lookedUp == null) ? c : lookedUp; }-*/; /** * Returns true if the JSON.parse function is present, false otherwise. */ private static native boolean hasJsonParse() /*-{ return typeof JSON == "object" && typeof JSON.parse == "function"; }-*/; private static native JavaScriptObject initEscapeTable() /*-{ var out = [ "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000B", "\\f", "\\r", "\\u000E", "\\u000F", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001A", "\\u001B", "\\u001C", "\\u001D", "\\u001E", "\\u001F"]; out[34] = '\\"'; out[92] = '\\\\'; out[0xad] = '\\u00ad'; // Soft hyphen out[0x600] = '\\u0600'; // Arabic number sign out[0x601] = '\\u0601'; // Arabic sign sanah out[0x602] = '\\u0602'; // Arabic footnote marker out[0x603] = '\\u0603'; // Arabic sign safha out[0x6dd] = '\\u06dd'; // Arabic and of ayah out[0x70f] = '\\u070f'; // Syriac abbreviation mark out[0x17b4] = '\\u17b4'; // Khmer vowel inherent aq out[0x17b5] = '\\u17b5'; // Khmer vowel inherent aa out[0x200c] = '\\u200c'; // Zero width non-joiner out[0x200d] = '\\u200d'; // Zero width joiner out[0x200e] = '\\u200e'; // Left-to-right mark out[0x200f] = '\\u200f'; // Right-to-left mark out[0x2028] = '\\u2028'; // Line separator out[0x2029] = '\\u2029'; // Paragraph separator out[0x202a] = '\\u202a'; // Left-to-right embedding out[0x202b] = '\\u202b'; // Right-to-left embedding out[0x202c] = '\\u202c'; // Pop directional formatting out[0x202d] = '\\u202d'; // Left-to-right override out[0x202e] = '\\u202e'; // Right-to-left override out[0x2060] = '\\u2060'; // Word joiner out[0x2061] = '\\u2061'; // Function application out[0x2062] = '\\u2062'; // Invisible times out[0x2063] = '\\u2063'; // Invisible separator out[0x206a] = '\\u206a'; // Inhibit symmetric swapping out[0x206b] = '\\u206b'; // Activate symmetric swapping out[0x206c] = '\\u206c'; // Inherent Arabic form shaping out[0x206d] = '\\u206d'; // Activate Arabic form shaping out[0x206e] = '\\u206e'; // National digit shapes out[0x206f] = '\\u206f'; // Nominal digit shapes out[0xfeff] = '\\ufeff'; // Zero width no-break space out[0xfff9] = '\\ufff9'; // Intralinear annotation anchor out[0xfffa] = '\\ufffa'; // Intralinear annotation separator out[0xfffb] = '\\ufffb'; // Intralinear annotation terminator return out; }-*/; private JsonUtils() { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy