Package: libjavascript-perl Version: 1.08-1+b1 Severity: important User: debian-...@lists.debian.org UserTags: debian-edu
For etch, I wrote a script to extract the proxy setting from a WPAD script to be able to update /etc/environment at boot. When trying to use it with Debian Edu based on Lenny, the script fail and perl segfaults. I hope this bug can be fixed in Lenny, because we are working on finalizing the Lenny based Debian Edu and it would be great if we could get this working using Lenny packages, as we are moving to using a WPAD file to specify the proxy setting. I had to disable the setting of the error handler, as this function seem to be missing in the Lenny package. This is how my script fails: % ../olpsvn/src/olp-packages/wpad-extract debug S[http]: Unable to find proxy settings for http http_proxy= Segmentation fault % This is the last part of the valgrind output from the crash. ==4227== Invalid read of size 4 ==4227== at 0x4887A44: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x48880BE: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x4888284: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x484B247: JS_GetProperty (in /usr/lib/libmozjs.so.1d) ==4227== by 0x40363B1: XS_JavaScript__Context_jsc_call (in /usr/lib/perl5/auto/JavaScript/JavaScript.so) ==4227== by 0x80B32D1: Perl_pp_entersub (in /usr/bin/perl) ==4227== by 0x80B1878: Perl_runops_standard (in /usr/bin/perl) ==4227== by 0x80AC69F: perl_run (in /usr/bin/perl) ==4227== by 0x8063DDC: main (in /usr/bin/perl) ==4227== Address 0x4bafff6 is 4,086 bytes inside a block of size 4,096 free'd ==4227== at 0x4022B8A: free (vg_replace_malloc.c:323) ==4227== by 0x4871A7C: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x484D898: JS_GC (in /usr/lib/libmozjs.so.1d) ==4227== by 0x4036E67: XS_JavaScript__Context_jsc_eval (in /usr/lib/perl5/auto/JavaScript/JavaScript.so) ==4227== by 0x80B32D1: Perl_pp_entersub (in /usr/bin/perl) ==4227== by 0x80B1878: Perl_runops_standard (in /usr/bin/perl) ==4227== by 0x80AC69F: perl_run (in /usr/bin/perl) ==4227== by 0x8063DDC: main (in /usr/bin/perl) ==4227== ==4227== Jump to the invalid address stated on the next line ==4227== at 0x0: ??? ==4227== by 0x48880BE: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x4888284: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x484B247: JS_GetProperty (in /usr/lib/libmozjs.so.1d) ==4227== by 0x40363B1: XS_JavaScript__Context_jsc_call (in /usr/lib/perl5/auto/JavaScript/JavaScript.so) ==4227== by 0x80B32D1: Perl_pp_entersub (in /usr/bin/perl) ==4227== by 0x80B1878: Perl_runops_standard (in /usr/bin/perl) ==4227== by 0x80AC69F: perl_run (in /usr/bin/perl) ==4227== by 0x8063DDC: main (in /usr/bin/perl) ==4227== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==4227== ==4227== Process terminating with default action of signal 11 (SIGSEGV) ==4227== Bad permissions for mapped region at address 0x0 ==4227== at 0x0: ??? ==4227== by 0x48880BE: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x4888284: (within /usr/lib/libmozjs.so.1d) ==4227== by 0x484B247: JS_GetProperty (in /usr/lib/libmozjs.so.1d) ==4227== by 0x40363B1: XS_JavaScript__Context_jsc_call (in /usr/lib/perl5/auto/JavaScript/JavaScript.so) ==4227== by 0x80B32D1: Perl_pp_entersub (in /usr/bin/perl) ==4227== by 0x80B1878: Perl_runops_standard (in /usr/bin/perl) ==4227== by 0x80AC69F: perl_run (in /usr/bin/perl) ==4227== by 0x8063DDC: main (in /usr/bin/perl) ==4227== ==4227== ERROR SUMMARY: 14 errors from 10 contexts (suppressed: 61 from 2) ==4227== malloc/free: in use at exit: 1,653,923 bytes in 31,709 blocks. ==4227== malloc/free: 58,682 allocs, 26,973 frees, 4,281,409 bytes allocated. ==4227== For counts of detected errors, rerun with: -v ==4227== searching for pointers to 31,709 not-freed blocks. ==4227== checked 1,816,188 bytes. ==4227== ==4227== LEAK SUMMARY: ==4227== definitely lost: 5,352 bytes in 124 blocks. ==4227== possibly lost: 15,319 bytes in 54 blocks. ==4227== still reachable: 1,633,252 bytes in 31,531 blocks. ==4227== suppressed: 0 bytes in 0 blocks. ==4227== Rerun with --leak-check=full to see details of leaked memory. Segmentation fault The script is attached. -- System Information: Debian Release: 5.0.3 APT prefers stable APT policy: (500, 'stable') Architecture: i386 (i686) Kernel: Linux 2.6.26-2-686 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages libjavascript-perl depends on: ii libc6 2.7-18 GNU C Library: Shared libraries ii libmozjs1d 1.9.0.16-1 The Mozilla SpiderMonkey JavaScrip ii perl 5.10.0-19lenny2 Larry Wall's Practical Extraction ii perl-base [perlapi-5.10. 5.10.0-19lenny2 minimal Perl system libjavascript-perl recommends no packages. libjavascript-perl suggests no packages. -- no debconf information
#!/usr/bin/perl # # Process WPAD file to extract proxy settings # http://docs.huihoo.com/gnu_linux/squid/html/x1187.html # # Author: Petter Reinholdtsen # License: GNU General Public License v2 or later use strict; use warnings; use JavaScript; # From the libjavascript-perl debian package use LWP::Simple; # From the libwww-perl debian package my $debug = 1; sub get_wpad_script_test { # Example wpad script for debugging and testing return <<EOF; function FindProxyForURL(url, host) { if (!isResolvable(host) || isPlainHostName(host) || dnsDomainIs(host, ".intern")) return "DIRECT"; else return "PROXY webcache:3128; DIRECT"; } EOF } sub get_wpad_script { my $wpadurl = shift; my $wpadbody; if ($wpadurl =~ m/^http[s]?:/) { print "Fetching URL $wpadurl\n" if $debug; $wpadbody = LWP::Simple::get($wpadurl); die "Could not get url $wpadurl!" unless defined $wpadbody; } elsif ($wpadurl =~ m/^file:\/\/(\/?.+)$/) { open(FILE, "<", $1) || die "Unable to read $1"; $wpadbody = ""; while (<FILE>) { $wpadbody .= $_; } close(FILE); } else { die "Unhandled URL type $wpadurl!"; } return $wpadbody; } sub usage { my $retval = shift; print <<EOF; Usage: $0 [URL-to-wpad-file] EOF exit $retval; } my $wpadurl = $ARGV[0]; shift; usage(1) unless $wpadurl; my $wpadbody; unless ("debug" eq $wpadurl) { $wpadbody = get_wpad_script($wpadurl); } else { $wpadbody = get_wpad_script_test(); } my @types = @ARGV; @types = ("http", "ftp") unless @types; for my $type (@types) { my $proxy = get_proxy($type, $wpadbody) || ""; print "${type}_proxy=$proxy\n"; } exit 0; sub get_proxy { my ($type, $wpadbody) = @_; my $rt = new JavaScript::Runtime(); my $cx = $rt->create_context(); if (0) { # XXX set_error_handler() seem to be missing from # libjavascript-perl version 1.08-1+b1 $cx->set_error_handler(sub { my ($message, $lineno, $linebuff) = @_; die "Error at line: $lineno\n". "Message is: $message\n". "Source is: $linebuff\n"; }); } # Load proxy autoconfig helper functions $cx->eval(get_pac_functions()); # Load the WPAD script $cx->eval($wpadbody); my ($url, $host); if ("http" eq $type) { $url = "http://www.debian.org/"; $host = "www.debian.org"; } elsif ("ftp" eq $type) { $url = "ftp://ftp.debian.org/"; $host = "ftp.debian.org"; } else { die "Unhandled proxy type requested"; } my $setting = $cx->call("FindProxyForURL", $url, $host) || ""; print "S[$type]: $setting\n" if $debug; if ($setting) { for my $entry (split(/; */, $setting)) { print " E: $entry\n" if $debug; return undef if $entry eq "DIRECT"; return "http://$1" if $entry =~ /^PROXY (.+)$/; # Not handling SOCKS proxy settings } } else { print STDERR "Unable to find proxy settings for $type\n"; } return undef; } # Make common functions available. Copied from # http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsProxyAutoConfig.js sub get_pac_functions { my $pacUtils = <<'EOF'; function dnsDomainIs(host, domain) { return (host.length >= domain.length && host.substring(host.length - domain.length) == domain); } function dnsDomainLevels(host) { return host.split('.').length-1; } function convert_addr(ipchars) { var bytes = ipchars.split('.'); var result = ((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) | ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff); return result; } function isInNet(ipaddr, pattern, maskstr) { var test = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/(ipaddr); if (test == null) { ipaddr = dnsResolve(ipaddr); if (ipaddr == null) return false; } else if (test[1] > 255 || test[2] > 255 || test[3] > 255 || test[4] > 255) { return false; // not an IP address } var host = convert_addr(ipaddr); var pat = convert_addr(pattern); var mask = convert_addr(maskstr); return ((host & mask) == (pat & mask)); } function isPlainHostName(host) { return (host.search('\\.') == -1); } function isResolvable(host) { var ip = dnsResolve(host); return (ip != null); } function localHostOrDomainIs(host, hostdom) { return (host == hostdom) || (hostdom.lastIndexOf(host + '.', 0) == 0); } function shExpMatch(url, pattern) { pattern = pattern.replace(/\./g, '\\.'); pattern = pattern.replace(/\*/g, '.*'); pattern = pattern.replace(/\?/g, '.'); var newRe = new RegExp('^'+pattern+'$'); return newRe.test(url); } var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6}; var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11}; function weekdayRange() { function getDay(weekday) { if (weekday in wdays) { return wdays[weekday]; } return -1; } var date = new Date(); var argc = arguments.length; var wday; if (argc < 1) return false; if (arguments[argc - 1] == 'GMT') { argc--; wday = date.getUTCDay(); } else { wday = date.getDay(); } var wd1 = getDay(arguments[0]); var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1; return (wd1 == -1 || wd2 == -1) ? false : (wd1 <= wday && wday <= wd2); } function dateRange() { function getMonth(name) { if (name in months) { return months[name]; } return -1; } var date = new Date(); var argc = arguments.length; if (argc < 1) { return false; } var isGMT = (arguments[argc - 1] == 'GMT'); if (isGMT) { argc--; } // function will work even without explict handling of this case if (argc == 1) { var tmp = parseInt(arguments[0]); if (isNaN(tmp)) { return ((isGMT ? date.getUTCMonth() : date.getMonth()) == getMonth(arguments[0])); } else if (tmp < 32) { return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp); } else { return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) == tmp); } } var year = date.getFullYear(); var date1, date2; date1 = new Date(year, 0, 1, 0, 0, 0); date2 = new Date(year, 11, 31, 23, 59, 59); var adjustMonth = false; for (var i = 0; i < (argc >> 1); i++) { var tmp = parseInt(arguments[i]); if (isNaN(tmp)) { var mon = getMonth(arguments[i]); date1.setMonth(mon); } else if (tmp < 32) { adjustMonth = (argc <= 2); date1.setDate(tmp); } else { date1.setFullYear(tmp); } } for (var i = (argc >> 1); i < argc; i++) { var tmp = parseInt(arguments[i]); if (isNaN(tmp)) { var mon = getMonth(arguments[i]); date2.setMonth(mon); } else if (tmp < 32) { date2.setDate(tmp); } else { date2.setFullYear(tmp); } } if (adjustMonth) { date1.setMonth(date.getMonth()); date2.setMonth(date.getMonth()); } if (isGMT) { var tmp = date; tmp.setFullYear(date.getUTCFullYear()); tmp.setMonth(date.getUTCMonth()); tmp.setDate(date.getUTCDate()); tmp.setHours(date.getUTCHours()); tmp.setMinutes(date.getUTCMinutes()); tmp.setSeconds(date.getUTCSeconds()); date = tmp; } return ((date1 <= date) && (date <= date2)); } function timeRange() { var argc = arguments.length; var date = new Date(); var isGMT= false; if (argc < 1) { return false; } if (arguments[argc - 1] == 'GMT') { isGMT = true; argc--; } var hour = isGMT ? date.getUTCHours() : date.getHours(); var date1, date2; date1 = new Date(); date2 = new Date(); if (argc == 1) { return (hour == arguments[0]); } else if (argc == 2) { return ((arguments[0] <= hour) && (hour <= arguments[1])); } else { switch (argc) { case 6: date1.setSeconds(arguments[2]); date2.setSeconds(arguments[5]); case 4: var middle = argc >> 1; date1.setHours(arguments[0]); date1.setMinutes(arguments[1]); date2.setHours(arguments[middle]); date2.setMinutes(arguments[middle + 1]); if (middle == 2) { date2.setSeconds(59); } break; default: throw 'timeRange: bad number of arguments' } } if (isGMT) { date.setFullYear(date.getUTCFullYear()); date.setMonth(date.getUTCMonth()); date.setDate(date.getUTCDate()); date.setHours(date.getUTCHours()); date.setMinutes(date.getUTCMinutes()); date.setSeconds(date.getUTCSeconds()); } return ((date1 <= date) && (date <= date2)); } EOF return $pacUtils; }