googleads / googleads-consent-sdk-ios

Consent SDK
https://developers.google.com/admob/ios/eu-consent
Apache License 2.0
31 stars 47 forks source link

"Unable to convert data to string around character" error while requesting consent info #13

Open accidbright opened 6 years ago

accidbright commented 6 years ago

I was trying to detect EEA user with this SDK, but found strange behavior. When user is not EEA, SDK works well both simulator and device. When user is EEA, it works correctly only on simulator. Trying to run at the device (tested on both iOS 10.3.3 and iOS 11.3 versions) and it fails

Here is my source

NSString * publisherId = @"pub-0123456789012345";
[PACConsentInformation.sharedInstance requestConsentInfoUpdateForPublisherIdentifiers:@[publisherId]
                                                                    completionHandler:^(NSError * _Nullable error) {
                                                                        if (error) {
                                                                            NSLog(@"Detecting EEA member error: %@", error);
                                                                        }
                                                                        BOOL isEEA = PACConsentInformation.sharedInstance.requestLocationInEEAOrUnknown;
                                                                        NSLog(@"Is%@EEA member", isEEA ? @" " : @" not ");
                                                                    }];

And it produces next log:

2018-05-24 16:44:31.471684+0300 GDPRConsentSample[1033:674075] Detecting EEA member error: Error Domain=NSCocoaErrorDomain Code=3840 "Unable to convert data to string around character 19596." UserInfo={NSDebugDescription=Unable to convert data to string around character 19596.}
2018-05-24 16:44:31.471994+0300 GDPRConsentSample[1033:674075] Is not EEA member

I found out that error occurs during response parsing:

// From file PACPersonalizedAdConsent.m:328
NSDictionary<NSString *, id> *info = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

Source was taken from cocoapods, version 1.0.0

stowy commented 6 years ago

Hi,

Can you capture the response and perhaps provide a sample project? We are unable to reproduce this error locally.

Thanks

Sam

accidbright commented 6 years ago

Tested with SDK version 1.0.1, issue is still the same. Here is sample project, that can show issue: https://github.com/accidbright/PACConsentSample Here are the response headers:

<NSHTTPURLResponse: 0x1c8032980> { URL: https://adservice.google.com/getconfig/pubvendors?es=2&plat=ios&v=1.0.1&pubs=pub-0123456789012345 } { Status Code: 200, Headers {
    "Access-Control-Allow-Origin" =     (
                                         "*"
                                         );
    "Cache-Control" =     (
                           private
                           );
    "Content-Disposition" =     (
                                 "attachment; filename=\"f.txt\""
                                 );
    "Content-Encoding" =     (
                              gzip
                              );
    "Content-Length" =     (
                            5545
                            );
    "Content-Type" =     (
                          "application/json; charset=windows-1251"
                          );
    Date =     (
                "Fri, 25 May 2018 09:01:27 GMT"
                );
    Server =     (
                  cafe
                  );
    "alt-svc" =     (
                     "hq=\"googleads.g.doubleclick.net:443\"; ma=2592000; quic=51303433; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=\"googleads.g.doubleclick.net:443\"; ma=2592000; v=\"43,42,41,39,35\",hq=\":443\"; ma=2592000; quic=51303433; quic=51303432; quic=51303431; quic=51303339; quic=51303335,quic=\":443\"; ma=2592000; v=\"43,42,41,39,35\""
                     );
    p3p =     (
               "policyref=\"https://www.googleadservices.com/pagead/p3p.xml\", CP=\"NOI DEV PSA PSD IVA IVD OTP OUR OTR IND OTC\""
               );
    "timing-allow-origin" =     (
                                 "*"
                                 );
    "x-content-type-options" =     (
                                    nosniff
                                    );
    "x-xss-protection" =     (
                              "1; mode=block"
                              );
} }
accidbright commented 6 years ago

Already found the issue by myself. There is encoding problem. According to official Apple docs the method JSONObjectWithData:options:error: expects UTF encoding:

The data must be in one of the 5 supported encodings listed in the JSON specification: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE.

But data in response is encoded with CP1251. That is not supported by this method.

As the solution I can offer next code:

NSString * dataString = [[NSString alloc] initWithData:data encoding:NSWindowsCP1251StringEncoding];
NSData * dataInUTFEncoding = [dataString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary<NSString *, id> *info = [NSJSONSerialization JSONObjectWithData:dataInUTFEncoding options:0 error:&error];

instead of existing:

// From file PACPersonalizedAdConsent.m:328
NSDictionary<NSString *, id> *info = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

This code works for me.

hei9gag commented 6 years ago

I can reproduce this error using real device but not in simulator

Izzyjm commented 5 years ago

has this issue been fixed ? why does it fail only on 10.3.3 and 11.3 ? if apple only supports "UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE" then how is it even working at all with CP1251 on non 10.1 and 11.3 devices & how come mine says charset=ISO-8859-1 and not windows1251? @hei9gag @accidbright