This file is indexed.

/usr/share/javascript/yui3/dataschema-json/dataschema-json.js is in libjs-yui3-full 3.5.1-1ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
/*
YUI 3.5.1 (build 22)
Copyright 2012 Yahoo! Inc. All rights reserved.
Licensed under the BSD License.
http://yuilibrary.com/license/
*/
YUI.add('dataschema-json', function(Y) {

/**
Provides a DataSchema implementation which can be used to work with JSON data.

@module dataschema
@submodule dataschema-json
**/

/**
Provides a DataSchema implementation which can be used to work with JSON data.

See the `apply` method for usage.

@class DataSchema.JSON
@extends DataSchema.Base
@static
**/
var LANG = Y.Lang,
    isFunction = LANG.isFunction,
    isObject   = LANG.isObject,
    isArray    = LANG.isArray,
    // TODO: I don't think the calls to Base.* need to be done via Base since
    // Base is mixed into SchemaJSON.  Investigate for later.
    Base       = Y.DataSchema.Base,

    SchemaJSON;
    
SchemaJSON = {

/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.JSON static methods
//
/////////////////////////////////////////////////////////////////////////////
    /**
     * Utility function converts JSON locator strings into walkable paths
     *
     * @method getPath
     * @param locator {String} JSON value locator.
     * @return {String[]} Walkable path to data value.
     * @static
     */
    getPath: function(locator) {
        var path = null,
            keys = [],
            i = 0;

        if (locator) {
            // Strip the ["string keys"] and [1] array indexes
            // TODO: the first two steps can probably be reduced to one with
            // /\[\s*(['"])?(.*?)\1\s*\]/g, but the array indices would be
            // stored as strings.  This is not likely an issue.
            locator = locator.
                replace(/\[\s*(['"])(.*?)\1\s*\]/g,
                function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}).
                replace(/\[(\d+)\]/g,
                function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}).
                replace(/^\./,''); // remove leading dot

            // Validate against problematic characters.
            // commented out because the path isn't sent to eval, so it
            // should be safe. I'm not sure what makes a locator invalid.
            //if (!/[^\w\.\$@]/.test(locator)) {
            path = locator.split('.');
            for (i=path.length-1; i >= 0; --i) {
                if (path[i].charAt(0) === '@') {
                    path[i] = keys[parseInt(path[i].substr(1),10)];
                }
            }
            /*}
            else {
            }
            */
        }
        return path;
    },

    /**
     * Utility function to walk a path and return the value located there.
     *
     * @method getLocationValue
     * @param path {String[]} Locator path.
     * @param data {String} Data to traverse.
     * @return {Object} Data value at location.
     * @static
     */
    getLocationValue: function (path, data) {
        var i = 0,
            len = path.length;
        for (;i<len;i++) {
            if (isObject(data) && (path[i] in data)) {
                data = data[path[i]];
            } else {
                data = undefined;
                break;
            }
        }
        return data;
    },

    /**
    Applies a schema to an array of data located in a JSON structure, returning
    a normalized object with results in the `results` property. Additional
    information can be parsed out of the JSON for inclusion in the `meta`
    property of the response object.  If an error is encountered during
    processing, an `error` property will be added.

    The input _data_ is expected to be an object or array.  If it is a string,
    it will be passed through `Y.JSON.parse()`.

    If _data_ contains an array of data records to normalize, specify the
    _schema.resultListLocator_ as a dot separated path string just as you would
    reference it in JavaScript.  So if your _data_ object has a record array at
    _data.response.results_, use _schema.resultListLocator_ =
    "response.results". Bracket notation can also be used for array indices or
    object properties (e.g. "response['results']");  This is called a "path
    locator"

    Field data in the result list is extracted with field identifiers in
    _schema.resultFields_.  Field identifiers are objects with the following
    properties:

      * `key`   : <strong>(required)</strong> The path locator (String)
      * `parser`: A function or the name of a function on `Y.Parsers` used
            to convert the input value into a normalized type.  Parser
            functions are passed the value as input and are expected to
            return a value.

    If no value parsing is needed, you can use path locators (strings) 
    instead of field identifiers (objects) -- see example below.

    If no processing of the result list array is needed, _schema.resultFields_
    can be omitted; the `response.results` will point directly to the array.

    If the result list contains arrays, `response.results` will contain an
    array of objects with key:value pairs assuming the fields in
    _schema.resultFields_ are ordered in accordance with the data array
    values.

    If the result list contains objects, the identified _schema.resultFields_
    will be used to extract a value from those objects for the output result.

    To extract additional information from the JSON, include an array of
    path locators in _schema.metaFields_.  The collected values will be
    stored in `response.meta`.


    @example
        // Process array of arrays
        var schema = {
                resultListLocator: 'produce.fruit',
                resultFields: [ 'name', 'color' ]
            },
            data = {
                produce: {
                    fruit: [
                        [ 'Banana', 'yellow' ],
                        [ 'Orange', 'orange' ],
                        [ 'Eggplant', 'purple' ]
                    ]
                }
            };

        var response = Y.DataSchema.JSON.apply(schema, data);

        // response.results[0] is { name: "Banana", color: "yellow" }

        
        // Process array of objects + some metadata
        schema.metaFields = [ 'lastInventory' ];

        data = {
            produce: {
                fruit: [
                    { name: 'Banana', color: 'yellow', price: '1.96' },
                    { name: 'Orange', color: 'orange', price: '2.04' },
                    { name: 'Eggplant', color: 'purple', price: '4.31' }
                ]
            },
            lastInventory: '2011-07-19'
        };

        response = Y.DataSchema.JSON.apply(schema, data);

        // response.results[0] is { name: "Banana", color: "yellow" }
        // response.meta.lastInventory is '2001-07-19'


        // Use parsers
        schema.resultFields = [
            {
                key: 'name',
                parser: function (val) { return val.toUpperCase(); }
            },
            {
                key: 'price',
                parser: 'number' // Uses Y.Parsers.number
            }
        ];

        response = Y.DataSchema.JSON.apply(schema, data);

        // Note price was converted from a numeric string to a number
        // response.results[0] looks like { fruit: "BANANA", price: 1.96 }
     
    @method apply
    @param {Object} [schema] Schema to apply.  Supported configuration
        properties are:
      @param {String} [schema.resultListLocator] Path locator for the
          location of the array of records to flatten into `response.results`
      @param {Array} [schema.resultFields] Field identifiers to
          locate/assign values in the response records. See above for
          details.
      @param {Array} [schema.metaFields] Path locators to extract extra
          non-record related information from the data object.
    @param {Object|Array|String} data JSON data or its string serialization.
    @return {Object} An Object with properties `results` and `meta`
    @static
    **/
    apply: function(schema, data) {
        var data_in = data,
            data_out = { results: [], meta: {} };

        // Convert incoming JSON strings
        if (!isObject(data)) {
            try {
                data_in = Y.JSON.parse(data);
            }
            catch(e) {
                data_out.error = e;
                return data_out;
            }
        }

        if (isObject(data_in) && schema) {
            // Parse results data
            data_out = SchemaJSON._parseResults.call(this, schema, data_in, data_out);

            // Parse meta data
            if (schema.metaFields !== undefined) {
                data_out = SchemaJSON._parseMeta(schema.metaFields, data_in, data_out);
            }
        }
        else {
            data_out.error = new Error("JSON schema parse failure");
        }

        return data_out;
    },

    /**
     * Schema-parsed list of results from full data
     *
     * @method _parseResults
     * @param schema {Object} Schema to parse against.
     * @param json_in {Object} JSON to parse.
     * @param data_out {Object} In-progress parsed data to update.
     * @return {Object} Parsed data object.
     * @static
     * @protected
     */
    _parseResults: function(schema, json_in, data_out) {
        var getPath  = SchemaJSON.getPath,
            getValue = SchemaJSON.getLocationValue,
            path     = getPath(schema.resultListLocator),
            results  = path ?
                        (getValue(path, json_in) ||
                         // Fall back to treat resultListLocator as a simple key
                            json_in[schema.resultListLocator]) :
                        // Or if no resultListLocator is supplied, use the input
                        json_in;

        if (isArray(results)) {
            // if no result fields are passed in, then just take
            // the results array whole-hog Sometimes you're getting
            // an array of strings, or want the whole object, so
            // resultFields don't make sense.
            if (isArray(schema.resultFields)) {
                data_out = SchemaJSON._getFieldValues.call(this, schema.resultFields, results, data_out);
            } else {
                data_out.results = results;
            }
        } else if (schema.resultListLocator) {
            data_out.results = [];
            data_out.error = new Error("JSON results retrieval failure");
        }

        return data_out;
    },

    /**
     * Get field data values out of list of full results
     *
     * @method _getFieldValues
     * @param fields {Array} Fields to find.
     * @param array_in {Array} Results to parse.
     * @param data_out {Object} In-progress parsed data to update.
     * @return {Object} Parsed data object.
     * @static
     * @protected
     */
    _getFieldValues: function(fields, array_in, data_out) {
        var results = [],
            len = fields.length,
            i, j,
            field, key, locator, path, parser, val,
            simplePaths = [], complexPaths = [], fieldParsers = [],
            result, record;

        // First collect hashes of simple paths, complex paths, and parsers
        for (i=0; i<len; i++) {
            field = fields[i]; // A field can be a simple string or a hash
            key = field.key || field; // Find the key
            locator = field.locator || key; // Find the locator

            // Validate and store locators for later
            path = SchemaJSON.getPath(locator);
            if (path) {
                if (path.length === 1) {
                    simplePaths.push({
                        key : key,
                        path: path[0]
                    });
                } else {
                    complexPaths.push({
                        key    : key,
                        path   : path,
                        locator: locator
                    });
                }
            } else {
            }

            // Validate and store parsers for later
            //TODO: use Y.DataSchema.parse?
            parser = (isFunction(field.parser)) ?
                        field.parser :
                        Y.Parsers[field.parser + ''];

            if (parser) {
                fieldParsers.push({
                    key   : key,
                    parser: parser
                });
            }
        }

        // Traverse list of array_in, creating records of simple fields,
        // complex fields, and applying parsers as necessary
        for (i=array_in.length-1; i>=0; --i) {
            record = {};
            result = array_in[i];
            if(result) {
                // Cycle through complexLocators
                for (j=complexPaths.length - 1; j>=0; --j) {
                    path = complexPaths[j];
                    val = SchemaJSON.getLocationValue(path.path, result);
                    if (val === undefined) {
                        val = SchemaJSON.getLocationValue([path.locator], result);
                        // Fail over keys like "foo.bar" from nested parsing
                        // to single token parsing if a value is found in
                        // results["foo.bar"]
                        if (val !== undefined) {
                            simplePaths.push({
                                key:  path.key,
                                path: path.locator
                            });
                            // Don't try to process the path as complex
                            // for further results
                            complexPaths.splice(i,1);
                            continue;
                        }
                    }

                    record[path.key] = Base.parse.call(this,
                        (SchemaJSON.getLocationValue(path.path, result)), path);
                }

                // Cycle through simpleLocators
                for (j = simplePaths.length - 1; j >= 0; --j) {
                    path = simplePaths[j];
                    // Bug 1777850: The result might be an array instead of object
                    record[path.key] = Base.parse.call(this,
                            ((result[path.path] === undefined) ?
                            result[j] : result[path.path]), path);
                }

                // Cycle through fieldParsers
                for (j=fieldParsers.length-1; j>=0; --j) {
                    key = fieldParsers[j].key;
                    record[key] = fieldParsers[j].parser.call(this, record[key]);
                    // Safety net
                    if (record[key] === undefined) {
                        record[key] = null;
                    }
                }
                results[i] = record;
            }
        }
        data_out.results = results;
        return data_out;
    },

    /**
     * Parses results data according to schema
     *
     * @method _parseMeta
     * @param metaFields {Object} Metafields definitions.
     * @param json_in {Object} JSON to parse.
     * @param data_out {Object} In-progress parsed data to update.
     * @return {Object} Schema-parsed meta data.
     * @static
     * @protected
     */
    _parseMeta: function(metaFields, json_in, data_out) {
        if (isObject(metaFields)) {
            var key, path;
            for(key in metaFields) {
                if (metaFields.hasOwnProperty(key)) {
                    path = SchemaJSON.getPath(metaFields[key]);
                    if (path && json_in) {
                        data_out.meta[key] = SchemaJSON.getLocationValue(path, json_in);
                    }
                }
            }
        }
        else {
            data_out.error = new Error("JSON meta data retrieval failure");
        }
        return data_out;
    }
};

// TODO: Y.Object + mix() might be better here
Y.DataSchema.JSON = Y.mix(SchemaJSON, Base);


}, '3.5.1' ,{requires:['dataschema-base','json']});