Package: geoip-bin
Version: 1.6.2-2
Severity: important
Tags: patch

This patch adds support to skip location IDs, if upstream CSV is not
correctly built.

diff -Naur '--exclude=.svn' tags/1.6.2-2/debian/src/geoip-csv-to-dat.cpp 
branches/jessie/debian/src/geoip-csv-to-dat.cpp
--- tags/1.6.2-2/debian/src/geoip-csv-to-dat.cpp        2014-10-27 
19:31:48.626784609 +0100
+++ branches/jessie/debian/src/geoip-csv-to-dat.cpp     2014-12-30 
19:32:51.588379341 +0100
@@ -694,12 +694,15 @@
        class city_dat_writer : public dat_writer
        {
        public:
-               // All serialized location information
+               // All serialized location information, in one big
+               // undifferentiated block
                std::stringstream location_stream;
 
                // Seek offset of each location within
                // location_stream (relative to the beginning of
-               // location_stream)
+               // location_stream). An offset of -1 means that that
+               // location is not in the table (can happen if the
+               // location info's out of order).
                std::vector<int> location_pos;
 
                city_dat_writer(const char *dat_file_name, GeoIPDBTypes 
database_type);
@@ -744,14 +747,22 @@
        {
                if (it->edges[0] == 0x1000000) // No data
                        it->edges[0] = trie_size;
-               else if (it->edges[0] > 0x1000000) // Ptr to location block
-                       it->edges[0] = location_pos[it->edges[0] - 0x1000000 - 
1] + trie_size;
+               else if (it->edges[0] > 0x1000000) { // Ptr to location block
+                       int loc_id = it->edges[0] - 0x1000000;
+                       if (loc_id >= location_pos.size() || 
location_pos[loc_id] == -1)
+                               error(EX_DATAERR, 1, "Location %d exists in 
blocks but not in locations", loc_id);
+                       it->edges[0] = location_pos[loc_id] + trie_size;
+               }
                // Any other value would indicate a non-leaf node
 
                if (it->edges[1] == 0x1000000) // No data
                        it->edges[1] = trie_size;
-               else if (it->edges[1] > 0x1000000) // Ptr to location block
-                       it->edges[1] = location_pos[it->edges[1] - 0x1000000 - 
1] + trie_size;
+               else if (it->edges[1] > 0x1000000) { // Ptr to location block
+                       int loc_id = it->edges[1] - 0x1000000;
+                       if (loc_id >= location_pos.size() || 
location_pos[loc_id] == -1)
+                               error(EX_DATAERR, 1, "Location %d exists in 
blocks but not in locations", loc_id);
+                       it->edges[1] = location_pos[loc_id] + trie_size;
+               }
                // Any other value would indicate a non-leaf node
        }
 }
@@ -801,19 +812,33 @@
                                              const char *input_file_name,
                                              int input_line_number)
 {
-       // There's nothing wrong with location info being out of
-       // order, but currently we don't support it (i.e. the code
-       // won't work if the info's out of order). Sanity check that
-       // things are in order.
+       // First, we save the offset of this location block.
        int loc_id = ::atoi(info[0].c_str());
-       if (loc_id != location_pos.size() + 1) {
-               error_at_line(EX_DATAERR, 0, input_file_name, input_line_number,
-                             "Location info not in order (currently not 
supported)");
-               return;
-       }
+       if (loc_id >= location_pos.size()) {
+               // We need to add to the location table (this is the
+               // usual case).
+
+               while(loc_id > location_pos.size()) {
+                       // If some numbers were skipped in the data,
+                       // then we need to add some empty locations to
+                       // the table before we find our spot.
+                       location_pos.push_back(-1);
+               }
 
-       // First, we save the offset of this location block.
-       location_pos.push_back(location_stream.tellp());
+               // Now we have our spot, insert this location.
+               location_pos.push_back(location_stream.tellp());
+       } else {
+               // We already have a space in the table for this location --
+               // if it's not empty, then we have two locations with the same
+               // ID, and we print an error.
+               if (location_pos[loc_id] != -1) {
+                       error_at_line(EX_DATAERR, 0, input_file_name,
+                                     input_line_number,
+                                     "Duplicate location info for ID %d",
+                                     loc_id);
+               }
+               location_pos[loc_id] = location_stream.tellp();
+       }
 
        // Country ID
        int country_id;
@@ -1319,8 +1344,8 @@
                return;
        }
 
-       const int locid = atoi(csv_fields[CSV_BLOCK_FIELD_LOC].c_str());
-       const binary_trie::edge_type leaf = 0x1000000 + locid;
+       const int loc_id = atoi(csv_fields[CSV_BLOCK_FIELD_LOC].c_str());
+       const binary_trie::edge_type leaf = 0x1000000 + loc_id;
 
        if (cmdline.address_family != AF_INET) {
                error(EX_SOFTWARE, 1, "IPv6 with city database is 
unimplemented.");

-- System Information:
Debian Release: 7.7
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages geoip-bin depends on:
ii  libc6       2.13-38+deb7u6
ii  libgcc1     1:4.7.2-5
ii  libgeoip1   1.4.8+dfsg-3
ii  libstdc++6  4.7.2-5

geoip-bin recommends no packages.

geoip-bin suggests no packages.

-- no debconf information


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to