r111829 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r111828‎ | r111829 | r111830 >
Date:14:35, 18 February 2012
Author:hartman
Status:reverted (Comments)
Tags:
Comment:
Add support to tablesorter to handle IP/CIDR notation

This fixes bug 34475
Modified paths:
  • /trunk/phase3/RELEASE-NOTES-1.20 (modified) (history)
  • /trunk/phase3/resources/jquery/jquery.tablesorter.js (modified) (history)
  • /trunk/phase3/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js (modified) (history)

Diff [purge]

Index: trunk/phase3/tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
@@ -236,6 +236,38 @@
237237 ['204.204.132.158'],
238238 ['247.240.82.209']
239239 ];
 240+var ipv4CIDR = [
 241+ // Some randomly generated fake IPs
 242+ ['45.238.27.109/36'],
 243+ ['170.38.91.162/36'],
 244+ ['247.240.82.209/36'],
 245+ ['204.204.132.158/24'],
 246+ ['170.38.91.162/24']
 247+];
 248+var ipv4CIDRSorted = [
 249+ // Sort order should go octet by octet
 250+ ['45.238.27.109/36'],
 251+ ['170.38.91.162/24'],
 252+ ['170.38.91.162/36'],
 253+ ['204.204.132.158/24'],
 254+ ['247.240.82.209/36']
 255+];
 256+var ipv4Mixed = [
 257+ // Some randomly generated fake IPs
 258+ ['45.238.27.109'],
 259+ ['170.38.91.162'],
 260+ ['247.240.82.209'],
 261+ ['204.204.132.158/24'],
 262+ ['170.38.91.162/24']
 263+];
 264+var ipv4MixedSorted = [
 265+ // Sort order should go octet by octet
 266+ ['45.238.27.109'],
 267+ ['170.38.91.162'],
 268+ ['170.38.91.162/24'],
 269+ ['204.204.132.158/24'],
 270+ ['247.240.82.209']
 271+];
240272
241273 tableTest(
242274 'Bug 17141: IPv4 address sorting',
@@ -257,7 +289,28 @@
258290 $table.find( '.headerSort:eq(0)' ).click().click();
259291 }
260292 );
 293+tableTest(
 294+ 'Bug 34475: IPv4/CIDR address sorting',
 295+ ['IP'],
 296+ ipv4CIDR,
 297+ ipv4CIDRSorted,
 298+ function( $table ) {
 299+ $table.tablesorter();
 300+ $table.find( '.headerSort:eq(0)' ).click();
 301+ }
 302+);
261303
 304+tableTest(
 305+ 'Bug 34475: Mixed IPv4 and IP/CIDR address sorting',
 306+ ['IP'],
 307+ ipv4Mixed,
 308+ ipv4MixedSorted,
 309+ function( $table ) {
 310+ $table.tablesorter();
 311+ $table.find( '.headerSort:eq(0)' ).click();
 312+ }
 313+);
 314+
262315 var umlautWords = [
263316 // Some words with Umlauts
264317 ['Günther'],
Index: trunk/phase3/RELEASE-NOTES-1.20
@@ -19,6 +19,7 @@
2020 preference for the non-default skin to look at something using the default skin.
2121 * (bug 31417) New ID mw-content-text around the actual page text, without categories,
2222 contentSub, ... The same div often also contains the class mw-content-ltr/rtl.
 23+* (bug 34475) Add support for IP/CIDR notation to tablesorter
2324
2425 === Bug fixes in 1.20 ===
2526 * (bug 30245) Use the correct way to construct a log page title.
Index: trunk/phase3/resources/jquery/jquery.tablesorter.js
@@ -484,7 +484,7 @@
485485 }
486486 ts.rgx = {
487487 IPAddress: [
488 - new RegExp( /^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/)
 488+ new RegExp( /^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}(\/\d{1,3})?$/)
489489 ],
490490 currency: [
491491 new RegExp( /^[£$€?.]/),
@@ -767,9 +767,15 @@
768768 },
769769 format: function( s ) {
770770 var a = s.split( '.' ),
771 - r = '',
772 - l = a.length;
773 - for ( var i = 0; i < l; i++ ) {
 771+ r = '';
 772+ if( a.length == 4 ) {
 773+ var cidr = a[3].split('/');
 774+ if (cidr.length > 1 ) {
 775+ a[3] = cidr[0];
 776+ a[4] = cidr[1];
 777+ } else a[4] = '000';
 778+ }
 779+ for ( var i = 0; i < a.length; i++ ) {
774780 var item = a[i];
775781 if ( item.length == 1 ) {
776782 r += '00' + item;

Follow-up revisions

RevisionCommit summaryAuthorDate
r113122rv table sorting of IP and fraction...hashar10:17, 6 March 2012

Comments

#Comment by Hashar (talk | contribs)   19:18, 18 February 2012

/36 is not a valid IPv4 mask since an IP address is 32 bits.

Instead of randomly generated IP, you need to make a list that would actually stress the code. For example making sure 100.0.0.0 is after 10.0.0.0. Or 10.0.0.1 after 10.0.0.0 but before 10.0.0.2.

How would you sort 10.0.0.0/24 vs 10.0.0.0/16. And 10.0.0.0/24 vs 10.0.0.0 ?

I guess an IP should be normalized to use a /32 mask then sort using that.

#Comment by Platonides (talk | contribs)   21:23, 18 February 2012

I'd sort 10.0.0.0/16, 10.0.0.0/24, 10.0.0.0 (from greater nets to smaller ones)

#Comment by TheDJ (talk | contribs)   12:55, 19 February 2012

I think that is a rather technical assumption. In my mind the users will care more about the IP order, and not so much about the technical meaning of the CIDR mask.

#Comment by TheDJ (talk | contribs)   13:00, 19 February 2012

Also note this is the IP sorter, supporting IP/CIDR notation, not an IP/CIDR sorter.

#Comment by Hashar (talk | contribs)   14:54, 19 February 2012

It is not reason to make false assumptions and write tests based on random content. We need obvious test cases and make sure the code does respect them. The code will sort a single IP by appending 000. Thus we could well have a sort output like: 10.0.0.0 10.0.0.0/0 10.0.0.0/32 which does not make sense since the first (10.0.0.0) is strictly the same as 10.0.0.0/32.

If we add CIDR notation support, we might as well have the sorter properly use it.

#Comment by TheDJ (talk | contribs)   22:20, 19 February 2012

i'm not sure how to do this. I've been tinkering with a base2 version of this formatter, but higher ip addresses flip the sign whenever I try to get a numeric or string value out of this.

			var	a = s.split( '.' ),
				r,
				u;
			if( a.length == 4 ) {
				var cidr = a[3].split('/');
				if (cidr.length > 1 ) {
					a[3] = cidr[0];
					a[4] = cidr[1];
				} else a[4] = '32';
			}
			for ( var i = 0; i < a.length; i++ ) {
				var item = parseInt(a[i]);
				item &= 255;
				switch(i) {
					case 0:
						r = (item << 24);
						break;
					case 1:
						r |= (item << 16);
						break;
					case 2:
						r |= (item << 8);
						break;
					case 3:
						r |= item;
						break;
					case 4:
						u = r; /* preserve unmasked value */
						if( item <= 32 ) {
							item = 32 - item;
							if( item > 0 ) {
								r = r >> item;
								r = r << item;
							}
						}
						break;
				}
			}

This does not work for instance with "192.168.31.2" . If anyone has more experience with bit operations in JS, then I welcome the feedback.

#Comment by TheDJ (talk | contribs)   00:21, 20 February 2012

OK, i might have found a way, but it's becoming a rather complex function now... It will also require testing on IE. BTW, what do you guys expect to sort higher ? So what is the expectation regarding sort order ? I currently have:

Ascending: 10.0.0.0/8 10.5.5.5/8 10.0.0.0/16 10.0.0.0/32, 10.0.0.0 10.5.5.5 192.168.0.0/8 192.168.0.0/32 192.168.0.0

That is masked value from big to small, then for equal subsets, subordered by unmasked value. A /32 is also 'smaller' than an unmasked IP address.

#Comment by Hashar (talk | contribs)   06:55, 20 February 2012

I would keep the host sort this way but sort the CIDR in reverse order. A /8 represents roughly 16Millions IP, way more IP than a /32:

Ascending:

10.0.0.0
10.0.0.0/32
10.0.0.0/16
10.0.0.0/8
10.5.5.5
10.5.5.5/8
192.168.0.0
192.168.0.0/32
192.168.0.0/8

The next funny case is were to insert 10.255.0.0/16 in the above list ? It should be between 10.0.0.0/16 and 10.0.0.0/8 since it has the same size has 10.0.0.0/16 but it is contained by 10.0.0.0/8.

10.0.0.0
10.0.0.0/32
10.0.0.0/16
10.255.0.0/16 <-----
10.0.0.0/8

That is not going to help you devising a smart CIDR sorter :-]


Since you normalize an IP to /32, you can not guarantee yet that an IP will be placed before its /32 representation. One way to verify it is to try sorting:

10.0.0.0
10.0.0.0/32

And sort

10.0.0.0/32
10.0.0.0

And verify that both give the same output for consistence.

Status & tagging log