~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

Viewing changes to subversion/libsvn_subr/hash.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * hash.c :  dumping and reading hash tables to/from files.
3
3
 *
4
4
 * ====================================================================
5
 
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
6
 
 *
7
 
 * This software is licensed as described in the file COPYING, which
8
 
 * you should have received as part of this distribution.  The terms
9
 
 * are also available at http://subversion.tigris.org/license-1.html.
10
 
 * If newer versions of this license are posted there, you may use a
11
 
 * newer version instead, at your option.
12
 
 *
13
 
 * This software consists of voluntary contributions made by many
14
 
 * individuals.  For exact contribution history, see the revision
15
 
 * history and logs, available at http://subversion.tigris.org/.
 
5
 *    Licensed to the Apache Software Foundation (ASF) under one
 
6
 *    or more contributor license agreements.  See the NOTICE file
 
7
 *    distributed with this work for additional information
 
8
 *    regarding copyright ownership.  The ASF licenses this file
 
9
 *    to you under the Apache License, Version 2.0 (the
 
10
 *    "License"); you may not use this file except in compliance
 
11
 *    with the License.  You may obtain a copy of the License at
 
12
 *
 
13
 *      http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 *    Unless required by applicable law or agreed to in writing,
 
16
 *    software distributed under the License is distributed on an
 
17
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
18
 *    KIND, either express or implied.  See the License for the
 
19
 *    specific language governing permissions and limitations
 
20
 *    under the License.
16
21
 * ====================================================================
17
22
 */
18
23
 
20
25
 
21
26
#include <stdlib.h>
22
27
#include <limits.h>
 
28
 
23
29
#include <apr_version.h>
24
30
#include <apr_pools.h>
25
31
#include <apr_hash.h>
26
32
#include <apr_file_io.h>
 
33
 
27
34
#include "svn_types.h"
28
35
#include "svn_string.h"
29
36
#include "svn_error.h"
31
38
#include "svn_sorts.h"
32
39
#include "svn_io.h"
33
40
#include "svn_pools.h"
 
41
 
34
42
#include "private/svn_dep_compat.h"
35
43
 
 
44
#include "svn_private_config.h"
 
45
 
 
46
 
36
47
 
37
48
 
38
49
/*
101
112
 
102
113
      /* Check for unexpected end of stream */
103
114
      if (eof)
104
 
        return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
115
        return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
116
                                _("Serialized hash missing terminator"));
105
117
 
106
118
      if ((buf->len >= 3) && (buf->data[0] == 'K') && (buf->data[1] == ' '))
107
119
        {
108
120
          /* Get the length of the key */
109
121
          keylen = (size_t) strtoul(buf->data + 2, &end, 10);
110
122
          if (keylen == (size_t) ULONG_MAX || *end != '\0')
111
 
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
123
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
124
                                    _("Serialized hash malformed"));
112
125
 
113
126
          /* Now read that much into a buffer. */
114
127
          keybuf = apr_palloc(pool, keylen + 1);
119
132
          len = 1;
120
133
          SVN_ERR(svn_stream_read(stream, &c, &len));
121
134
          if (c != '\n')
122
 
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
135
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
136
                                    _("Serialized hash malformed"));
123
137
 
124
138
          /* Read a val length line */
125
139
          SVN_ERR(svn_stream_readline(stream, &buf, "\n", &eof, iterpool));
128
142
            {
129
143
              vallen = (size_t) strtoul(buf->data + 2, &end, 10);
130
144
              if (vallen == (size_t) ULONG_MAX || *end != '\0')
131
 
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
145
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
146
                                        _("Serialized hash malformed"));
132
147
 
133
148
              valbuf = apr_palloc(iterpool, vallen + 1);
134
149
              SVN_ERR(svn_stream_read(stream, valbuf, &vallen));
138
153
              len = 1;
139
154
              SVN_ERR(svn_stream_read(stream, &c, &len));
140
155
              if (c != '\n')
141
 
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
156
                return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
157
                                        _("Serialized hash malformed"));
142
158
 
143
159
              /* Add a new hash entry. */
144
160
              apr_hash_set(hash, keybuf, keylen,
145
161
                           svn_string_ncreate(valbuf, vallen, pool));
146
162
            }
147
163
          else
148
 
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
164
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
165
                                    _("Serialized hash malformed"));
149
166
        }
150
167
      else if (incremental && (buf->len >= 3)
151
168
               && (buf->data[0] == 'D') && (buf->data[1] == ' '))
153
170
          /* Get the length of the key */
154
171
          keylen = (size_t) strtoul(buf->data + 2, &end, 10);
155
172
          if (keylen == (size_t) ULONG_MAX || *end != '\0')
156
 
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
173
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
174
                                    _("Serialized hash malformed"));
157
175
 
158
176
          /* Now read that much into a buffer. */
159
177
          keybuf = apr_palloc(iterpool, keylen + 1);
164
182
          len = 1;
165
183
          SVN_ERR(svn_stream_read(stream, &c, &len));
166
184
          if (c != '\n')
167
 
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
185
            return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
186
                                    _("Serialized hash malformed"));
168
187
 
169
188
          /* Remove this hash entry. */
170
189
          apr_hash_set(hash, keybuf, keylen, NULL);
171
190
        }
172
191
      else
173
192
        {
174
 
          return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL, NULL);
 
193
          return svn_error_create(SVN_ERR_MALFORMED_FILE, NULL,
 
194
                                  _("Serialized hash malformed"));
175
195
        }
176
196
    }
177
197
 
339
359
        }
340
360
      else if ((buf[0] == 'K') && (buf[1] == ' '))
341
361
        {
 
362
          size_t keylen;
 
363
          int parsed_len;
 
364
          void *keybuf;
 
365
 
342
366
          /* Get the length of the key */
343
 
          size_t keylen = (size_t) atoi(buf + 2);
 
367
          SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
 
368
          keylen = parsed_len;
344
369
 
345
370
          /* Now read that much into a buffer, + 1 byte for null terminator */
346
 
          void *keybuf = apr_palloc(pool, keylen + 1);
347
 
          SVN_ERR(svn_io_file_read_full(srcfile,
348
 
                                        keybuf, keylen, &num_read, pool));
 
371
          keybuf = apr_palloc(pool, keylen + 1);
 
372
          SVN_ERR(svn_io_file_read_full2(srcfile,
 
373
                                         keybuf, keylen,
 
374
                                         &num_read, NULL, pool));
349
375
          ((char *) keybuf)[keylen] = '\0';
350
376
 
351
377
          /* Suck up extra newline after key data */
360
386
          if ((buf[0] == 'V') && (buf[1] == ' '))
361
387
            {
362
388
              svn_string_t *value = apr_palloc(pool, sizeof(*value));
 
389
              apr_size_t vallen;
 
390
              void *valbuf;
363
391
 
364
392
              /* Get the length of the value */
365
 
              apr_size_t vallen = atoi(buf + 2);
 
393
              SVN_ERR(svn_cstring_atoi(&parsed_len, buf + 2));
 
394
              vallen = parsed_len;
366
395
 
367
396
              /* Again, 1 extra byte for the null termination. */
368
 
              void *valbuf = apr_palloc(pool, vallen + 1);
369
 
              SVN_ERR(svn_io_file_read_full(srcfile,
370
 
                                            valbuf, vallen,
371
 
                                            &num_read, pool));
 
397
              valbuf = apr_palloc(pool, vallen + 1);
 
398
              SVN_ERR(svn_io_file_read_full2(srcfile,
 
399
                                             valbuf, vallen,
 
400
                                             &num_read, NULL, pool));
372
401
              ((char *) valbuf)[vallen] = '\0';
373
402
 
374
403
              /* Suck up extra newline after val data */
453
482
 
454
483
  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
455
484
    {
456
 
      const void *key;
457
 
      const char *path;
458
 
 
459
 
      apr_hash_this(hi, &key, NULL, NULL);
460
 
      path = key;
461
 
 
462
 
      APR_ARRAY_PUSH(*array, const char *) = path;
 
485
      APR_ARRAY_PUSH(*array, const char *) = svn__apr_hash_index_key(hi);
463
486
    }
464
487
 
465
488
  return SVN_NO_ERROR;
485
508
 
486
509
 
487
510
svn_error_t *
488
 
svn_hash__clear(apr_hash_t *hash)
 
511
svn_hash__clear(apr_hash_t *hash, apr_pool_t *pool)
489
512
{
490
513
#if APR_VERSION_AT_LEAST(1, 3, 0)
491
514
  apr_hash_clear(hash);
494
517
  const void *key;
495
518
  apr_ssize_t klen;
496
519
 
497
 
  for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi))
 
520
  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
498
521
    {
499
522
      apr_hash_this(hi, &key, &klen, NULL);
500
523
      apr_hash_set(hash, key, klen, NULL);
502
525
#endif
503
526
  return SVN_NO_ERROR;
504
527
}
 
528
 
 
529
 
 
530
 
 
531
/*** Specialized getter APIs ***/
 
532
 
 
533
const char *
 
534
svn_hash__get_cstring(apr_hash_t *hash,
 
535
                      const char *key,
 
536
                      const char *default_value)
 
537
{
 
538
  if (hash)
 
539
    {
 
540
      const char *value = apr_hash_get(hash, key, APR_HASH_KEY_STRING);
 
541
      return value ? value : default_value;
 
542
    }
 
543
 
 
544
  return default_value;
 
545
}
 
546
 
 
547
 
 
548
svn_boolean_t
 
549
svn_hash__get_bool(apr_hash_t *hash, const char *key,
 
550
                   svn_boolean_t default_value)
 
551
{
 
552
  const char *tmp_value = svn_hash__get_cstring(hash, key, NULL);
 
553
  svn_tristate_t value = svn_tristate__from_word(tmp_value);
 
554
 
 
555
  if (value == svn_tristate_true)
 
556
    return TRUE;
 
557
  else if (value == svn_tristate_false)
 
558
    return FALSE;
 
559
 
 
560
  return default_value;
 
561
}
 
562