Tampermonkey/tampermonkey

GM.getValue throws InvalidCharacterError: String contains an invalid character

cvzi opened this issue · 6 comments

cvzi commented

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 => 'ᦃ'

Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

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.

cvzi commented

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.