comparison mercurial/chgserver.py @ 35170:c9740b69b9b7 stable

dispatch: add HGPLAIN=+strictflags to restrict early parsing of global options If this feature is enabled, early options are parsed using the global options table. As the parser stops processing options when non/unknown option is encountered, it won't mistakenly take an option value as a new early option. Still "--" can be injected to terminate the parsing (e.g. "hg -R -- log"), I think it's unlikely to lead to an RCE. To minimize a risk of this change, new fancyopts.earlygetopt() path is enabled only when +strictflags is set. Also the strict parser doesn't support '--repo', a short for '--repository' yet. This limitation will be removed later. As this feature is backward incompatible, I decided to add a new opt-in mechanism to HGPLAIN. I'm not pretty sure if this is the right choice, but I'm thinking of adding +feature/-feature syntax to HGPLAIN. Alternatively, we could add a new environment variable. Any bikeshedding is welcome. Note that HGPLAIN=+strictflags doesn't work correctly in chg session since command arguments are pre-processed in C. This wouldn't be easily fixed.
author Yuya Nishihara <yuya@tcha.org>
date Thu, 23 Nov 2017 22:17:03 +0900
parents d3d35a55e03b
children 6e6d0a5b88e6
comparison
equal deleted inserted replaced
35169:898c6f812a51 35170:c9740b69b9b7
218 setattr(newui, a, getattr(srcui, a)) 218 setattr(newui, a, getattr(srcui, a))
219 if util.safehasattr(srcui, '_csystem'): 219 if util.safehasattr(srcui, '_csystem'):
220 newui._csystem = srcui._csystem 220 newui._csystem = srcui._csystem
221 221
222 # command line args 222 # command line args
223 args = args[:] 223 options = {}
224 dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args)) 224 if srcui.plain('strictflags'):
225 options.update(dispatch._earlyparseopts(args))
226 else:
227 args = args[:]
228 options['config'] = dispatch._earlygetopt(['--config'], args)
229 cwds = dispatch._earlygetopt(['--cwd'], args)
230 options['cwd'] = cwds and cwds[-1] or ''
231 rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args)
232 options['repository'] = rpath and rpath[-1] or ''
233 dispatch._parseconfig(newui, options['config'])
225 234
226 # stolen from tortoisehg.util.copydynamicconfig() 235 # stolen from tortoisehg.util.copydynamicconfig()
227 for section, name, value in srcui.walkconfig(): 236 for section, name, value in srcui.walkconfig():
228 source = srcui.configsource(section, name) 237 source = srcui.configsource(section, name)
229 if ':' in source or source == '--config' or source.startswith('$'): 238 if ':' in source or source == '--config' or source.startswith('$'):
230 # path:line or command line, or environ 239 # path:line or command line, or environ
231 continue 240 continue
232 newui.setconfig(section, name, value, source) 241 newui.setconfig(section, name, value, source)
233 242
234 # load wd and repo config, copied from dispatch.py 243 # load wd and repo config, copied from dispatch.py
235 cwds = dispatch._earlygetopt(['--cwd'], args) 244 cwd = options['cwd']
236 cwd = cwds and os.path.realpath(cwds[-1]) or None 245 cwd = cwd and os.path.realpath(cwd) or None
237 rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args) 246 rpath = options['repository']
238 rpath = rpath and rpath[-1] or ''
239 path, newlui = dispatch._getlocal(newui, rpath, wd=cwd) 247 path, newlui = dispatch._getlocal(newui, rpath, wd=cwd)
240 248
241 return (newui, newlui) 249 return (newui, newlui)
242 250
243 class channeledsystem(object): 251 class channeledsystem(object):