Description
When decoding a TcfCaV1 (TCF Canada) GPP section on [iabgpp.com], two fields display incorrect values:
- Purpose [2] "Use limited data to select advertising" shows as not set (should be true for full consent)
- SpecialFeature [1] and [2] show as not set (should be true for full consent)
The @iabgpp/cmpapi library decodes correctly -- the bugs are in the website's decode.js UI code.
Reproduction
Paste this full-consent GPP string into the decoder:
DBABDA~BQhtCJ2QhtCJ2GEABAENCyCf_v-AAP-AAAvrBRAAUAA0ADgAKgAWgA0ACGAEsAKAAXQAzABtADuAH6AQQBCACKAEoAJ0AT4ArYBbgFwAMoAaYA5wB3AEAgJKAkwBOwCfgGKAM0AZ0Az4BrwDiAHVAP4AiYBJ4CVAE5AJ_AUeAqIBUoC3gFwgLoAXuAv8Bg4DMAGggNHAaaA2oBuIDjQHLAPEAeaA-QCAgEJAI3AR_AlKBKqCYAJggTVAmuBOYCfgFJgKWAVOAqsBYQC0QF2wL6gu3ApAAUABwAGgAQwAzABtADuAH4AQgAigBWgDKAHOAO4AgABJQCfgGKAOIAiYBOQCjwFRAKlAXQAv8BmADRwGmgOWAfIBAQCVUEwATBAnMBPwClgFTgLCAWiAu2AA.YAAAAAAAAAA
Expected: All purposes 2-10 and special features 1-2 selected.
Actual: Purpose 2 unselected, special features 1-2 unselected.
Verified with raw binary decode and [UniConsent GPP Decoder] which shows correct results.
Bug 1: Purposes off-by-one (src/js/app/decode.js ~line 230)
The CA GVL has 9 purposes starting at ID 2 (Purpose 1 is unused in TCF Canada). The <select> options are:
options[0] = "[2] Use limited data to select advertising"
options[1] = "[3] Create profiles..."
But PurposesExpressConsent is a 24-element boolean array where index 0 = Purpose 1:
values[0] = false (Purpose 1 -- unused)
values[1] = true (Purpose 2)
The loop uses i as index into both:
for (let i = 0; i < select.length; i++) {
let option = select[i];
if (i < values.length) {
option.selected = values[i] === true;
}
}
So options[0] (labeled "Purpose 2") reads values[0] (Purpose 1 = false) -- shown as unselected.
Fix: Use the option's value to index into the array:
for (let i = 0; i < select.length; i++) {
let option = select[i];
let idx = parseInt(option.value) - 1;
option.selected = idx < values.length && values[idx] === true;
}
Same issue applies to PurposesImpliedConsent (~line 245).
Bug 2: Special features never displayed (src/js/app/decode.js ~line 228)
document.getElementById("tcfcav1-special-feature-express-consent").checked =
cmpApi.getFieldValue("tcfcav1", "SpecialFeatureExpressConsent");
The element is a <select multiple>, not a checkbox. Setting .checked on a <select> does nothing -- special features are never visually selected.
Fix: Iterate over options like purposes:
let values = cmpApi.getFieldValue("tcfcav1", "SpecialFeatureExpressConsent");
let select = document.getElementById("tcfcav1-special-feature-express-consent");
for (let i = 0; i < select.length; i++) {
let option = select[i];
let idx = parseInt(option.value) - 1;
option.selected = idx < values.length && values[idx] === true;
}
Description
When decoding a TcfCaV1 (TCF Canada) GPP section on [iabgpp.com], two fields display incorrect values:
The
@iabgpp/cmpapilibrary decodes correctly -- the bugs are in the website'sdecode.jsUI code.Reproduction
Paste this full-consent GPP string into the decoder:
Expected: All purposes 2-10 and special features 1-2 selected.
Actual: Purpose 2 unselected, special features 1-2 unselected.
Verified with raw binary decode and [UniConsent GPP Decoder] which shows correct results.
Bug 1: Purposes off-by-one (src/js/app/decode.js ~line 230)
The CA GVL has 9 purposes starting at ID 2 (Purpose 1 is unused in TCF Canada). The
<select>options are:options[0]= "[2] Use limited data to select advertising"options[1]= "[3] Create profiles..."But
PurposesExpressConsentis a 24-element boolean array where index 0 = Purpose 1:values[0]= false (Purpose 1 -- unused)values[1]= true (Purpose 2)The loop uses
ias index into both:So
options[0](labeled "Purpose 2") readsvalues[0](Purpose 1 = false) -- shown as unselected.Fix: Use the option's value to index into the array:
Same issue applies to
PurposesImpliedConsent(~line 245).Bug 2: Special features never displayed (src/js/app/decode.js ~line 228)
The element is a
<select multiple>, not a checkbox. Setting.checkedon a<select>does nothing -- special features are never visually selected.Fix: Iterate over options like purposes: