GM.getValue throws InvalidCharacterError: String contains an invalid character
cvzi opened this issue · 6 comments
Expected Behavior
Trying to retrieve a string with GM.getValue
(The string is quite long)
Actual Behavior
Throws an error InvalidCharacterError
Specifications
- Firefox: 107.0.1
- TM: Beta 4.19.6176
- OS: Windows 10
Script
// ==UserScript==
// @name Test script
// @namespace cuzi
// @include https://*
// @version 1.0.0
// @grant GM.setValue
// @grant GM.getValue
// ==/UserScript==
console.log('try getValue')
GM.getValue('tralbumlibrary').then(function (str) {
console.log('success')
})
Log
content: normal start event processing for lbiu5j5e.ims (6 to run)
env: schedule "Test script" for document-idle
env: inject "Test script" now
content: DOMContentLoaded
env: run "Test script" now (0 requires)
try getValue
InvalidCharacterError: String contains an invalid character
content: load
I attached the exported script with its storage:
Test script export.zip
Edit:
When I import the script in Chrome, I get a different error:
Uncaught (in promise) DOMException: Failed to execute 'atob' on 'Window': The string to be decoded contains characters outside of the Latin1 range
Hi, I also encountered the same error.
After checking the js code, it is found that the error occurs in the newly added page.js
file after version 4.18 of tampermonkey chrome, the js code that will cause errors is [decode:e=>Ae(e)
], because the js is obfuscated and compressed, and this "Ae
" is the atob()
function.
Here is a simple example to reproduce the error:
atob("ᦃ")
Uncaught DOMException: Failed to execute 'atob' on 'Window': The string to be decoded contains characters outside of the Latin1 range.
The solution may refer to stackoverflow:
var x = btoa(unescape(encodeURIComponent("ᦃ")));
var y = decodeURIComponent(escape(atob(x)));
x => '4aaD'
y => 'ᦃ'
I can reproduce the issue with the exported files, but the storage seems to be modified manually.
The key "tralbumlibrary" should contain a Base64 encoded string, but it doesn't. That's why decoding the string fails.
Simply modify the exported storage from
{"ts":1670722922352,"data":{"tralbumlibrary":"x{
to
{"ts":1670722922352,"data":{"tralbumlibrary":"s{
to fix the issue.
Is there a way to fix this in the script code? I don't think the average user will be able to fix this manually
Hi, derjanb
My script also has the same error issue, but I can't manually modify the storage, explain the reason below.
I used LZString to compressToUTF16 the string before setValue, and then decompressFromUTF16 the string after getValue, it works normally before 4.18 in chrome.
Script
// ==UserScript==
// @require https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
const sObj = {
isGM: typeof GM_getValue != 'undefined' && typeof GM_getValue('a', 'b') != 'undefined',
setValue: function (name, value) {
value = JSON.stringify(value)
value = LZString.compressToUTF16(value)
return this.isGM ? GM_setValue(name, value) : localStorage.setItem(name, value)
},
getValue: function(name, def){
let value = this.isGM ? GM_getValue(name) : localStorage.getItem(name)
value = value ? LZString.decompressFromUTF16(value) : null
return value ? JSON.parse(value) : def
}
}
but the storage seems to be modified manually.
I withdraw my statement and claim the opposite! I found the bug. 🙈
Should be fixed at 4.19.6177 (crx|xpi)
Chrome/Edge users, please download the crx file linked above and drag and drop it to the extensions page chrome://extensions
.
Firefox users please install the BETA version or check for BETA version updates at about:addons
For a quick fix please export your settings and scripts as zip or (JSON) file at the "Utilities" tab and import it back at the fixed BETA version.