Return the base temporary directory, creating it if needed. :returns: The base temporary directory.
(self)
| 143 | return p |
| 144 | |
| 145 | def getbasetemp(self) -> Path: |
| 146 | class="st">"""Return the base temporary directory, creating it if needed. |
| 147 | |
| 148 | :returns: |
| 149 | The base temporary directory. |
| 150 | class="st">""" |
| 151 | if self._basetemp is not None: |
| 152 | return self._basetemp |
| 153 | |
| 154 | if self._given_basetemp is not None: |
| 155 | basetemp = self._given_basetemp |
| 156 | if basetemp.exists(): |
| 157 | rm_rf(basetemp) |
| 158 | basetemp.mkdir(mode=0o700) |
| 159 | basetemp = basetemp.resolve() |
| 160 | else: |
| 161 | from_env = os.environ.get(class="st">"PYTEST_DEBUG_TEMPROOT") |
| 162 | temproot = Path(from_env or tempfile.gettempdir()).resolve() |
| 163 | user = get_user() or class="st">"unknown" |
| 164 | class="cm"># use a sub-directory in the temproot to speed-up |
| 165 | class="cm"># make_numbered_dir() call |
| 166 | rootdir = temproot.joinpath(fclass="st">"pytest-of-{user}") |
| 167 | try: |
| 168 | rootdir.mkdir(mode=0o700, exist_ok=True) |
| 169 | except OSError: |
| 170 | class="cm"># getuser() likely returned illegal characters for the platform, use unknown back off mechanism |
| 171 | rootdir = temproot.joinpath(class="st">"pytest-of-unknown") |
| 172 | rootdir.mkdir(mode=0o700, exist_ok=True) |
| 173 | class="cm"># Because we use exist_ok=True with a predictable name, make sure |
| 174 | class="cm"># we are the owners, to prevent any funny business (on unix, where |
| 175 | class="cm"># temproot is usually shared). |
| 176 | class="cm"># Also, to keep things private, fixup any world-readable temp |
| 177 | class="cm"># rootdirclass="st">'s permissions. Historically 0o755 was used, so we can't |
| 178 | class="cm"># just error out on this, at least for a while. |
| 179 | class="cm"># Donclass="st">'t follow symlinks, otherwise we're open to symlink-swapping |
| 180 | class="cm"># TOCTOU vulnerability. |
| 181 | class="cm"># This check makes us vulnerable to a DoS - a user can `mkdir |
| 182 | class="cm"># /tmp/pytest-of-otheruser` and then `otheruser` will fail this |
| 183 | class="cm"># check. For now we don't consider it a real problem. otheruser can |
| 184 | class="cm"># change their TMPDIR or --basetemp, and maybe give the prankster a |
| 185 | class="cm"># good scolding. |
| 186 | uid = get_user_id() |
| 187 | if uid is not None: |
| 188 | stat_follow_symlinks = ( |
| 189 | False if os.stat in os.supports_follow_symlinks else True |
| 190 | ) |
| 191 | rootdir_stat = rootdir.stat(follow_symlinks=stat_follow_symlinks) |
| 192 | if stat.S_ISLNK(rootdir_stat.st_mode): |
| 193 | raise OSError( |
| 194 | fclass="st">"The temporary directory {rootdir} is a symbolic link. " |
| 195 | class="st">"Fix this and try again." |
| 196 | ) |
| 197 | if rootdir_stat.st_uid != uid: |
| 198 | raise OSError( |
| 199 | fclass="st">"The temporary directory {rootdir} is not owned by the current user. " |
| 200 | class="st">"Fix this and try again." |
| 201 | ) |
| 202 | if (rootdir_stat.st_mode & 0o077) != 0: |