Обсуждения » Обсуждение сайта Greasy Fork

Tighten the validity check of the userscript metablock comment?

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.

JasonBarnabeМод
§
Создано: 14.10.2024
Отредактировано: 14.10.2024

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...

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

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 (.*?)

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

Ответить

Войдите, чтобы ответить.