<commit_before>// Copyright 2006 The Closure Library Authors. All Rights Reserved.
//
// 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.

/**
 * @fileoverview JSON utility functions.
 * @author <EMAIL> (<NAME>)
 */


goog.provide('goog.json');
goog.provide('goog.json.Replacer');
goog.provide('goog.json.Reviver');
goog.provide('goog.json.Serializer');


/**
 * @define {boolean} If true, use the native JSON parsing API.
 * NOTE: The default {@code goog.json.parse} implementation is able to handle
 * invalid JSON. JSPB used to produce invalid JSON which is not the case
 * anymore so this is safe to enable for parsing JSPB. Using native JSON is
 * faster and safer than the default implementation using {@code eval}.
 */
goog.define('goog.json.USE_NATIVE_JSON', false);

/**
 * @define {boolean} If true, try the native JSON parsing API first. If it
 * fails, log an error and use {@code eval} instead. This is useful when
 * transitioning to {@code goog.json.USE_NATIVE_JSON}. The error logger needs to
 * be set by {@code goog.json.setErrorLogger}. If it is not set then the error
 * is ignored.
 */
goog.define('goog.json.TRY_NATIVE_JSON', false);


/**
 * Tests if a string is an invalid JSON string. This only ensures that we are
 * not using any invalid characters
 * @param {string} s The string to test.
 * @return {boolean} True if the input is a valid JSON string.
 */
goog.json.isValid = function(s) {
  // All empty whitespace is not valid.
  if (/^\s*$/.test(s)) {
    return false;
  }

  // This is taken from http://www.json.org/json2.js which is released to the
  // public domain.
  // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator
  // inside strings.  We also treat \u2028 and \u2029 as whitespace which they
  // are in the RFC but IE and Safari does not match \s to these so we need to
  // include them in the reg exps in all places where whitespace is allowed.
  // We allowed \x7f inside strings because some tools don't escape it,
  // e.g. http://www.json.org/java/org/json/JSONObject.java

  // Parsing happens in three stages. In the first stage, we run the text
  // against regular expressions that look for non-JSON patterns. We are
  // especially concerned with '()' and 'new' because they can cause invocation,
  // and '=' because it can cause mutation. But just to be safe, we want to
  // reject all unexpected forms.

  // We split the first stage into 4 regexp operations in order to work around
  // crippling inefficiencies in IE's and Safari's regexp engines. First we
  // replace all backslash pairs with '@' (a non-JSON character). Second, we
  // replace all simple value tokens with ']' characters, but only when followed
  // by a colon, comma, closing bracket or end of string. Third, we delete all
  // open brackets that follow a colon or comma or that begin the text. Finally,
  // we look to see that the remaining characters are only whitespace or ']' or
  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

  // Don't make these static since they have the global flag.
  var backslashesRe = /\\["\\\/bfnrtu]/g;
  var simpleValuesRe =
      /(?:"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)[\s\u2028\u2029]*(?=:|,|]|}|$)/g;
  var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
  var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;

  return remainderRe.test(
      s.replace(backslashesRe, '@')
          .replace(simpleValuesRe, ']')
          .replace(openBracketsRe, ''));
};

/**
 * Logs a parsing error in {@code JSON.parse} solvable by using {@code eval}
 * if {@code goog.json.TRY_NATIVE_JSON} is enabled.
 * @private {function(string, !Error)} The first parameter is the error message,
 *     the second is the exception thrown by {@code JSON.parse}.
 */
goog.json.errorLogger_ = goog.nullFunction;


/**
 * Sets an error logger to use if there's a recoverable parsing error and {@code
 * goog.json.TRY_NATIVE_JSON} is enabled.
 * @param {function(string, !Error)} errorLogger The first parameter is the
 *     error message, the second is the exception thrown by {@code JSON.parse}.
 */
goog.json.setErrorLogger = function(errorLogger) {
  goog.json.errorLogger_ = errorLogger;
};


/**
 * Parses a JSON string and returns the result. This throws an exception if
 * the string is an invalid JSON string.
 *
 * Note that this is very slow on large strings. Use JSON.parse if possible.
 *
 * @param {*} s The JSON string to parse.
 * @throws Error if s is invalid JSON.
 * @return {Object} The object generated from the JSON string, or null.
 */
goog.json.parse = goog.json.USE_NATIVE_JSON ?
    /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :
    function(s) {
      var error;
      if (goog.json.TRY_NATIVE_JSON) {
        try {
          return goog.global['JSON']['parse'](s);
        } catch (ex) {
          error = ex;
        }
      }
      var o = String(s);
      if (goog.json.isValid(o)) {

        try {
          var result = /** @type {?Object} */ (eval('(' + o + ')'));
          if (error) {
            goog.json.errorLogger_('Invalid JSON: ' + o, error);
          }
          return result;
        } catch (ex) {
        }
      }
      throw new Error('Invalid JSON string: ' + o);
    };
<commit_msg>RELNOTES: Deprecate goog.json.parse. Use JSON.parse.<commit_after>// Copyright 2006 The Closure Library Authors. All Rights Reserved.
//
// 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.

/**
 * @fileoverview JSON utility functions.
 * @author <EMAIL> (<NAME>)
 */


goog.provide('goog.json');
goog.provide('goog.json.Replacer');
goog.provide('goog.json.Reviver');
goog.provide('goog.json.Serializer');


/**
 * @define {boolean} If true, use the native JSON parsing API.
 * NOTE: The default {@code goog.json.parse} implementation is able to handle
 * invalid JSON. JSPB used to produce invalid JSON which is not the case
 * anymore so this is safe to enable for parsing JSPB. Using native JSON is
 * faster and safer than the default implementation using {@code eval}.
 */
goog.define('goog.json.USE_NATIVE_JSON', false);

/**
 * @define {boolean} If true, try the native JSON parsing API first. If it
 * fails, log an error and use {@code eval} instead. This is useful when
 * transitioning to {@code goog.json.USE_NATIVE_JSON}. The error logger needs to
 * be set by {@code goog.json.setErrorLogger}. If it is not set then the error
 * is ignored.
 */
goog.define('goog.json.TRY_NATIVE_JSON', false);


/**
 * Tests if a string is an invalid JSON string. This only ensures that we are
 * not using any invalid characters
 * @param {string} s The string to test.
 * @return {boolean} True if the input is a valid JSON string.
 */
goog.json.isValid = function(s) {
  // All empty whitespace is not valid.
  if (/^\s*$/.test(s)) {
    return false;
  }

  // This is taken from http://www.json.org/json2.js which is released to the
  // public domain.
  // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator
  // inside strings.  We also treat \u2028 and \u2029 as whitespace which they
  // are in the RFC but IE and Safari does not match \s to these so we need to
  // include them in the reg exps in all places where whitespace is allowed.
  // We allowed \x7f inside strings because some tools don't escape it,
  // e.g. http://www.json.org/java/org/json/JSONObject.java

  // Parsing happens in three stages. In the first stage, we run the text
  // against regular expressions that look for non-JSON patterns. We are
  // especially concerned with '()' and 'new' because they can cause invocation,
  // and '=' because it can cause mutation. But just to be safe, we want to
  // reject all unexpected forms.

  // We split the first stage into 4 regexp operations in order to work around
  // crippling inefficiencies in IE's and Safari's regexp engines. First we
  // replace all backslash pairs with '@' (a non-JSON character). Second, we
  // replace all simple value tokens with ']' characters, but only when followed
  // by a colon, comma, closing bracket or end of string. Third, we delete all
  // open brackets that follow a colon or comma or that begin the text. Finally,
  // we look to see that the remaining characters are only whitespace or ']' or
  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

  // Don't make these static since they have the global flag.
  var backslashesRe = /\\["\\\/bfnrtu]/g;
  var simpleValuesRe =
      /(?:"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)[\s\u2028\u2029]*(?=:|,|]|}|$)/g;
  var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
  var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;

  return remainderRe.test(
      s.replace(backslashesRe, '@')
          .replace(simpleValuesRe, ']')
          .replace(openBracketsRe, ''));
};

/**
 * Logs a parsing error in {@code JSON.parse} solvable by using {@code eval}
 * if {@code goog.json.TRY_NATIVE_JSON} is enabled.
 * @private {function(string, !Error)} The first parameter is the error message,
 *     the second is the exception thrown by {@code JSON.parse}.
 */
goog.json.errorLogger_ = goog.nullFunction;


/**
 * Sets an error logger to use if there's a recoverable parsing error and {@code
 * goog.json.TRY_NATIVE_JSON} is enabled.
 * @param {function(string, !Error)} errorLogger The first parameter is the
 *     error message, the second is the exception thrown by {@code JSON.parse}.
 */
goog.json.setErrorLogger = function(errorLogger) {
  goog.json.errorLogger_ = errorLogger;
};


/**
 * Parses a JSON string and returns the result. This throws an exception if
 * the string is an invalid JSON string.
 *
 * Note that this is very slow on large strings. Use JSON.parse if possible.
 *
 * @param {*} s The JSON string to parse.
 * @throws Error if s is invalid JSON.
 * @return {Object} The object generated from the JSON string, or null.
 * @deprecated Use JSON.parse.
 */
goog.json.parse = goog.json.USE_NATIVE_JSON ?
    /** @type {function(*):Object} */ (goog.global['JSON']['parse']) :
    function(s) {
      var error;
      if (goog.json.TRY_NATIVE_JSON) {
        try {
          return goog.global['JSON']['parse'](s);
        } catch (ex) {
          error = ex;
        }
      }
      var o = String(s);
      if (goog.json.isValid(o)) {

        try {
          var result = /** @type {?Object} */ (eval('(' + o + ')'));
          if (error) {
            goog.json.errorLogger_('Invalid JSON: ' + o, error);
          }
          return result;
        } catch (ex) {
        }
      }
      throw new Error('Invalid JSON string: ' + o);
    };

{'fraction_non_alphanumeric': 0.1292470548062148, 'fraction_numerical': 0.011097831654430595, 'mean_word_length': 2.99965858654831, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5253743', 'n_tokens_mistral': 3680, 'n_tokens_neox': 3461, 'n_words': 1401}