I just spent 6 hours of debugging some code, just to find out I had to delete a line in a .gitkeep file:

I’m developing a Grav skeleton, which is a kind of template for Grav CMS to easily create sites with it. Such skeletons can include themes and plugins, which can be used to enhance its features and make individual sites.

Now I had this error that the sitemap.xml (used to tell search engines which pages should be indexed and where to find them) threw an error because the XML declaration wasn’t on the first line as it should, but on the 2nd line. It came out that every page had this empty line, no matter if html, json or xml.
To find the bug causing this, I first disabled all plugins and enabled them step by step to find out which one produces said bug. It was the shortcode-core plugin, which can be used to style text with more than just markdown. Since this plugin isn’t related in any way to the sitemap plugin, I searched for other possible error sources.
After some playing around, I found out that when I remove a theme, the bug simply disappears. With that info, it had to be a problem with said theme. Since themes can include custom shortcodes and the shortcode plugin did make some “noises”, I started investigating a bit more with that. While trying to find the bug, I accidentally deleted the shortcode folder, which had only a .gitkeep file in it. This file was necessary that the folder persist with git versioning because if there was no such directory, the plugin would output an error message. I then recreated the folder manually and the error was still gone. Even after recreating the .gitkeep file, there was no empty line in the output.
After trying to find the bug, I checked git to see which edit made the bug resolve. And there was it: the .gitkeep file I recreated had some changes? But I didn’t make any changes to the file except for recreating it. Wrong. The file originally had 2 empty lines, probably accidentally. And by recreating the file, it only had one line which resolved the bug.

It came out that somehow the shortcode plugin tried to get shortcodes from this file and likely added the 2 empty lines to the output. And an empty line before the start of the XML declaration causes the XML parser to output an error. Deleting the 2nd empty line from the .gitkeep file removes the empty line from the output and the error is gone. Bug fixed.


And I spent 6 hours today with the help of a kind stranger in a discord channel who was a bit like a 2nd brain to me. It really helped having someone who hasn’t worked on this skeleton and could see some bugs you don’t see because you’re too familiar with it (“Betriebsblind” in German).

  • dohpaz42@lemmy.world
    link
    fedilink
    English
    arrow-up
    6
    ·
    1 hour ago

    You found an important bug in your short code plugin. Removing the line from .gitkeep is not actually the solution; it was a symptom of a much bigger and more dangerous problem: you are inadvertently including and parsing a file that is not intended to be a short code.

    You, or a crafty hacker, might one day create a file with code in it that should not be parsed as a short code, and not realize that it’s being done. You’re lucky that you’re the one who discovered this and not somebody else.

    The solution is the only parse the files that you need to parse. This means ignoring hidden files that begin with a dot. You might also think about creating a default ignore list for any other non-shortcode file that could exist.

    • chraebsli@programming.devOP
      link
      fedilink
      arrow-up
      1
      ·
      1 hour ago

      Every shortcode is a PHP class and looks like this:

      <?php
      
      namespace Grav\Plugin\Shortcodes;
      
      use Grav\Common\Utils;
      use Thunder\Shortcode\Shortcode\ShortcodeInterface;
      
      class ClearBothShortcode extends Shortcode
      {
          public function init()
          {
              $this->shortcode->getHandlers()->add('clearboth', function (ShortcodeInterface $sc) {
      
                  // Get shortcode content and parameters
                  $str = $sc->getContent();
      
                  $output = '<div style="clear: both;"></div>';
      
                  return $output;
      
              });
          }
      }
      

      with that, it should be possible to only call these classes.