Closed egberts closed 5 years ago
To recreate the backtrace, web-security-topics-2018.md
file contains:
Title: Web Security Advanced Topic 2018
Date: 2018 Nov 22
Tag: http, security, exploit
Category: research
Summary: Advanced exploits of web security in 2018
# Advanced Wed Security Topic 2018
https://blog.georgovassilis.com/2016/04/16/advanced-web-security-topics/
Then execute
MYDIR="/home/johnd/websites/example.com"
PELICAN_BIN="/usr/local/bin/pelican"
ipython --pdb \
--pprint \
-c "pdb 1" \
-c "run $PELICAN_BIN \
-o $MYDIR/output \
-s $MYDIR/pelicanconf.py \
-v -v -v -v -D \
$MYDIR/content/"
ipython traceback is:
CRITICAL: AttributeError: 'str' object has no attribute 'slug'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/usr/local/bin/pelican in <module>()
9 sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
10 sys.exit(
---> 11 load_entry_point('pelican==4.0.0', 'console_scripts', 'pelican')()
12 )
~/work/websites/pelican/pelican/__init__.py in main()
621 logger.warning('Empty theme folder. Using `basic` theme.')
622
--> 623 pelican.run()
624
625 except Exception as e:
~/work/websites/pelican/pelican/__init__.py in run(self)
176 for p in generators:
177 if hasattr(p, 'generate_context'):
--> 178 p.generate_context()
179
180 for p in generators:
~/work/websites/pelican/pelican/generators.py in generate_context(self)
631 continue
632
--> 633 if not article.is_valid():
634 self._add_failed_source_path(f)
635 continue
~/work/websites/pelican/pelican/contents.py in is_valid(self)
200 # Use all() to not short circuit and get results of all validations
201 return all([self._has_valid_mandatory_properties(),
--> 202 self._has_valid_save_as(),
203 self._has_valid_status()])
204
~/work/websites/pelican/pelican/contents.py in _has_valid_save_as(self)
172
173 try:
--> 174 sanitised_join(output_path, self.save_as)
175 except RuntimeError: # outside output_dir
176 logger.error(
~/work/websites/pelican/pelican/contents.py in save_as(self)
432 @property
433 def save_as(self):
--> 434 return self.get_url_setting('save_as')
435
436 def _get_template(self):
~/work/websites/pelican/pelican/contents.py in get_url_setting(self, key)
229 return getattr(self, 'override_' + key)
230 key = key if self.in_default_lang else 'lang_%s' % key
--> 231 return self._expand_settings(key)
232
233 def _link_replacer(self, siteurl, m):
~/work/websites/pelican/pelican/contents.py in _expand_settings(self, key)
524 def _expand_settings(self, key):
525 klass = 'draft' if self.status == 'draft' else 'article'
--> 526 return super(Article, self)._expand_settings(key, klass)
527
528
~/work/websites/pelican/pelican/contents.py in _expand_settings(self, key, klass)
223 klass = self.__class__.__name__
224 fq_key = ('%s_%s' % (klass, key)).upper()
--> 225 return self.settings[fq_key].format(**self.url_format)
226
227 def get_url_setting(self, key):
~/work/websites/pelican/pelican/contents.py in url_format(self)
214 'date': getattr(self, 'date', SafeDatetime.now()),
215 'author': self.author.slug if hasattr(self, 'author') else '',
--> 216 'tag': self.tag.slug if hasattr(self, 'tag') else '',
217 'category': self.category.slug if hasattr(self, 'category') else ''
218 })
AttributeError: 'str' object has no attribute 'slug'
> /home/steve/work/websites/pelican/pelican/contents.py(216)url_format()
214 'date': getattr(self, 'date', SafeDatetime.now()),
215 'author': self.author.slug if hasattr(self, 'author') else '',
--> 216 'tag': self.tag.slug if hasattr(self, 'tag') else '',
217 'category': self.category.slug if hasattr(self, 'category') else ''
218 })
ipdb> quit
Pelican: 3.7.1-r1 (latest git repo 033d6ac4d676b4c376a21bb5d5ecafcba2f221cb) Debian 9
Examining the self.tag
shows that the attribute slug
is missing.
ipdb> l
211 'path': path_to_url(path),
212 'slug': getattr(self, 'slug', ''),
213 'lang': getattr(self, 'lang', 'en'),
214 'date': getattr(self, 'date', SafeDatetime.now()),
215 'author': self.author.slug if hasattr(self, 'author') else '',
--> 216 'tag': self.tag.slug if hasattr(self, 'tag') else '',
217 'category': self.category.slug if hasattr(self, 'category') else ''
218 })
219 return metadata
220
221 def _expand_settings(self, key, klass=None):
ipdb> pp self
<pelican.contents.Article object at 0x7f15cd6ec1d0>
ipdb> pp self.tag
'http, security, exploit'
ipdb> pp dir(self.tag)
[ <removed double-underscore crufts>,
'capitalize',
'casefold',
'center',
'count',
'encode',
'endswith',
'expandtabs',
'find',
'format',
'format_map',
'index',
'isalnum',
'isalpha',
'isdecimal',
'isdigit',
'isidentifier',
'islower',
'isnumeric',
'isprintable',
'isspace',
'istitle',
'isupper',
'join',
'ljust',
'lower',
'lstrip',
'maketrans',
'partition',
'replace',
'rfind',
'rindex',
'rjust',
'rpartition',
'rsplit',
'rstrip',
'split',
'splitlines',
'startswith',
'strip',
'swapcase',
'title',
'translate',
'upper',
'zfill']
Hi'ya @egberts, we meet again.
This error looks like it's a little harder to fix. From what I reproduced, it looks like when we use the Tag:
attribute in the content file, it overrides the list of Tag
objects passed when the Content
object is created.
An option could be implementing a list of protected attributes from being overridden in the Content
object.
The simple fix I'm proposing uses a try/except
block in Content.is_valid
to emit a error, then return False
to tell the Generator
to record it as failed and skip it. The error will look like this:
ERROR: "articles/testing.md" is not structured properly. Check http://docs.getpelican.com/en/stable/content.html for more information.
I know this doesn't explicitly tell us what the problem is, (it also masks other problems in the code if there are any) but it gets us on the right track when debugging.
If you (or any of the veterans here) have any more good ideas let me know. Searching the closed issues I managed to find #2177.
I think @bryanbrattlof is right that this is caused because the tag
metadata is set to a string in your article, whereas the code assumes it is a Tag
object.
The real question however is why the Content.url_format
method tries to convert .tag
to .tag.slug
in the first place. No .tag
Tag attribute is set anywhere for Articles (let alone other Content). They have a .tags
attribute, which is a list of Tags. Using {tag}
in the article path makes no sense. This was introduced as part of https://github.com/getpelican/pelican/pull/1926, but without motivation, so I'm minded to just remove it again.
Fix for this has been included in Pelican 4.0.1, which I just released. Enjoy! :rocket:
Using an
articles/example.md
file, when mistyping in the metadataTag:
(instead of `Tags:) resulted in a cryptic error message as shown:Probably should say something like:
Crash dump