From 68fac5f0b833cfd3432ca4dfe573bb979aa97b66 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 30 Sep 2012 00:14:59 -0400 Subject: [PATCH] Message reduction code and shell quote hardening. --- NEWS | 4 ++++ irkerhook.py | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 1a67ea1..d17cbfd 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,10 @@ 1.2 @ All segments of a message with embedded newlines are now transmitted. + Message reduction - irkerhook driops the filelist on execessively long ones. + Shell quote hardening in irkerhook.py. + + diff --git a/irkerhook.py b/irkerhook.py index 02c1efa..523eb83 100755 --- a/irkerhook.py +++ b/irkerhook.py @@ -75,6 +75,9 @@ import os, sys, commands, socket, urllib, json version = "1.1" +def shellquote(s): + return "'" + s.replace("'","'\\''") + "'" + def do(command): return commands.getstatusoutput(command)[1] @@ -126,14 +129,14 @@ class GitExtractor: elif self.revformat == 'short': self.rev = '' else: # self.revformat == 'describe' - self.rev = do("git describe %s 2>/dev/null" % self.commit) + self.rev = do("git describe %s 2>/dev/null" % shellquote(self.commit)) if not self.rev: self.rev = self.commit[:12] # Extract the meta-information for the commit - self.files = do("git diff-tree -r --name-only '"+ self.commit +"'") + self.files = do("git diff-tree -r --name-only " + shellquote(self.commit)) self.files = " ".join(self.files.strip().split("\n")[1:]) - metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%s' " + self.commit) + metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%s' " + shellquote(self.commit)) (self.author, self.logmsg) = metainfo.split("\n") # This discards the part of the author's address after @. # Might be be nice to ship the full email address, if not @@ -161,7 +164,7 @@ class SvnExtractor: self.logmsg = self.svnlook("log") self.rev = "r{0}".format(self.commit) def svnlook(self, info): - return do("svnlook {0} {1} --revision {2}".format(info, self.repository, self.commit)) + return do("svnlook {0} {1} --revision {2}".format(shellquote(info), shellquote(self.repository), shellquote(self.commit))) if __name__ == "__main__": import getopt @@ -250,7 +253,17 @@ if __name__ == "__main__": sys.stderr.write("irkerhook.py: no project name set!\n") sys.exit(1) + # Message reduction. The assumption here is that IRC can't handle + # lines more than 510 characters long. If we exceed that length, we + # try knocking out the file list, on the theory that for notification + # purposes the commit text is more important. If it's still too long + # there's nothing much can be done other than ship it expecting the IRC + # server to truncate. privmsg = template % extractor.__dict__ + if len(privmsg) > 510: + extractor.files = "" + privmsg = template % extractor.__dict__ + channel_list = extractor.channels.split(",") structure = {"to":channel_list, "privmsg":privmsg} message = json.dumps(structure) -- 2.26.2