in source/sigv4.c [1807:1877]
static void processAmpersandInQueryString( bool fieldHasValue,
size_t currQueryIndex,
size_t * pStartOfFieldOrValue,
size_t * pCurrParamCount,
const char * pQuery,
CanonicalContext_t * pCanonicalRequest )
{
bool previousParamIsValid = true;
assert( pCurrParamCount != NULL );
assert( pStartOfFieldOrValue != NULL );
assert( pQuery != NULL );
assert( pCanonicalRequest != NULL );
/* Process scenarios when a value for the previous parameter entry has been detected. */
if( fieldHasValue )
{
/* Case when parameter has empty value even though the query parameter entry has the form
* "<param>=". */
if( ( currQueryIndex - *pStartOfFieldOrValue ) == 0U )
{
/* Store the previous parameter's empty value information. Use NULL to represent empty value. */
setQueryParameterValue( *pCurrParamCount, NULL, 0U, pCanonicalRequest );
}
/* This represents the case when the previous parameter has a value associated with it. */
else
{
/* End of value reached, so store a pointer to the previously set value. */
setQueryParameterValue( *pCurrParamCount, &( pQuery[ *pStartOfFieldOrValue ] ), currQueryIndex - *pStartOfFieldOrValue, pCanonicalRequest );
}
}
/* A parameter value has not been found for the previous parameter. */
else
{
/* Ignore unnecessary '&' that represent empty parameter names.
* Trimmable '&'s can be leading, trailing or repeated as separators between parameter
* pairs.
* For example, this function will prune "&p1=v1&&p2=v2&" to "p1=v1&p2=v2". */
if( ( currQueryIndex - *pStartOfFieldOrValue ) == 0U )
{
/* Do nothing as previous parameter name is empty. */
previousParamIsValid = false;
}
/* Case when a new query parameter pair has begun without the previous parameter having an associated value,
* i.e. of the format "<param1>&<param2>=<value>" where "<param1>".
* In thus case, as the previous parameter does not have a value, we will store an empty value for it. */
else
{
/* Store information about previous query parameter name. The query parameter has no associated value. */
setQueryParameterKey( *pCurrParamCount, &( pQuery[ *pStartOfFieldOrValue ] ), currQueryIndex - *pStartOfFieldOrValue, pCanonicalRequest );
/* Store the previous parameter's empty value information. Use NULL to represent empty value. */
setQueryParameterValue( *pCurrParamCount, NULL, 0U, pCanonicalRequest );
}
}
/* Increment the parameter count if the previous parameter is not empty
* An empty previous parameter is caused in query strings where the '&' are unnecessary. */
if( previousParamIsValid == true )
{
/* As the previous parameter is valid, increment the total parameters
* parsed so far from the query string. */
( *pCurrParamCount )++;
}
/* As '&' is always treated as a separator, update the starting index to represent the next
* query parameter. */
*pStartOfFieldOrValue = currQueryIndex + 1U;
}