159 if throw: |
159 if throw: |
160 raise error.HookAbort(_('%s hook %s') % (name, desc)) |
160 raise error.HookAbort(_('%s hook %s') % (name, desc)) |
161 ui.warn(_('warning: %s hook %s\n') % (name, desc)) |
161 ui.warn(_('warning: %s hook %s\n') % (name, desc)) |
162 return r |
162 return r |
163 |
163 |
|
164 # represent an untrusted hook command |
|
165 _fromuntrusted = object() |
|
166 |
164 def _allhooks(ui): |
167 def _allhooks(ui): |
165 """return a list of (hook-id, cmd) pairs sorted by priority""" |
168 """return a list of (hook-id, cmd) pairs sorted by priority""" |
166 hooks = _hookitems(ui) |
169 hooks = _hookitems(ui) |
|
170 # Be careful in this section, propagating the real commands from untrusted |
|
171 # sources would create a security vulnerability, make sure anything altered |
|
172 # in that section uses "_fromuntrusted" as its command. |
|
173 untrustedhooks = _hookitems(ui, _untrusted=True) |
|
174 for name, value in untrustedhooks.items(): |
|
175 trustedvalue = hooks.get(name, (None, None, name, _fromuntrusted)) |
|
176 if value != trustedvalue: |
|
177 (lp, lo, lk, lv) = trustedvalue |
|
178 hooks[name] = (lp, lo, lk, _fromuntrusted) |
|
179 # (end of the security sensitive section) |
167 return [(k, v) for p, o, k, v in sorted(hooks.values())] |
180 return [(k, v) for p, o, k, v in sorted(hooks.values())] |
168 |
181 |
169 def _hookitems(ui): |
182 def _hookitems(ui, _untrusted=False): |
170 """return all hooks items ready to be sorted""" |
183 """return all hooks items ready to be sorted""" |
171 hooks = {} |
184 hooks = {} |
172 for name, cmd in ui.configitems('hooks'): |
185 for name, cmd in ui.configitems('hooks', untrusted=_untrusted): |
173 if not name.startswith('priority'): |
186 if not name.startswith('priority'): |
174 priority = ui.configint('hooks', 'priority.%s' % name, 0) |
187 priority = ui.configint('hooks', 'priority.%s' % name, 0) |
175 hooks[name] = (-priority, len(hooks), name, cmd) |
188 hooks[name] = (-priority, len(hooks), name, cmd) |
176 return hooks |
189 return hooks |
177 |
190 |
212 os.dup2(stderrno, stdoutno) |
225 os.dup2(stderrno, stdoutno) |
213 except (OSError, AttributeError): |
226 except (OSError, AttributeError): |
214 # files seem to be bogus, give up on redirecting (WSGI, etc) |
227 # files seem to be bogus, give up on redirecting (WSGI, etc) |
215 pass |
228 pass |
216 |
229 |
217 if callable(cmd): |
230 if cmd is _fromuntrusted: |
|
231 if throw: |
|
232 raise error.HookAbort( |
|
233 _('untrusted hook %s not executed') % name, |
|
234 hint = _("see 'hg help config.trusted'")) |
|
235 ui.warn(_('warning: untrusted hook %s not executed\n') % name) |
|
236 r = 1 |
|
237 raised = False |
|
238 elif callable(cmd): |
218 r, raised = _pythonhook(ui, repo, name, hname, cmd, args, throw) |
239 r, raised = _pythonhook(ui, repo, name, hname, cmd, args, throw) |
219 elif cmd.startswith('python:'): |
240 elif cmd.startswith('python:'): |
220 if cmd.count(':') >= 2: |
241 if cmd.count(':') >= 2: |
221 path, cmd = cmd[7:].rsplit(':', 1) |
242 path, cmd = cmd[7:].rsplit(':', 1) |
222 path = util.expandpath(path) |
243 path = util.expandpath(path) |