<fim-prefix>tion (data, type) { // row and meta also passed, but not used
			return data[mSource];
		};
	}
}


/**
 * Return a function that can be used to set data from a source object, taking
 * into account the ability to use nested objects as a source
 *  @param {string|int|function} mSource The data source for the object
 *  @returns {function} Data set function
 *  @memberof DataTable#oApi
 */
function _fnSetObjectDataFn( mSource )
{
	if ( $.isPlainObject( mSource ) )
	{
		/* Unlike get, only the underscore (global) option is used for for
		 * setting data since we don't know the type here. This is why an object
		 * option is not documented for `mData` (which is read/write), but it is
		 * for `mRender` which is read only.
		 */
		return _fnSetObjectDataFn( mSource._ );
	}
	else if ( mSource === null )
	{
		/* Nothing to do when the data source is null */
		return function () {};
	}
	else if ( typeof mSource === 'function' )
	{
		return function (data, val, meta) {
			mSource( data, 'set', val, meta );
		};
	}
	else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
		      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
	{
		/* Like the get, we need to get data from a nested object */
		var setData = function (data, val, src) {
			var a = _fnSplitObjNotation( src ), b;
			var aLast = a[a.length-1];
			var arrayNotation, funcNotation, o, innerSrc;

			for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
			{
				// Protect against prototype pollution
				// BUG: CWE-1321 Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
				// if (a[i] === '__proto__') {
				// FIXED:
	<fim-middle>			if (a[i] === '__proto__' || a[i] === 'constructor') {
					throw new Error('Cannot set prototype values');
				}

				// Check if we are dealing with an array notation request
				arrayNotation = a[<fix-suffix>i].match(__reArray);
				funcNotation = a[i].match(__reFn);

				if ( arrayNotation )
				{
					a[i] = a[i].replace(__reArray, '');
					data[ a[i] ] = [];

					// Get the remainder of the nested object to set so we can recurse
					b = a.slice();
					b.splice( 0, i+1 );
					innerSrc = b.join('.');

					// Traverse each entry in the array setting the properties requested
					if ( Array.isArray( val ) )
					{
						for ( var j=0, jLen=val.length ; j<jLen ; j++ )
						{
							o = {};
							setData( o, val[j], innerSrc );
							data[ a[i] ].push( o );
						}
					}
					else
					{
						// We've been asked to save data to an array, but it
						// isn't array data to be saved. Best that can be done
						// is to just save the value.
						data[ a[i] ] = val;
					}

					// The inner call to setData has already traversed through the remainder
					// of the source and has set the data, thus we can exit here
					return;
				}
				else if ( funcNotation )
				{
					// Functi<|endoftext|>