-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix security issue in __version__ extra calculation (fix #328) #330
Conversation
# Sanitize path of ref file | ||
# get full path to ref file | ||
ref_file_path = os.path.abspath(os.path.join(gitdir, ref_file)) | ||
# check that we are in git folder (by stripping the git folder from the ref file path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inconsistent capitalization of comments (PEP 8 recommends lowercase)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because the capitalized one pertains to the whole code block, whereas the lowercase pertains to only the next line (because there's not enough space to put it at the right of the code). I don't know how to make it more explicit or prettier...
__version__ += '-' + cur_hash | ||
res = None | ||
scriptdir = os.path.dirname(__file__) | ||
gitdir = os.path.abspath(scriptdir+'/../.git') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no spaces around operator
else: | ||
res = res[:8] | ||
# Append to version string | ||
if res: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is not None
can be more explicit
Thanks @CrazyPython, I fixed what you spotted :) |
(Disclaimer: I haven't tested this; I only had a cursory look at the code.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An opinionated style review. This is also dearly in need of newlines, esp. between 15&16, 29&30, and 39&40.
@@ -15,18 +11,35 @@ | |||
|
|||
|
|||
# auto -extra based on commit hash (if not tagged as release) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PEP 8 dictates one less newline here
gitdir = os.path.abspath(scriptdir + '/../.git') | ||
if os.path.isdir(gitdir): | ||
# Open the HEAD file | ||
with open(os.path.join(gitdir,'HEAD'), 'r') as fh_head: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space after comma
@@ -4,7 +4,8 @@ | |||
def test_version(): | |||
""" Test version string """ | |||
from tqdm import __version__ | |||
Mmpe = re.split('[.-]', __version__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a very good variable name - CamelCase and undescriptive
|
||
if (last_release is None) or (cur_hash not in last_release): | ||
__version__ += '-' + cur_hash | ||
res = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
res
is defined here...
gitdir = os.path.abspath(scriptdir + '/../.git') | ||
if os.path.isdir(gitdir): | ||
# Open the HEAD file | ||
with open(os.path.join(gitdir,'HEAD'), 'r') as fh_head: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...but only used in this if statement. Either move it in (lazy evaluation) or move the checking operation out (imperative).
gitdir = os.path.abspath(scriptdir + '/../.git') | ||
if os.path.isdir(gitdir): | ||
# Open the HEAD file | ||
with open(os.path.join(gitdir,'HEAD'), 'r') as fh_head: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'r'
is not required, you decide if that's a good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah but better be explicit :)
|
||
if (last_release is None) or (cur_hash not in last_release): | ||
__version__ += '-' + cur_hash | ||
res = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to rename res
to result
. It's more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to extra
.
with open(os.path.join(gitdir,'HEAD'), 'r') as fh_head: | ||
res = fh_head.readline().strip() | ||
# If we are in a branch, HEAD will point to a file containing the latest commit | ||
if 'ref:' in res: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both of these branches, res
is set. Yet above, res
is set to another name. Two variables would be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand your remark, res
always aim to contain the extra = the commit hash (and if available the branch name). I changed the variable name to be more explicit. It's just that if we are in a branch, we don't get the commit hash from the HEAD file, so then it's necessary to do some more processing.
@@ -4,7 +4,8 @@ | |||
def test_version(): | |||
""" Test version string """ | |||
from tqdm import __version__ | |||
Mmpe = re.split('[.-]', __version__) | |||
Mmpe = __version__.split()[0] # remove part after space (branch name) | |||
Mmpe = re.split('[.-]', Mmpe) # split by dot and dash | |||
assert 3 <= len(Mmpe) <= 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this not the same as assert len(Mmpe) in (3, 4)
? People usually expect reversed syntax, e.g. 4 >= len(Mmpe) >= 3
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is the same but I disagree the reversed syntax is more common, since they are mathematical operators I expect the same convention as in mathematical notation (least value first).
Thanks both for your reviews and insights. I agree, we should think about
keeping this code.
Note to self:
- [x] check git repo name (tqdm)
- [x] fix CrazyPython remarks.
|
<= is waaay more common than >= in chained comparisons:
https://codesearch.debian.net/search?q=%3C%3D%5Cs%2B%5Cw%2B%5Cs%2B%3C%3D+filetype%3Apython (5363 hits)
https://codesearch.debian.net/search?q=%3E%3D%5Cs%2B%5Cw%2B%5Cs%2B%3E%3D+filetype%3Apython (78 hits)
|
Wow regex in debian repo search, I did not know about that, amazing!
2017-01-01 15:59 GMT+01:00 Jakub Wilk <notifications@github.com>:
… <= is waaay more common than >= in chained comparisons:
https://codesearch.debian.net/search?q=%3C%3D%5Cs%2B%5Cw%2B%
5Cs%2B%3C%3D+filetype%3Apython (5363 hits)
https://codesearch.debian.net/search?q=%3E%3D%5Cs%2B%5Cw%2B%
5Cs%2B%3E%3D+filetype%3Apython (78 hits)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#330 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABES3iIvpUk7CdK-itAUMx-U2J1MPPtoks5rN79hgaJpZM4LYlJv>
.
|
If I have time later, I might review some of the existing tqdm codebase, if you want me to. |
@CrazyPython yes please feel free to do so, your feedbacks are appreciated
:) But it might take you a while!
2017-01-01 21:16 GMT+01:00 CrazyPython <notifications@github.com>:
… If I have time later, I might review some of the existing tqdm codebase,
if you want me to.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#330 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABES3rSO1CJgUJxnQWv3g03Fe2972a_Jks5rOAmBgaJpZM4LYlJv>
.
|
try: | ||
map(int, Mmpe[:3]) | ||
map(int, version_parts[:3]) | ||
except: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want except ValueError:
. This catches "errors" like SystemExit
and other python internals.
extra = None | ||
# Open config file to check if we are in tqdm project | ||
with open(os.path.join(gitdir, 'config'), 'r') as fh_config: | ||
if 'tqdm' in fh_config.read(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here you're just checking if 'tqdm' is anywhere in .git/config which might not be strict enough
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandrotosi Yep I thought the same but after reading a bit about git internals, I didn't find a better way to check if we were looking at tqdm repository. Any suggestion? Maybe looking specifically for a specific entry in config file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i looks like you have to go thru several steps: read .git/HEAD, lookup the remote for that ref in .git/config, check the remote url in .git/config if that ends with '/tqdm.git' (as you have to consider forks and other possible checkout methods).
i still think there must be an easier way to do it, and i'd look at out other "big" projects (numpy, scipy, matplotlib, and the like) do as they probably want to tackle the same problem as you do
5702ac0
to
4857462
Compare
I agree that it's a bit much to go overboard with this, it was meant to be a small helper. I'm tempted to ignore coverage of the "extra" version bit. |
and add branch name in
__version__
if available.This should fix the security issue reported in #328 (thanks to @jwilk!) alias CVE-2016-10075.
TODO (but can be done later, we should merge ASAP a fix for this issue):
with unittest.mock.patch.dict(os.environ, PATH='/nonexistent')
(courtesy of @jwilk)?