Skip to content

Commit

Permalink
ortbConverter: fix bug where ${AUCTION_PRICE} in nurl is not escaped (#…
Browse files Browse the repository at this point in the history
…11388)

* ortbConverter: fix bug where  in nurl is not escaped

* fix engageya
  • Loading branch information
dgirardi authored Apr 24, 2024
1 parent d3d452e commit 129cfb5
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
4 changes: 2 additions & 2 deletions libraries/ortbConverter/processors/banner.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {createTrackPixelHtml, deepAccess, inIframe, mergeDeep} from '../../../src/utils.js';
import {createTrackPixelHtml, deepAccess, encodeMacroURI, inIframe, mergeDeep} from '../../../src/utils.js';
import {BANNER} from '../../../src/mediaTypes.js';
import {sizesToFormat} from '../lib/sizes.js';

Expand All @@ -24,7 +24,7 @@ export function fillBannerImp(imp, bidRequest, context) {
}
}

export function bannerResponseProcessor({createPixel = (url) => createTrackPixelHtml(decodeURIComponent(url))} = {}) {
export function bannerResponseProcessor({createPixel = (url) => createTrackPixelHtml(decodeURIComponent(url), encodeMacroURI)} = {}) {
return function fillBannerResponse(bidResponse, bid) {
if (bidResponse.mediaType === BANNER) {
if (bid.adm && bid.nurl) {
Expand Down
2 changes: 1 addition & 1 deletion modules/engageyaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function parseBannerResponse(rec, response) {
const title = rec.title && rec.title.trim() ? `<div class="eng_tag_ttl" style="display: none">${rec.title}</div>` : '';
const displayName = rec.displayName && title ? `<div class="eng_tag_brnd" style="display: none">${rec.displayName}</div>` : '';
const trackers = getImpressionTrackers(rec, response)
.map(createTrackPixelHtml)
.map((url) => createTrackPixelHtml(url))
.join('');
return `<html><body>${style}<div id="ENG_TAG"><a href="${rec.clickUrl}" target=_blank><img class="eng_tag_img" src="${getImageSrc(rec)}" style="width:${response.imageWidth}px;height:${response.imageHeight}px;" alt="${rec.title}"/>${displayName}${title}</a>${trackers}</div></body></html>`;
}
Expand Down
17 changes: 15 additions & 2 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,32 @@ export function insertUserSyncIframe(url, done, timeout) {
/**
* Creates a snippet of HTML that retrieves the specified `url`
* @param {string} url URL to be requested
* @param encode
* @return {string} HTML snippet that contains the img src = set to `url`
*/
export function createTrackPixelHtml(url) {
export function createTrackPixelHtml(url, encode = encodeURI) {
if (!url) {
return '';
}

let escapedUrl = encodeURI(url);
let escapedUrl = encode(url);
let img = '<div style="position:absolute;left:0px;top:0px;visibility:hidden;">';
img += '<img src="' + escapedUrl + '"></div>';
return img;
};

/**
* encodeURI, but preserves macros of the form '${MACRO}' (e.g. '${AUCTION_PRICE}')
* @param url
* @return {string}
*/
export function encodeMacroURI(url) {
const macros = Array.from(url.matchAll(/\$({[^}]+})/g)).map(match => match[1]);
return macros.reduce((str, macro) => {
return str.replace('$' + encodeURIComponent(macro), '$' + macro)
}, encodeURI(url))
}

/**
* Creates a snippet of Iframe HTML that retrieves the specified `url`
* @param {string} url plain URL to be requested
Expand Down
18 changes: 17 additions & 1 deletion test/spec/utils_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {expect} from 'chai';
import { TARGETING_KEYS } from 'src/constants.js';
import * as utils from 'src/utils.js';
import {getHighestCpm, getLatestHighestCpmBid, getOldestHighestCpmBid} from '../../src/utils/reducers.js';
import {binarySearch, deepEqual, memoize, waitForElementToLoad} from 'src/utils.js';
import {binarySearch, deepEqual, encodeMacroURI, memoize, waitForElementToLoad} from 'src/utils.js';
import {convertCamelToUnderscore} from '../../libraries/appnexusUtils/anUtils.js';

var assert = require('assert');
Expand Down Expand Up @@ -778,6 +778,22 @@ describe('Utils', function () {
expect(parsed.search).to.equal('?search=test&foo=bar&bar=foo&foo=xxx');
});
});

describe('encodeMacroURI', () => {
[
['https://www.example.com', 'https://www.example.com'],
['https://www.example/${MACRO}', 'https://www.example/${MACRO}'],
['http://www.example/è', `http://www.example/${encodeURIComponent('è')}`],
['https://www.${MACRO_1}/${MACRO_1}/${MACRO_2}è', 'https://www.${MACRO_1}/${MACRO_1}/${MACRO_2}' + encodeURIComponent('è')],
['http://${MACRO}${MACRO}/${MACRO}', 'http://${MACRO}${MACRO}/${MACRO}'],
['{MACRO}${MACRO}', `${encodeURIComponent('{MACRO}')}\${MACRO}`],
['https://www.example.com?p=${AUCTION_PRICE}', 'https://www.example.com?p=${AUCTION_PRICE}']
].forEach(([input, expected]) => {
it(`can encode ${input} -> ${expected}`, () => {
expect(encodeMacroURI(input)).to.eql(expected);
})
})
})
});

describe('insertElement', function () {
Expand Down

0 comments on commit 129cfb5

Please sign in to comment.