Skip to content

oidc - JavaScript-Adapter LocalStorage#clearExpired does not clear all possible items #15635

@tomsontom

Description

@tomsontom

Area

adapter/javascript

Describe the bug

It does not really cause a huge problem but the code in LocalStorage#clearExpired looks suspicous because if keys who start with 'kc-callback-' are next to each other only every 2nd will be cleared.

function clearExpired() {
var time = new Date().getTime();
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
if (key && key.indexOf('kc-callback-') == 0) {
var value = localStorage.getItem(key);
if (value) {
try {
var expires = JSON.parse(value).expires;
if (!expires || expires < time) {
localStorage.removeItem(key);
}
} catch (err) {
localStorage.removeItem(key);
}
}
}
}
}

If you look at the code you see it walks the local-storage and removes if the key starts with 'kc-callback-' but as i is advanced everytime and hence always the key exactly after the removed is missed.

It is not a big problem because it will be simply cleared on the next call.

I have no reproducer for keycloak.js but the effect can be seen in browser dev-tools if you execute the code below:

localStorage.length // prints 0
localStorage.setItem('kc-callback-a', 'a'); 
localStorage.setItem('kc-callback-b', 'b'); 
for( let i = 0; i < localStorage.length; i++ ) { if( localStorage.key(i).startsWith('kc-callback-') ) { localStorage.removeItem(localStorage.key(i)) } } 
localStorage.length  // prints 1 but it would be expected to be 0

Version

main

Expected behavior

I think the expected behavior is that the cache is clearExpired clears all possible entries and does not leave entries who could have been removed.

Actual behavior

Not all possible entries are removed.

How to Reproduce?

see bug description

Anything else?

The simplest possible solution is to reverse the loop

for (var i = 0; i < localStorage.length; i++)  {

to

for (var i = localStorage.length - 1; i >= 0; i--)  {

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions