Skip to content

JSONp API request (with callback) strips first and last character from result #18133

@tomudding

Description

@tomudding

Expected Behavior

I am making a JSONp request to the Overlay API with a specific callback value, as follows:

https://demo.matomo.cloud/?module=API&method=Overlay.getTranslations&idSite=1&format=JSON&jsoncallback=__jsonp1

I expect to get back the following:

__jsonp1([{"oneClick":"1 click","clicks":"%s clicks","clicksFromXLinks":"%1$s clicks from one of %2$s links","link":"Link"}])

Current Behavior

What is actually returned:

_jsonp1([{"oneClick":"1 click","clicks":"%s clicks","clicksFromXLinks":"%1$s clicks from one of %2$s links","link":"Link"}]

The first and last character are missing.

Possible Solution

This issue comes from this specific check and call to substr(). If the array is simple (i.e., one-dimensional), the first and last character are removed to create an output like {...} instead of [{...}].

// if $array is a simple associative array, remove the JSON root array that is added by renderDataTable
if (!empty($array)
&& Piwik::isAssociativeArray($array)
&& !Piwik::isMultiDimensionalArray($array)
) {
$result = substr($result, 1, strlen($result) - 2);
}
return $result;

However, this does not account for the call to renderDataTable() just before that. Which, when using JSONp with a callback will prepend callback(, and append ).

The substr() will strip the first character of the callback and the closing parentheses. This creates invalid JavaScript, which in turn cannot be used.

The easiest way to fix this would be to add an additional check to the if statement: $this->isJsonp():

 // if $array is a simple associative array, remove the JSON root array that is added by renderDataTable 
 if (!empty($array) 
+    && !this->isJsonp() 
     && Piwik::isAssociativeArray($array) 
     && !Piwik::isMultiDimensionalArray($array) 
 ) { 
     $result = substr($result, 1, strlen($result) - 2); 
 } 
  
 return $result; 

Steps to Reproduce (for Bugs)

  1. Go to https://demo.matomo.cloud/?module=API&method=Overlay.getTranslations&idSite=1&format=JSON&jsoncallback=__jsonp1 or any other API function which returns a simple array.
  2. Observe incorrect output.

Context

Your Environment

  • Matomo Version: 4.4.1
  • PHP Version: 7.4

Metadata

Metadata

Labels

BugFor errors / faults / flaws / inconsistencies etc.RegressionIndicates a feature used to work in a certain way but it no longer does even though it should.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions