Discussions » Greasy Fork Feedback

Tighten the validity check of the userscript metablock comment?

woxxomMod
§
Posted: 2024-10-14

Examples:

  • 14915, 14422, 15709 start with CODE: // ==UserScript==
  • 472958 starts with /// ==UserScript== (three slashes)

Engines:

  • Chrome and other browsers with built-in support for userscripts don't install it
  • Violentmonkey doesn't install them, doesn't allow to save such code in the editor
  • Greasemonkey installs such scripts ignoring the metablock as matching all sites and nameless (it guesses the name from the URL)
  • Firemonkey and Tampermonkey install them without problems, which is why such scripts appear at all as TM is currently the de facto standard

I think at the very least a skippable warning should be displayed when a broken metablock is uploaded, similarly to the warning when the same version is uploaded.

FYI.

ScriptCat requires // ==UserScript== to be placed in the beginning of the userscript. /* ..... */ cannot be inserted before // ==UserScript==.

Tighten validity check should be necessary.

§
Posted: 2024-10-14
Edited: 2024-10-14

About 3% of user scripts on the site do not start with exactly // ==UserScript==. The things these scripts start with include:

In the absence of a standard I'm leery of having a validation for this, especially since TM is OK with it and TM is the most popular. Maybe one of those skippable warnings...

woxxomMod
§
Posted: 2024-10-14

Violentmonkey will allow malformed userscript metadata with a warning: https://github.com/violentmonkey/violentmonkey/commit/2dd34c3f729766ed49de190b6876fc43b3dfa84f

By ChatGPT,

function validateUserScriptMetaBlock(script) {
    // Regular expression to match the full metablock
    const metablockPattern = /^\/\/\s*==UserScript==\n([\s\S]*?)\n\/\/\s*==\/UserScript==/;

    // Ensure no content appears before the metablock
    const startsWithMetablock = metablockPattern.test(script);

    // Extract the metablock if it exists, to validate contents inside
    if (startsWithMetablock) {
        const match = script.match(metablockPattern);
        const metablockContent = match[1];

        // Validate common userscript metadata (@name, @version, etc.)
        const requiredFields = ['@name', '@version'];
        for (const field of requiredFields) {
            const fieldPattern = new RegExp(`^\\s*//\\s*${field}\\s+`, 'm');
            if (!fieldPattern.test(metablockContent)) {
                return false; // Missing required metadata field
            }
        }
        return true;
    }

    return false;
}

// Example usage:
const userScript = `// ==UserScript==
// @name Example Script
// @version 1.0.0
// @description This is an example userscript
// ==/UserScript==

console.log('Hello, world!');
`;

if (validateUserScriptMetaBlock(userScript)) {
    console.log("Valid UserScript meta block!");
} else {
    console.log("Invalid UserScript meta block!");
}


def validate_user_script_meta_block(script)
  # Regular expression to match the full metablock
  metablock_pattern = /^\/\/\s*==UserScript==\n([\s\S]*?)\n\/\/\s*==\/UserScript==/m

  # Check if the script starts with the metablock
  if script =~ metablock_pattern
    metablock_content = script.match(metablock_pattern)[1]

    # Validate the presence of common userscript metadata
    required_fields = ['@name', '@version']
    required_fields.each do |field|
      field_pattern = /^\/\/\s*#{field}\s+/
      return false unless metablock_content =~ field_pattern
    end
    return true
  end

  return false
end

# Example usage:
user_script = <<-SCRIPT
// ==UserScript==
// @name Example Script
// @version 1.0.0
// @description This is an example userscript
// ==/UserScript==

puts 'Hello, world!'
SCRIPT

if validate_user_script_meta_block(user_script)
  puts "Valid UserScript meta block!"
else
  puts "Invalid UserScript meta block!"
end

woxxomMod
§
Posted: 2024-10-15

ChatGPT can't help here because the task is something where one should think e.g. it anchors the pattern via ^ and uses \s which includes \n so it won't be a single line. You can see an example of how to detect validity in the commit I've linked above: it captures invalid input in (.*?)

§
Posted: 2024-10-15

I've added a skippable warning for any user.js that doesn't start with // ==UserScript==.

Post reply

Sign in to post a reply.