From 297a4333cd731e92d9781ca260d7ec00512a18fa Mon Sep 17 00:00:00 2001
From: Eric Lippmann <eric.lippmann@netways.de>
Date: Fri, 4 Sep 2015 11:58:11 +0200
Subject: [PATCH] lib/ldap: Use the indefinite form of the length octets for
 encoded sort rules where appropriate

I guess we may never need this, but hey :)

refs #9364
---
 .../Icinga/Protocol/Ldap/LdapConnection.php   | 40 ++++++++++++++-----
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/library/Icinga/Protocol/Ldap/LdapConnection.php b/library/Icinga/Protocol/Ldap/LdapConnection.php
index 3d30f9852..57b1fe90d 100644
--- a/library/Icinga/Protocol/Ldap/LdapConnection.php
+++ b/library/Icinga/Protocol/Ldap/LdapConnection.php
@@ -936,24 +936,44 @@ class LdapConnection implements Selectable, Inspectable
      */
     protected function encodeSortRules(array $sortRules)
     {
-        // TODO(el): Indefinite form of length octet
         $sequenceOf = '';
 
         foreach ($sortRules as $rule) {
-            $reversed = '0101' . ($rule[1] === Sortable::SORT_DESC ? 'ff' : '00');
+            if (false && $rule[1] === Sortable::SORT_DESC) {
+                $reversed = '0101ff';
+            } else {
+                $reversed = '';
+            }
 
             $attributeType = unpack('H*', $rule[0]);
             $attributeType = $attributeType[1];
-            $attributeType = '04' . str_pad(dechex(strlen($attributeType) / 2), 2, '0', STR_PAD_LEFT) . $attributeType;
-            $sequence = '30'
-                . str_pad(dechex(strlen($attributeType . $reversed) / 2), 2, '0', STR_PAD_LEFT)
-                . $attributeType
-                . $reversed;
+            $attributeOctets = strlen($attributeType) / 2;
+            if ($attributeOctets >= 127) {
+                // Use the indefinite form of the length octets (the long form would be another option)
+                $attributeType = '0440' . $attributeType . '0000';
+
+            } else {
+                $attributeType = '04' . str_pad(dechex($attributeOctets), 2, '0', STR_PAD_LEFT) . $attributeType;
+            }
+
+            $sequence = $attributeType . $reversed;
+            $sequenceOctects = strlen($sequence) / 2;
+            if ($sequenceOctects >= 127) {
+                $sequence = '3040' . $sequence . '0000';
+            } else {
+                $sequence = '30' . str_pad(dechex($sequenceOctects), 2, '0', STR_PAD_LEFT) . $sequence;
+            }
+
             $sequenceOf .= $sequence;
         }
-        $sequenceOf = '30'
-            . str_pad(dechex(strlen($sequenceOf) / 2), 2, '0', STR_PAD_LEFT)
-            . $sequenceOf;
+
+        $sequenceOfOctets = strlen($sequenceOf) / 2;
+        if ($sequenceOfOctets >= 127) {
+            $sequenceOf = '3040' . $sequenceOf . '0000';
+        } else {
+            $sequenceOf = '30' . str_pad(dechex($sequenceOfOctets), 2, '0', STR_PAD_LEFT) . $sequenceOf;
+        }
+
         return hex2bin($sequenceOf);
     }