unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
ab1fc0e3ba16840aff562fdb2c64d0d235f4dc9f blob 2925 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 
/*
 * Generic C functions and macros go here, there are no dependencies
 * on Unicorn internal structures or the Ruby C API in here.
 */

#ifndef UH_util_h
#define UH_util_h

#include <unistd.h>
#include <assert.h>

#define MIN(a,b) (a < b ? a : b)
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

#ifndef SIZEOF_OFF_T
#  define SIZEOF_OFF_T 4
#  warning SIZEOF_OFF_T not defined, guessing 4.  Did you run extconf.rb?
#endif

#if SIZEOF_OFF_T == 4
#  define UH_OFF_T_MAX 0x7fffffff
#elif SIZEOF_OFF_T == 8
#  if SIZEOF_LONG == 4
#    define UH_OFF_T_MAX 0x7fffffffffffffffLL
#  else
#    define UH_OFF_T_MAX 0x7fffffffffffffff
#  endif
#else
#  error off_t size unknown for this platform!
#endif /* SIZEOF_OFF_T check */

/*
 * ragel enforces fpc as a const, and merely casting can make picky
 * compilers unhappy, so we have this little helper do our dirty work
 */
static inline void *deconst(const void *in)
{
  union { const void *in; void *out; } tmp;

  tmp.in = in;

  return tmp.out;
}

/*
 * capitalizes all lower-case ASCII characters and converts dashes
 * to underscores for HTTP headers.  Locale-agnostic.
 */
static void snake_upcase_char(char *c)
{
  if (*c >= 'a' && *c <= 'z')
    *c &= ~0x20;
  else if (*c == '-')
    *c = '_';
}

/* Downcases a single ASCII character.  Locale-agnostic. */
static void downcase_char(char *c)
{
  if (*c >= 'A' && *c <= 'Z')
    *c |= 0x20;
}

static int hexchar2int(int xdigit)
{
  if (xdigit >= 'A' && xdigit <= 'F')
    return xdigit - 'A' + 10;
  if (xdigit >= 'a' && xdigit <= 'f')
    return xdigit - 'a' + 10;

  /* Ragel already does runtime range checking for us in Unicorn: */
  assert(xdigit >= '0' && xdigit <= '9' && "invalid digit character");

  return xdigit - '0';
}

/*
 * multiplies +i+ by +base+ and increments the result by the parsed
 * integer value of +xdigit+.  +xdigit+ is a character byte
 * representing a number the range of 0..(base-1)
 * returns the new value of +i+ on success
 * returns -1 on errors (including overflow)
 */
static off_t step_incr(off_t i, int xdigit, const int base)
{
  static const off_t max = UH_OFF_T_MAX;
  const off_t next_max = (max - (max % base)) / base;
  off_t offset = hexchar2int(xdigit);

  if (offset > (base - 1))
    return -1;
  if (i > next_max)
    return -1;
  i *= base;

  if ((offset > (base - 1)) || ((max - i) < offset))
    return -1;

  return i + offset;
}

/*
 * parses a non-negative length according to base-10 and
 * returns it as an off_t value.  Returns -1 on errors
 * (including overflow).
 */
static off_t parse_length(const char *value, size_t length)
{
  off_t rv;

  for (rv = 0; length-- && rv >= 0; ++value) {
    if (*value >= '0' && *value <= '9')
      rv = step_incr(rv, *value, 10);
    else
      return -1;
  }

  return rv;
}

#define CONST_MEM_EQ(const_p, buf, len) \
  ((sizeof(const_p) - 1) == len && !memcmp(const_p, buf, sizeof(const_p) - 1))

#endif /* UH_util_h */
debug log:

solving ab1fc0e ...
found ab1fc0e in https://yhbt.net/unicorn.git

Code repositories for project(s) associated with this inbox:

	../../../unicorn.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).