Skip to content
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

[WIP] Undefined variable value yields '.' as node and may cause removing all files in tree. #3905

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
"Multiple ways to build the same target were specified for:". Now mingw will disable
creating the symlinks (and adding version string to ) dlls. It sets SHLIBNOVERSIONSYMLINKS,
IMPLIBNOVERSIONSYMLINKS and LDMODULENOVERSIONSYMLINKS to True.
- Fix Issue #2801 - Handle calling Clean('$XYZ','$ABC') when either env['XYZ'] or env['ABC']
is undefined as that would yield either argument as '.'. This will lead to cleaning the wrong
(or all) files potentially when you request the wrong (or any target).


From Daniel Moody:
- Update CacheDir to use uuid for tmpfile uniqueness instead of pid.
Expand Down
20 changes: 17 additions & 3 deletions SCons/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@

import copy
import os
import sys
import re
import shlex
import sys
from collections import UserDict

import SCons.Action
import SCons.Builder
import SCons.Debug
from SCons.Debug import logInstanceCreation
import SCons.Defaults
from SCons.Errors import UserError, BuildError
import SCons.Memoize
import SCons.Node
import SCons.Node.Alias
Expand All @@ -54,6 +52,8 @@
import SCons.Subst
import SCons.Tool
import SCons.Warnings
from SCons.Debug import logInstanceCreation
from SCons.Errors import UserError, BuildError
from SCons.Util import (
AppendPath,
CLVar,
Expand All @@ -74,6 +74,7 @@
uniquer_hashables,
)


class _Null:
pass

Expand Down Expand Up @@ -2000,6 +2001,19 @@ def CacheDir(self, path):

def Clean(self, targets, files):
global CleanTargets

# Check for anything which evaluates to empty string, which would yield cleaning '.'
targets_strings = [(t, self.subst(t)) for t in flatten(targets) if is_String(t) and ('$' in t or t == '')]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be simpler to just let tlist and flist expand and check in them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I don't think using tlist or flist would allow proper checking for accidental '.' from undefined var.
Also you wouldn't be able to give as much information about what was wrong.

files_strings = [(t, self.subst(t)) for t in flatten(files) if is_String(t) and ('$' in t or t == '')]
if any([s == '' for t, s in targets_strings]):
raise UserError(
"Targets specified to Clean() include on which evaluates to an empty string: [%s]" % ",".join(
bdbaddog marked this conversation as resolved.
Show resolved Hide resolved
["%s='%s'" % (str(t), s) for (t, s) in targets_strings]))
if any([s == '' for t, s in files_strings]):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that one stanza checks targets_strings and the other files_strings, but this still reads quite duplicative... any way to combine?

raise UserError(
"Targets specified to Clean() include on which evaluates to an empty string: [%s]" % ",".join(
bdbaddog marked this conversation as resolved.
Show resolved Hide resolved
["%s='%s'" % (str(t), s) for (t, s) in files_strings]))

tlist = self.arg2nodes(targets, self.fs.Entry)
flist = self.arg2nodes(files, self.fs.Entry)
for t in tlist:
Expand Down