Re: svn commit: r1917266 - in /apr/apr/trunk: buffer/apr_buffer.c include/apr_buffer.h test/testbuffer.c

2024-04-25 Thread Yann Ylavic
[Graham please use plain text emails or at least fix your MUA so that
one does not need to re-quote/format your messages when replying in
plain text]

On Wed, Apr 24, 2024 at 7:51 PM Graham Leggett  wrote:
>
> On 24 Apr 2024, at 14:03, Yann Ylavic  wrote:
>>
>> Here in apr_buffer_str_set() we still have apr_ssize_t len, please
>> make it an apr_size_t for the reason explained in the other thread
>> (also the apr_buffer_mem_*() ones use apr_size_t already so it should
>> be consistent)?
>
> The apr_ssize_t is intended in this case.
>
> As per the docs, an apr_ssize_t of -1 means compute the length:
>
> https://github.com/apache/apr/blob/trunk/include/apr_buffer.h#L46
>
> /**
>  * When passing a string to apr_buffer_str_make, this value can be
>  * passed to indicate a string with unknown length, and have 
> apr_buffer_str_make
>  * compute the length automatically.
>  */
> #define APR_BUFFER_STRING (-1)

I've got that, but it's still a valid value to pass in a size_t, which
with sign extension will become (apr_size_t)-1, i.e. APR_SIZE_MAX.
If len is a size_t it's still perfectly defined and works to pass it -1, though:
 #define APR_BUFFER_STRING  ((apr_size_t)-1) /* or APR_SIZE_MAX */
would make it an unsigned value and is probably cleaner.

>
> https://github.com/apache/apr/blob/trunk/include/apr_buffer.h#L125
>
>  * @param len The length of the string without terminating zero, or
>  * APR_BUFFER_STRING to have the length calculated.
>
> The definition of ssize_t is "unsigned length or -1", so we're using it 
> correctly.

The definition is not really "unsigned length or -1", it's _at least_
greater or equal to -1, but it has to be a signed type to be able to
represent -1 (in practice it's the same as ptrdiff_t, no real
restriction/trap when below -1).

But anyway, the point is that you cannot pass strlen() or any size_t
to a ssize_t without first checking that it's representable in a
ssize_t, so if len is defined as ssize_t the onus is on the user to
verify that the passed in value (possibly and likely an
unsigned/size_t which is what users use for sizes) fits in a ssize_t
*before* calling apr_buffer_str_set/make(). And then the checks in
apr_buffer_str_set/make() for len > APR_BUFFER_MAX are just useless,
the compiler might just have assumed that since it's undefined to pass
an unrepresentable value then len > APR_BUFFER_MAX just cannot happen
and it simply removes/optimizes out the test..

>
> The purpose of the apr_buffer is to make a stark and impossible to mix up 
> distinction between a string and a memory area, apr_buffer_src() and 
> apr_buffer_mem() definitely shouldn't be the same.

>>>
>>> if (!str) {
>>> buf->d.str = NULL;
>>> buf->size = 0;
>>> +buf->zero_terminated = 0;
>>> }
>>> else if (len < 0) {
>>> apr_size_t slen = strlen(str);
>>> if (slen <= APR_BUFFER_MAX) {
>>> buf->d.str = str;
>>> -buf->size = -(apr_off_t)(slen + 1);
>>> +buf->size = slen;
>>> +buf->zero_terminated = 1;
>>> }
>>> else {
>>> buf->d.str = NULL;
>>> buf->size = 0;
>>> +buf->zero_terminated = 0;
>>
>> return APR_EINVAL?
>
> A NULL buffer is valid and intended.

But here it becomes NULL because len > APR_BUFFER_MAX, not because the
user passed NULL, so it's an error?

>>
>> Overall I think it could be simplified as:
>>
>> APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
>> char *str, apr_size_t len)
>> {
>>if (len == APR_BUFFER_STRING) {
>>len = str ? strlen(str) : 0;
>>}
>>else if (str ? str[len] != '\0' : len != 0) {
>>return APR_EINVAL;
>>}
>>if (len > APR_BUFFER_MAX) {
>>return APR_EINVAL; /* or APR_ENOSPC? */
>>}
>>
>>buf->d.str = str;
>>buf->size = len;
>>buf->zero_terminated = 1;
>>
>>return APR_SUCCESS;
>> }
>
> This breaks when src is NULL.

What breaks? If src (actually str) is NULL then ->d.str is NULL but
it's what you want AFAICT (plus the above also enforces that len is
zero in this case).
Or do you mean ->zero_termined is broken? All right, so how about:
buf->zero_terminated = (str != NULL);
?

>>
>> Likewise apr_ssize_t => apr_size_t len for apr_buffer_str_make(),
>> APR_BUFFER_STRING and co should be unsigned (e.g. APR_SIZE_MAX) too.
>
> We already use -1 to mean "compute the length&

Re: svn commit: r1917266 - in /apr/apr/trunk: buffer/apr_buffer.c include/apr_buffer.h test/testbuffer.c

2024-04-24 Thread Yann Ylavic
On Wed, Apr 24, 2024 at 3:03 PM Yann Ylavic  wrote:
>
> APR_DECLARE(int) apr_buffer_cmp(const apr_buffer_t *src,
> const apr_buffer_t *dst)
> {
> apr_size_t slen, dlen;
>
> if (!src) {
> return dst ? 1 : 0;
> }
> if (!dst) {
> return -1;
> }
> if (src->size != dst->size) {
> return src->size < dst->size ? -1 : 1;
> }
>
> return memcmp(src->d.mem, dst->d.mem, slen);
> }
>
> Though I still don't think that we should handle NULLs here (let it crash..).

I meant:

APR_DECLARE(int) apr_buffer_cmp(const apr_buffer_t *src,
const apr_buffer_t *dst)
{
apr_size_t slen, dlen;

if (!src.d.mem) {
return dst.d.mem ? 1 : 0;
}
if (!dst.d.mem) {
return -1;
}
if (src->size != dst->size) {
return src->size < dst->size ? -1 : 1;
}

return memcmp(src->d.mem, dst->d.mem, slen);
}


Re: svn commit: r1917266 - in /apr/apr/trunk: buffer/apr_buffer.c include/apr_buffer.h test/testbuffer.c

2024-04-24 Thread Yann Ylavic
On Mon, Apr 22, 2024 at 2:46 PM  wrote:
>
> --- apr/apr/trunk/buffer/apr_buffer.c (original)
> +++ apr/apr/trunk/buffer/apr_buffer.c Mon Apr 22 12:46:37 2024
> @@ -28,7 +28,7 @@
>  #include "apr_strings.h"
>  #include "apr_private.h"
>
> -#define APR_BUFFER_MAX APR_SIZE_MAX/2
> +#define APR_BUFFER_MAX (APR_SIZE_MAX/2-1)

It seems that the ->size does include the terminating NUL byte so
APR_BUFFER_MAX could be APR_SIZE_MAX/2 no? Why -1 here?
Also maybe ->size should be ->len then?

>
> @@ -74,21 +76,25 @@ APR_DECLARE(apr_status_t) apr_buffer_str

Here in apr_buffer_str_set() we still have apr_ssize_t len, please
make it an apr_size_t for the reason explained in the other thread
(also the apr_buffer_mem_*() ones use apr_size_t already so it should
be consistent)?

>  if (!str) {
>  buf->d.str = NULL;
>  buf->size = 0;
> +buf->zero_terminated = 0;
>  }
>  else if (len < 0) {
>  apr_size_t slen = strlen(str);
>  if (slen <= APR_BUFFER_MAX) {
>  buf->d.str = str;
> -buf->size = -(apr_off_t)(slen + 1);
> +buf->size = slen;
> +buf->zero_terminated = 1;
>  }
>  else {
>  buf->d.str = NULL;
>  buf->size = 0;
> +buf->zero_terminated = 0;

return APR_EINVAL?

>  }
>  }
>  else {
>  buf->d.str = str;
> -buf->size = -(len + 1);
> +buf->size = len;
> +buf->zero_terminated = 1;

Shouldn't we check that str[len] == '\0' here? Though if it's not the
check might be out of bounds, but OTOH it's not a string buffer and
->zero_terminated is not true..

>  }
>
>  return APR_SUCCESS;

Overall I think it could be simplified as:

APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
 char *str, apr_size_t len)
{
if (len == APR_BUFFER_STRING) {
len = str ? strlen(str) : 0;
}
else if (str ? str[len] != '\0' : len != 0) {
return APR_EINVAL;
}
if (len > APR_BUFFER_MAX) {
return APR_EINVAL; /* or APR_ENOSPC? */
}

buf->d.str = str;
buf->size = len;
buf->zero_terminated = 1;

return APR_SUCCESS;
}


> @@ -100,25 +106,25 @@ APR_DECLARE(apr_buffer_t *) apr_buffer_s

Likewise apr_ssize_t => apr_size_t len for apr_buffer_str_make(),
APR_BUFFER_STRING and co should be unsigned (e.g. APR_SIZE_MAX) too.

>  apr_buffer_t *buf;
>  apr_int64_t size;
>  apr_size_t slen;
> +unsigned int zero_terminated;
>
>  if (!str) {
>  str = NULL;
>  size = 0;
> +zero_terminated = 0;
>  }
> -if (APR_BUFFER_STRING == len && !str[0]) {
> -size = len;
> -}
> -else if (len < 0) {
> +if (APR_BUFFER_STRING == len) {
>  slen = strlen(str);
>  if (slen <= APR_BUFFER_MAX) {
> -size = -(apr_off_t)(slen + 1);
> +size = slen;
> +zero_terminated = 1;
>  }
>  else {
>  return NULL;
>  }
>  }
>  else {
> -size = -(len + 1);
> +size = (apr_size_t)len;
>  }
>
>  buf = apr_palloc(pool, sizeof(apr_buffer_t));
> @@ -126,6 +132,7 @@ APR_DECLARE(apr_buffer_t *) apr_buffer_s
>  if (buf) {
>  buf->d.str = str;
>  buf->size = size;
> +buf->zero_terminated = zero_terminated;
>  }
>
>  return buf;

Since there could be multiple error cases for apr_buffer_str_make()
too, I think we cannot return NULL so rather than a _make() we need a
_create() like:

APR_DECLARE(apr_status_t) apr_buffer_str_create(apr_pool_t *pool,
apr_buffer_t **pbuf,
char *str, apr_size_t len)
{
*pbuf = apr_palloc(pool, sizeof(apr_buffer_t));

return *pbuf ? apr_buffer_str_set(*pbuf, str, len) : APR_ENOMEM;
}

?

>
>  APR_DECLARE(apr_size_t) apr_buffer_allocated(const apr_buffer_t *buf)

apr_buffer_size() if ->size is changed to ->len ?

>  {
> -if (buf->size < 0) {
> -return (apr_size_t)((-buf->size));
> -}
> -else {
> -return (apr_size_t)buf->size;
> -}
> +return buf->size + buf->zero_terminated;
>  }

>
>  APR_DECLARE(void *) apr_buffer_mem(const apr_buffer_t *buf, apr_size_t *size)
> @@ -227,11 +214,12 @@ APR_DECLARE(apr_buffer_t *) apr_buffer_a
>  for (i = 0; i < nelts; i++) {
>
>  /* absolute value is size of mem buffer including optional 
> terminating zero */
> -apr_size_t size = src->size < 0 ? -src->size : src->size;
> +apr_size_t size = src->size + src->zero_terminated;
>
>  void *mem = alloc(ctx, size);

Check mem == NULL => APR_ENOMEM ?

>  memcpy(mem, src->d.mem, size);
>
> +dst->zero_terminated = src->zero_terminated;
>  dst->size = src->size;
>  dst->d.mem = mem;

>
> @@ -256,22 +244,25 @@ APR_DECLARE(apr_buffer_t *) apr_buffer_c
>
>  dst->d.mem = 

Re: svn commit: r1917047 - in /apr/apr/trunk: CHANGES buffer/ buffer/apr_buffer.c build.conf include/apr_buffer.h test/Makefile.in test/Makefile.win test/NWGNUaprtest test/abts_tests.h test/testbuffer

2024-04-18 Thread Yann Ylavic
On Tue, Apr 16, 2024 at 10:54 PM  wrote:
>
> --- apr/apr/trunk/buffer/apr_buffer.c (added)
> +++ apr/apr/trunk/buffer/apr_buffer.c Tue Apr 16 20:54:51 2024
> @@ -0,0 +1,408 @@
> +
> +APR_DECLARE(apr_buffer_t *) apr_buffer_mem_make(apr_pool_t *pool,
> +void *mem, apr_size_t len)

Two different possibilities for returning NULL, maybe an
apr_buffer_mem_create() instead returning APR_EINVAL/ENOMEM
accordingly.

> +{
> +apr_buffer_t *buf;
> +
> +if (len > APR_INT64_MAX) {
> +return NULL;
> +}
> +
> +buf = apr_palloc(pool, sizeof(apr_buffer_t));
> +
> +if (buf) {
> +buf->d.mem = mem;
> +buf->size = len;
> +}
> +
> +return buf;
> +}
> +
> +APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
> + char *str, apr_ssize_t len)
> +{
> +
> +if (len > APR_INT64_MAX) {
> +return APR_EINVAL;
> +}
> +
> +if (!str) {
> +buf->d.str = NULL;
> +buf->size = 0;
> +}
> +else if (len < 0) {
> +apr_size_t slen = strlen(str);
> +if (slen <= APR_INT64_MAX) {
> +buf->d.str = str;
> +buf->size = -(slen + 1);
> +}
> +else {

return APR_EINVAL?

> +buf->d.str = NULL;
> +buf->size = 0;
> +}
> +}
> +else {
> +buf->d.str = str;
> +buf->size = -(len + 1);
> +}
> +
> +return APR_SUCCESS;
> +}
> +
> +APR_DECLARE(apr_buffer_t *) apr_buffer_str_make(apr_pool_t *pool,
> +char *str, apr_ssize_t len)

Likewise several possibilities for returning NULL, apr_buffer_str_create()?

> +{
> +apr_buffer_t *buf;
> +apr_int64_t size;
> +apr_size_t slen;
> +
> +if (!str) {
> +str = NULL;
> +size = 0;
> +}
> +if (APR_BUFFER_STRING == len && !str[0]) {
> +size = len;
> +}
> +else if (len < 0) {
> +slen = strlen(str);
> +if (slen <= APR_INT64_MAX) {
> +size = -(slen + 1);
> +}
> +else {
> +return NULL;
> +}
> +}
> +else {
> +size = -(len + 1);
> +}
> +
> +buf = apr_palloc(pool, sizeof(apr_buffer_t));
> +
> +if (buf) {
> +buf->d.str = str;
> +buf->size = size;
> +}
> +
> +return buf;
> +}
> +
> +APR_DECLARE(apr_buffer_t *) apr_buffer_null_make(apr_pool_t *pool)
> +{
> +return apr_pcalloc(pool, sizeof(apr_buffer_t));
> +}
> +
> +APR_DECLARE(apr_size_t) apr_buffer_len(const apr_buffer_t *buf)
> +{
> +if (buf->size < 0) {
> +return (apr_size_t)((-buf->size) - 1);
> +}
> +else {
> +return (apr_size_t)buf->size;
> +}
> +}
> +
> +APR_DECLARE(apr_size_t) apr_buffer_allocated(const apr_buffer_t *buf)

Same as apr_buffer_len()?

> +{
> +if (buf->size < 0) {
> +return (apr_size_t)((-buf->size));
> +}
> +else {
> +return (apr_size_t)buf->size;
> +}
> +}

> +
> +APR_DECLARE(void *) apr_buffer_pmemdup(apr_pool_t *pool, const apr_buffer_t 
> *buf, apr_size_t *size)
> +{
> +apr_size_t len = apr_buffer_len(buf);
> +
> +if (size) {
> +size[0] = len;
> +}
> +
> +return apr_pmemdup(pool, buf->d.mem, len);

Should pmemdup() include the '\0' for a "string" buffer?

> +}

> +
> +APR_DECLARE(apr_buffer_t *) apr_buffer_arraydup(const apr_buffer_t *src,
> +apr_buffer_alloc alloc, void 
> *ctx,
> +int nelts)

apr_size_t or at least unsigned int for nelts?

> +{
> +apr_buffer_t *dst = alloc(ctx, nelts * sizeof(apr_buffer_t));

Maybe check for nelts < APR_SIZE_MAX / sizeof(apr_buffer_t) before
allocating, and fail with APR_EINVAL otherwise?

Also, like apr_buffer_cpy() below, we could allow for allow == NULL
here (and if so maybe move the nelts argument before the alloc and
ctx).

> +apr_buffer_t *d = dst;
> +
> +int i;
> +for (i = 0; i < nelts; i++) {
> +
> +/* absolute value is size of mem buffer including optional 
> terminating zero */
> +apr_int64_t size = src->size < 0 ? -src->size : src->size;
> +
> +void *mem = alloc(ctx, size);
> +memcpy(mem, src->d.mem, size);
> +
> +dst->size = src->size;
> +dst->d.mem = mem;
> +
> +src++;
> +dst++;
> +}
> +
> +return d;
> +}


> +
> +APR_DECLARE(int) apr_buffer_cmp(const apr_buffer_t *src,
> +const apr_buffer_t *dst)
> +{
> +apr_size_t slen = apr_buffer_len(src);
> +apr_size_t dlen = apr_buffer_len(dst);
> +
> +if (slen != dlen) {
> +return slen < dlen ? -1 : 1;
> +}
> +else if (src->d.mem == dst->d.mem) {
> +/* identical data or both NULL */
> +return 0;
> +}
> +else if (!src->d.mem) {
> +return -1;
> +}
> +else if (!dst->d.mem) {
> +

Re: svn commit: r1917082 - /apr/apr/trunk/buffer/apr_buffer.c

2024-04-18 Thread Yann Ylavic
On Thu, Apr 18, 2024 at 3:58 PM Graham Leggett  wrote:
>
> On 18 Apr 2024, at 13:15, Yann Ylavic  wrote:
>
>> But let me plead again for a much simpler ->size of type apr_size_t,
>> checked against APR_BUFFER_MAX=APR_SIZE_MAX/2 wherever an apr_buffer_t
>> is initialized, using the high bit of ->size for string vs plain
>> buffer, and then getting rid of off_t/ssize_t plus all the fancy
>> signed arithmetics in the apr_buffer code (we don't care about the
>> sizeof(off_t) or anything like that anymore)..
>
> I looked at it, and it was more confusing.

There is also another completely obvious alternative which is:

typedef struct
{
union {
char *str;
void *mem;
} d;
apr_size_t size;
unsigned int flags;
} apr_buffer_t;

which also makes ->size directly usable without a helper, but you want
the type to be to words only?

If so maybe:

typedef struct
{
union {
char *str;
void *mem;
} d;
#if APR_SIZEOF_VOIDP == 8
#   define APR_BUFFER_SIZE_WIDTH 63
#else
#   define APR_BUFFER_SIZE_WIDTH 31
#endif
   apr_size_t size:APR_BUFFER_SIZE_WIDTH,
   zero_terminated:1;
} apr_buffer_t;

One could still use buf->size directly.

Regards;
Yann.


Re: svn commit: r1917082 - /apr/apr/trunk/buffer/apr_buffer.c

2024-04-18 Thread Yann Ylavic
On Thu, Apr 18, 2024 at 4:41 PM Yann Ylavic  wrote:
>
> could be:
> APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
>  char *str, apr_size_t len)
> {
> if (len == APR_BUFFER_STRING) {
> len = str ? strlen(str) : 0;
> }
> if (len > APR_BUFFER_MAX) {
> return APR_EINVAL;
> }
>
> if (!str) {
> buf->d.str = NULL;
> buf->size = 0;
> }
> else {
> buf->d.str = str;
> buf->size = len;
> }
> buf->size |= ~APR_BUFFER_MAX;

The above conditional is not even needed, just:
  buf->d.str = str;
  buf->size = len | ~APR_BUFFER_MAX;
works too.

>
> return APR_SUCCESS;
> }


Re: svn commit: r1917082 - /apr/apr/trunk/buffer/apr_buffer.c

2024-04-18 Thread Yann Ylavic
On Thu, Apr 18, 2024 at 3:58 PM Graham Leggett  wrote:
>
> On 18 Apr 2024, at 13:15, Yann Ylavic  wrote:
>
>> Indeed at least APR_BUFFER_MAX and buf->size of should be of the same
>> signedness.
>
>
> APR_BUFFER_MAX represents the size limit visible outside the API. This is 
> always positive.

I meant the same signedness of the type, not the value itself.
If APR_BUFFER_MAX is APR_SIZE_MAX/2 it's a size_t (thus unsigned),
while buf->size is an apr_off_t (thus signed), not the same types.

>
> buf->size is an internal implementation detail. This is invisible.
>
> The only reason we can see inside apr_buffer_t is because we want to allocate 
> them on the stack, and make arrays of them, so code outside needs to know the 
> size.

Fair enough, though there probably should be big warning a the struct
apr_buffer_t definition to not use ->size directly.

>
>> But let me plead again for a much simpler ->size of type apr_size_t,
>> checked against APR_BUFFER_MAX=APR_SIZE_MAX/2 wherever an apr_buffer_t
>> is initialized, using the high bit of ->size for string vs plain
>> buffer, and then getting rid of off_t/ssize_t plus all the fancy
>> signed arithmetics in the apr_buffer code (we don't care about the
>> sizeof(off_t) or anything like that anymore)..
>
>
> I looked at it, and it was more confusing.
>
> Right now, positive is a memory buffer, negative is a string. I don't know 
> why we would need to make it more complicated than that.

I think we can hardly make more complicated than:
APR_DECLARE(apr_size_t) apr_buffer_len(const apr_buffer_t *buf)
{
if (buf->size < 0) {
return (apr_size_t)((-buf->size) - 1);
}
else {
return (apr_size_t)buf->size;
}
}
...

With an apr_size_t ->size it could be:
APR_DECLARE(apr_size_t) apr_buffer_len(const apr_buffer_t *buf)
{
return buf->size & APR_BUFFER_MAX;
}
which I find much more simpler (and efficient) personally.

Another exemple:

APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
 char *str, apr_ssize_t len)
{

if (len > APR_BUFFER_MAX) {
return APR_EINVAL;
}

if (!str) {
buf->d.str = NULL;
buf->size = 0;
}
else if (len < 0) {
apr_size_t slen = strlen(str);
if (slen <= APR_BUFFER_MAX) {
buf->d.str = str;
buf->size = -(apr_off_t)(slen + 1);
}
else {
buf->d.str = NULL;
buf->size = 0;
}
}
else {
buf->d.str = str;
buf->size = -(len + 1);
}

return APR_SUCCESS;
}

could be:
APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
 char *str, apr_size_t len)
{
if (len == APR_BUFFER_STRING) {
len = str ? strlen(str) : 0;
}
if (len > APR_BUFFER_MAX) {
return APR_EINVAL;
}

if (!str) {
buf->d.str = NULL;
buf->size = 0;
}
else {
buf->d.str = str;
buf->size = len;
}
buf->size |= ~APR_BUFFER_MAX;

return APR_SUCCESS;
}

Should be the same kind of simplification everywhere I suppose.

>
>> Currently apr_buffer_str_make(mystring, strlen(mystring)) is UB, the
>> API is just broken IMHO.
>
> Can you clarify why? What, specifically, is broken, so I can fix it?

Passing/converting an unsigned value to a signed one where the
unsigned value cannot be represented in the signed one is undefined
behaviour in C.

So with:
  APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
   char *str, apr_ssize_t len);
one cannot simply do (w/o UB):
  apr_size_t len = strlen(mystr);
  apr_buffer_str_set(buf, mystr, len);
without first checking that len <= APR_BUFFER_MAX, which is not really
user friendly.

Whereas with the proposed:
  APR_DECLARE(apr_status_t) apr_buffer_str_set(apr_buffer_t *buf,
   char *str, apr_size_t len);
the will return EINVAL if len > APR_BUFFER_MAX without the user having
to do the check to avoid UB.


Regards;
Yann.


Re: svn commit: r1917082 - /apr/apr/trunk/buffer/apr_buffer.c

2024-04-18 Thread Yann Ylavic
On Thu, Apr 18, 2024 at 1:16 PM Ruediger Pluem  wrote:
>
> On 4/18/24 12:37 AM, minf...@apache.org wrote:
> > Author: minfrin
> > Date: Wed Apr 17 22:37:07 2024
> > New Revision: 1917082
> >
> > URL: http://svn.apache.org/viewvc?rev=1917082=rev
> > Log:
> > apr_buffer: Add explicit casts on all potentially narrowing conversions
> > to apr_size_t. Define the maximum buffer size as APR_SIZE_MAX/2.
> >
> > Modified:
> > apr/apr/trunk/buffer/apr_buffer.c
> >
> > Modified: apr/apr/trunk/buffer/apr_buffer.c
> > URL: 
> > http://svn.apache.org/viewvc/apr/apr/trunk/buffer/apr_buffer.c?rev=1917082=1917081=1917082=diff
> > ==
> > --- apr/apr/trunk/buffer/apr_buffer.c (original)
> > +++ apr/apr/trunk/buffer/apr_buffer.c Wed Apr 17 22:37:07 2024
> > @@ -28,12 +28,13 @@
> >  #include "apr_strings.h"
> >  #include "apr_private.h"
> >
> > +#define APR_BUFFER_MAX APR_SIZE_MAX/2
>
> Why no longer APR_OFF_MAX?

Indeed at least APR_BUFFER_MAX and buf->size of should be of the same
signedness.

But let me plead again for a much simpler ->size of type apr_size_t,
checked against APR_BUFFER_MAX=APR_SIZE_MAX/2 wherever an apr_buffer_t
is initialized, using the high bit of ->size for string vs plain
buffer, and then getting rid of off_t/ssize_t plus all the fancy
signed arithmetics in the apr_buffer code (we don't care about the
sizeof(off_t) or anything like that anymore)..

Currently apr_buffer_str_make(mystring, strlen(mystring)) is UB, the
API is just broken IMHO.


Regards;
Yann.


Re: svn commit: r1917047 - in /apr/apr/trunk: CHANGES buffer/ buffer/apr_buffer.c build.conf include/apr_buffer.h test/Makefile.in test/Makefile.win test/NWGNUaprtest test/abts_tests.h test/testbuffer

2024-04-17 Thread Yann Ylavic
On Wed, Apr 17, 2024 at 9:36 AM Graham Leggett via dev
 wrote:
>
> On 17 Apr 2024, at 08:12, Ruediger Pluem  wrote:
>
> >> I need some advice on handling Windows 32 bit. apr_int64_t for size is too 
> >> big, and tests are failing.
> >>
> >> Technically apr_ssize_t is the right size, but the definition of ssize_t 
> >> is [-1, SSIZE_MAX]. I need a signed very big number. Given we define 
> >> apr_ssize_t, is it ok to use apr_ssize_t anyway?
> >
> > How about off_t / apr_off_t instead?
>
> Perfect, will fix.

Does it work on 32bit systems since apr_off_t is always 64bitin in apr (IIRC)?

I think the right type is apr_size_t because a buffer length just
can't be negative.
That'd also avoid signed integers arithmetic games like:
+APR_DECLARE(apr_size_t) apr_buffer_len(const apr_buffer_t *buf)
+{
+if (buf->size < 0) {
+return (apr_size_t)((-buf->size) - 1);
+}
+else {
+return (apr_size_t)buf->size;
+}
+}
If you want a bit for string vs non-string buffers just limit the size
to SIZE_MAX/2 and use the high bit of an apr_size_t. The user can't
use buf->size directly still and must use apr_buffer_len() but it's no
different from the current implementation.

Likewise for the "apr_ssize_t len" parameter of apr_buffer_str_set()
and apr_buffer_str_make(), passing an sise_t/strlen() is just
undefined behaviour in C so it does not really help the user. With
apr_size_t one could pass APR_BUFFER_STRING for a nul-terminated
string and we could check the SIZE_MAX/2 limit there still.


Regards;
Yann.

PS: we have the very problem in the apr_encode/apr_escape interfaces.


Re: svn commit: r1916332 - /apr/apr/trunk/test/testescape.c

2024-03-18 Thread Yann Ylavic
On Mon, Mar 18, 2024 at 2:11 PM Joe Orton  wrote:
>
> On Fri, Mar 15, 2024 at 10:26:27AM -, yla...@apache.org wrote:
> > Author: ylavic
> > Date: Fri Mar 15 10:26:27 2024
> > New Revision: 1916332
> >
> > URL: http://svn.apache.org/viewvc?rev=1916332=rev
> > Log:
> > testescape: missing ';' in entity escaping.
>
> The test now fails... did you intend to commit the fix too, something
> like this?

Argh yes, I had another (similar) change for apr_escape_json() and
wanted to commit them separately, but this got lost when proceeding
with further changes..

Now in r1916390 (plus backports to 1.[78]).

Thanks!
Yann.


Re: svn commit: r1916337 - /apr/apr/trunk/include/apr_general.h

2024-03-18 Thread Yann Ylavic
On Mon, Mar 18, 2024 at 10:00 AM Ruediger Pluem  wrote:
>
> On 3/15/24 2:35 PM, yla...@apache.org wrote:
> >
> > -#if defined(offsetof) && !defined(__cplusplus)
> > +#if defined(__has_builtin) && __has_builtin(__builtin_offsetof)
>
> This causes an
>
> ./include/apr_general.h:109:45: error: missing binary operator before token 
> "("
>
> with gcc 8.5.0 for me. Following 
> https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fbuiltin.html
> and changing it to
>
> Index: include/apr_general.h
> ===
> --- include/apr_general.h   (revision 1916382)
> +++ include/apr_general.h   (working copy)
> @@ -106,13 +106,18 @@
>   * @param field  data field within the structure
>   * @return offset
>   */
> -#if defined(__has_builtin) && __has_builtin(__builtin_offsetof)
> +#if defined(__has_builtin)
> +#if __has_builtin(__builtin_offsetof)
>  #define APR_OFFSETOF(s_type,field) __builtin_offsetof(s_type,field)
> -#elif defined(offsetof) && !defined(__cplusplus)
> +#endif
> +#endif
> +#if !defined(APR_OFFSETOF)
> +#if defined(offsetof) && !defined(__cplusplus)
>  #define APR_OFFSETOF(s_type,field) offsetof(s_type,field)
>  #else
>  #define APR_OFFSETOF(s_type,field) APR_OFFSET(s_type*,field)
>  #endif
> +#endif
>
>
> Looks like to me that __has_builtin does not like to be used within an '&&' 
> operation for whatever reason.

oO well, ok: r1916385 (plus backports to 1.[78])

Thanks;
Yann.


APR_POOL_DEBUG in apr-util (was: APR_POOL_DEBUG usage question)

2024-02-01 Thread Yann Ylavic
dev@ team,

I'm wondering if we could/should remove APR_POOL_DEBUG specifics in
apr-util 1.6.x and 1.7.x, otherwise it's not possible run
non-pool-debug apr-util with pool-debug apr.

Fortunately the only dependency on APR_POOL_DEBUG for apr-util seems
to be the apr_bucket code below.

On Thu, Feb 1, 2024 at 2:38 PM Simon Walter wrote:
>
> I had partial success with '--enable-pool-debug=yes' and
> '--enable-pool-debug=verbose'. Then I ran into something else regarding
> apr-util. I see there are pre-processor conditions based on APR_POOL_DEBUG.
>
> In apr_bucket_alloc_create():
>
> #if APR_POOL_DEBUG
> /* may be NULL for debug mode. */
> if (allocator == NULL) {
> if (apr_allocator_create() != APR_SUCCESS) {
> apr_abortfunc_t fn = apr_pool_abort_get(p);
> if (fn)
> (fn)(APR_ENOMEM);
> abort();
> }
> }
> #endif
>
> Indeed it segfaults in allocator_alloc() because the allocator is null.

Here, if apr was compiled with APR_POOL_DEBUG but apr-util without, it
crashes because the allocator is/remains NULL.

I think this code works without the compile time "#if APR_POOL_DEBUG"
checks because there is no way for apr_pool_allocator_get() to return
NULL besides APR_POOL_DEBUG mode, and of course both apr_pool_t and
apr_bucket_alloc_t are opaque which prevents anyone from playing with
their ->allocator.
It shouldn't either cause too much overhead if running this code for
!APR_POOL_DEBUG.

So don't you think we could/should just remove the "#if
APR_POOL_DEBUG" in buckets/apr_buckets_alloc.c?


Regards;
Yann.


Re: APR_POOL_DEBUG usage question

2024-02-01 Thread Yann Ylavic
On Thu, Feb 1, 2024 at 2:38 PM Simon Walter  wrote:
>
> I had partial success with '--enable-pool-debug=yes' and
> '--enable-pool-debug=verbose'. Then I ran into something else regarding
> apr-util. I see there are pre-processor conditions based on APR_POOL_DEBUG.

Yes, you need to both apr and apr-util consistently with or without
--enable-pool-debug.

Regards;
Yann.


Re: APR_POOL_DEBUG usage question

2024-02-01 Thread Yann Ylavic
On Wed, Jan 31, 2024 at 7:44 PM Simon Walter  wrote:
>
> My question about how to debuging should be done. abort() is called on
> apr_initialize():
>
> Program received signal SIGABRT, Aborted.

Does the attached patch fix the issue with apr_initialize()?

Regards;
Yann.
Index: memory/unix/apr_pools.c
===
--- memory/unix/apr_pools.c	(revision 1913753)
+++ memory/unix/apr_pools.c	(working copy)
@@ -2029,6 +2029,13 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug
 pool->file_line = file_line;
 
 #if APR_HAS_THREADS
+pool->owner = apr_os_thread_current();
+#endif /* APR_HAS_THREADS */
+#ifdef NETWARE
+pool->owner_proc = (apr_os_proc_t)getnlmhandle();
+#endif /* defined(NETWARE) */
+
+#if APR_HAS_THREADS
 if (parent == NULL || parent->allocator != allocator) {
 apr_status_t rv;
 
@@ -2067,13 +2074,6 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug
 pool->ref = NULL;
 }
 
-#if APR_HAS_THREADS
-pool->owner = apr_os_thread_current();
-#endif /* APR_HAS_THREADS */
-#ifdef NETWARE
-pool->owner_proc = (apr_os_proc_t)getnlmhandle();
-#endif /* defined(NETWARE) */
-
 #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
 apr_pool_log_event(pool, "CREATE", file_line, 1);
 #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */


Re: APR_POOL_DEBUG usage question

2024-02-01 Thread Yann Ylavic
On Thu, Feb 1, 2024 at 1:56 PM Yann Ylavic  wrote:
>
> On Wed, Jan 31, 2024 at 7:44 PM Simon Walter  wrote:
> >
> > Should I use '--enable-pool-debug=yes' or '--enable-pool-debug=verbose'?
>
> I'd suggest using simple --enable-pool-debug[=yes] and ASan (Address
> Sanitizer, i.e. "-fsanitize=address -fno-sanitize-recover=address" in
> $CFLAGS).

I mean, ASan for compiling the APR eventually, but it should be used
to compile your program too for a full leaks/use-after-free coverage.

>
> Regards,
> Yann.


Re: APR_POOL_DEBUG usage question

2024-02-01 Thread Yann Ylavic
On Wed, Jan 31, 2024 at 7:44 PM Simon Walter  wrote:
>
> Should I use '--enable-pool-debug=yes' or '--enable-pool-debug=verbose'?

I'd suggest using simple --enable-pool-debug[=yes] and ASan (Address
Sanitizer, i.e. "-fsanitize=address -fno-sanitize-recover=address" in
$CFLAGS).


Regards,
Yann.


Re: Out of tree build broken for APR 1.7.x and 1.8.x

2023-10-16 Thread Yann Ylavic
On Mon, Oct 16, 2023 at 11:41 AM Rainer Jung  wrote:
>
> This problem is in 1.7.x and 1.8.x. I did not check apr trunk.

Looks like apr_private_common.h does not exist in trunk (anymore?).

>
> Unfortunately I have no idea how to make autoheader to use
>
> #include "arch/apr_private_common.h"
>
> instead of
>
> #include "../apr_private_common.h"
>
> in the generated arch/unix/apr_private.h.in.
>
> Maybe someone has an idea?

The below seems to do it (and pass `make check` for me):

Index: configure.in
===
--- configure.in(revision 1910349)
+++ configure.in(working copy)
@@ -100,7 +100,7 @@ AH_BOTTOM([
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"
 #endif /* APR_PRIVATE_H */
 ])

Index: include/arch/netware/apr_private.h
===
--- include/arch/netware/apr_private.h(revision 1910349)
+++ include/arch/netware/apr_private.h(working copy)
@@ -199,7 +199,7 @@ void* getStatCache();
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"

 #endif  /*APR_PRIVATE_H*/
 #endif  /*NETWARE*/
Index: include/arch/win32/apr_private.h
===
--- include/arch/win32/apr_private.h(revision 1910349)
+++ include/arch/win32/apr_private.h(working copy)
@@ -169,7 +169,7 @@ APR_DECLARE_DATA int errno;
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"

 #endif  /*APR_PRIVATE_H*/
 #endif  /*WIN32*/
--


Regards;
Yann.


Re: svn commit: r1912607 - in /apr/apr/trunk: ./ .github/workflows/ build/ dbm/ include/ include/private/ test/

2023-10-02 Thread Yann Ylavic
On Fri, Sep 29, 2023 at 3:39 PM  wrote:
>
> Author: jorton
> Date: Fri Sep 29 13:39:11 2023
> New Revision: 1912607
[]
> --- apr/apr/trunk/dbm/apr_dbm_lmdb.c (added)
> +++ apr/apr/trunk/dbm/apr_dbm_lmdb.c Fri Sep 29 13:39:11 2023
[]
> +static apr_status_t vt_lmdb_open(apr_dbm_t **pdb, const char *pathname,
> + apr_int32_t mode, apr_fileperms_t perm,
> + apr_pool_t *pool)
> +{
[]
> +{
> +int dberr;
> +file.txn = NULL;
> +file.cursor = NULL;
> +
> +if ((dberr = mdb_env_create()) == 0) {
> +//XXX: properly set db size
> +if ((dberr = mdb_env_set_mapsize(file.env, UINT32_MAX)) == 0){
> +if ((dberr = mdb_env_open(file.env, pathname, dbmode | 
> DEFAULT_ENV_FLAGS, apr_posix_perms2mode(perm))) == 0) {
> +if ((dberr = mdb_txn_begin(file.env, NULL, dbmode, 
> )) == 0){
> +if ((dberr = mdb_dbi_open(file.txn, NULL, 
> dbi_open_flags, )) != 0){
> +/* close the env handler */
> +mdb_env_close(file.env);
> +}
> +}
> +}
> +}
> +}
> +
> +if (truncate){
> +if ((dberr = mdb_drop(file.txn, file.dbi, 0)) != 0){
> +mdb_env_close(file.env);
> +}
> +}
> +
> +if (dberr != 0)
> +return db2s(dberr);
> +}

This seems to potentially double-close or leak "file.env" on some
errors, maybe write it like the below instead?

dberr = mdb_env_create();
if (dberr != 0) {
return db2s(dberr);
}
dberr = ...;
if (dberr == 0) {
dberr = ...;
}
dberr = ...;
if (dberr == 0) {
dberr = ...;
}
...
if (dberr == 0) {
dberr = mdb_dbi_open(file.txn, NULL, dbi_open_flags, );
if (dberr == 0 && truncate) {
dberr = mdb_drop(file.txn, file.dbi, 0);
if (dberr != 0) {
mdb_dbi_close(file.env, file.dbi);
}
}
}
if (dberr != 0) {
mdb_env_close(file.env);
return db2s(dberr);
}

> +
> +/* we have an open database... return it */
> +*pdb = apr_pcalloc(pool, sizeof(**pdb));
> +(*pdb)->pool = pool;
> +(*pdb)->type = _dbm_type_lmdb;
> +(*pdb)->file = apr_pmemdup(pool, , sizeof(file));
> +
> +/* ### register a cleanup to close the DBM? */
> +
> +return APR_SUCCESS;
> +}
> +
> +static void vt_lmdb_close(apr_dbm_t *dbm)
> +{
> +real_file_t *f = dbm->file;
> +
> +if (f->cursor){
> +mdb_cursor_close(f->cursor);
> +f->cursor = NULL;
> +}
> +
> +if (f->txn){
> +   mdb_txn_commit(f->txn);
> +   f->txn = NULL;
> +}

Shouldn't we abort the transaction here if there was no explicit
commit (store/del) previously?
In any case, the docs[1] for commit/abort seem to say that both
invalidate the ->cursor, so maybe we want to write this like:

   if (f->txn){
   mdb_txn_{commit,abort}(f->txn);
   f->txn = NULL;
   f->cursor = NULL;
   }
   if (f->cursor){
   mdb_cursor_close(f->cursor);
   f->cursor = NULL;
   }

?
[1] http://www.lmdb.tech/doc/group__mdb.html#ga846fbd6f46105617ac9f4d76476f6597

> +
> +mdb_dbi_close(f->env, f->dbi);
> +mdb_env_close(f->env);
> +
> +f->env = NULL;
> +f->dbi = 0;
> +}
[]
> +static apr_status_t vt_lmdb_store(apr_dbm_t *dbm, apr_datum_t key,
> +  apr_datum_t value)
> +{
> +real_file_t *f = dbm->file;
> +int rv;
> +MDB_val ckey = { 0 };
> +MDB_val cvalue = { 0 };
> +
> +ckey.mv_data = key.dptr;
> +ckey.mv_size = key.dsize;
> +
> +cvalue.mv_data = value.dptr;
> +cvalue.mv_size = value.dsize;
> +
> +if ((rv = mdb_put(f->txn, f->dbi, , , 0)) == 0) {
> +/* commit transaction */
> +if (((rv = mdb_txn_commit(f->txn)) == MDB_SUCCESS)
> +&& ((rv = mdb_txn_begin(f->env, NULL, 0, >txn)) == 
> MDB_SUCCESS)) {
> +f->cursor = NULL;
> +}

AIUI, f->cursor should be reset whether or not mdb_txn_begin()
succeeds here, and f->txn if any of _commit() or _begin() fails?

> +}
> +
> +/* store any error info into DBM, and return a status code. */
> +return set_error(dbm, rv);
> +}
> +
> +static apr_status_t vt_lmdb_del(apr_dbm_t *dbm, apr_datum_t key)
> +{
> +real_file_t *f = dbm->file;
> +int rv;
> +MDB_val ckey = { 0 };
> +
> +ckey.mv_data = key.dptr;
> +ckey.mv_size = key.dsize;
> +
> +if ((rv = mdb_del(f->txn, f->dbi, , NULL)) == 0) {
> +/* commit transaction */
> +if (((rv = mdb_txn_commit(f->txn)) == MDB_SUCCESS)
> +&& ((rv = mdb_txn_begin(f->env, NULL, 0, >txn)) == 
> MDB_SUCCESS)) {
> +f->cursor = NULL;
> +}

Likewise for f->cursor and f->txn resetting.

> +}
> +
> +/* store any error info into DBM, and 

Re: [VOTE] Release apr-1.7.4-rc1 as apr-1.7.4

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 1:08 PM Yann Ylavic  wrote:
>
> On Thu, Apr 13, 2023 at 1:02 PM Eric Covener  wrote:
> >
> > New for this release we are only toggling it on the release tag (sic), 
> > similar to httpd release process.
>
> Maybe a bump (to 1.7.5 here) is missing in 1.7.x after tagging now?
> Currently apr_version.h is still at 1.7.4-dev it seems.

Nevermind, this probably happens when the release is accepted..


Re: [VOTE] Release apr-1.7.4-rc1 as apr-1.7.4

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 4:25 AM Eric Covener  wrote:
>
> I would like to call a VOTE over the next few days to release
> this candidate tarball apr-1.7.4-rc1 as 1.7.4:

[X] +1: It's not just good, it's good enough!

All tests pass on Debian 11 and 12, sums/sigs/version/dirname OK.

Thanks Eric for RMing!


Re: [VOTE] Release apr-1.7.4-rc1 as apr-1.7.4

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 1:02 PM Eric Covener  wrote:
>
> New for this release we are only toggling it on the release tag (sic), 
> similar to httpd release process.

Maybe a bump (to 1.7.5 here) is missing in 1.7.x after tagging now?
Currently apr_version.h is still at 1.7.4-dev it seems.


Re: [VOTE] Release apr-1.7.4-rc1 as apr-1.7.4

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 12:16 PM SteffenAL  wrote:
>
> it's me.  I build from svn, and there is :
>
> #define APR_IS_DEV_VERSION

Yeah, this is restored immediately after tagging to not let a branch
in a "release" state.
You could checkout tags/apr-1.7.4-rc1 rather than branches/1.7.x for
testing, the vote is about the tarballs but I suppose testing the tag
is fine too if it helps (maybe related with Windows' CRLF vs tarball's
LF in the source files in your case..).


Regards;
Yann.


Re: Release APR 1.7.4?

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 12:15 PM Evgeny Kotkov
 wrote:
>
> Yann Ylavic  writes:
>
> > Do we want to include r1909117 in 1.7.4 (to call abort() instead of
> > assert() in apr_base64 when NDEBUG)?
> > Sorry for the lateness, but should there be an -rc2 (or in any case..).
>
> If I recall correctly, APR 1.7.x doesn't have apr_base64, because it is a
> part of APR-util in that timeline.

Ah yes sorry for the noise, I keep forgetting which ones are in apr or
in apr-util :)


Regards;
Yann.


Re: Release APR 1.7.4?

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 10:47 AM Evgeny Kotkov via dev
 wrote:
>
> Eric Covener  writes:
>
> > I will RM but it might be a bit piecemeal between now and the weekend.
> >   At the mercy of a lot of inflexible $bigco stuff.
> >
> > Hoping to improve a little this time by porting more of icings amazing
> > httpd release work.
>
> Awesome, thanks!

Do we want to include r1909117 in 1.7.4 (to call abort() instead of
assert() in apr_base64 when NDEBUG)?
Sorry for the lateness, but should there be an -rc2 (or in any case..).


Regards;
Yann.


Re: [VOTE] Release apr-1.7.4-rc1 as apr-1.7.4

2023-04-13 Thread Yann Ylavic
On Thu, Apr 13, 2023 at 9:38 AM SteffenAL  wrote:
>
> It is identified as 1.7.4-dev
>
> In apr_version.h dev version is defined.

I don't see this in the release candidate tarballs (.gz or .bz2),
apr_version.h contains:
/* #undef APR_IS_DEV_VERSION */
so it should not include the "-dev" suffix in APR_VERSION_STRING.
Likewise here: 
https://github.com/apache/apr/blob/1.7.4-rc1-candidate/include/apr_version.h#L72

Could it be from a local /D of yours or something?


Regards;
Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2023-03-29 Thread Yann Ylavic
On Wed, Mar 29, 2023 at 1:04 PM Evgeny Kotkov via dev
 wrote:
>
> Yann Ylavic  writes:
>
> > +#undef NDEBUG /* always abort() on assert()ion failure */
> > +#include 
>
> Sorry for being late to the party, but I think there are a few problems with
> the "#undef NDEBUG" line:
>
> 1) The debug implementation of an assert() may print a diagnostic message,
> for example to stderr.  A caller of the library function may not be ready for
> this to happen when using a non-debug version of the library.
>
> 2) The actual destination of the message seems to be implementation-defined.
> For example, in Windows-based applications this may show a message box [1],
> which is probably even more unexpected for the user of the library.
>
> 3) Undefining NDEBUG before other headers may silently cause unexpected
> effects if any of those headers make some decisions based on the NDEBUG value,
> which isn't an entirely unreasonable thing to expect.

Fair points, the system printing (the faulting code) or not by default
before abort() should be #ifdef'd then? Depend on NDEBUG or an
APR_ABORT_USE_STDERR alike?
I'm not sure what the right default is though, ISTM that using system
printing before abort() for a portable [system] lib is not delusional.
This works well for users that can afford to let std outputs go or
handle/redirect them (e.g. httpd including when running as a Windows
service where the error could go to a journal/eventlog?), and an
abort() can be hard to diagnose without a message (and without a
coredump/backtrace).
Using a build time toggle does not necessarily help by the way when
all you have is an apr built by a distro/vendor (no NDEBUG set in
Debian it seems for instance).
Faulting silently by default looks harsh to me, there is no precedent
on apr abort()ing explicitly so there is no legacy behaviour to
preserve IMO. But not a strong opinion provided there is a #define'd.

>
> So, depending on whether we want the checks to soft- or hard-fault, maybe we
> could either remove the "#undef NDEBUG" line, or switch to a custom check that
> explicitly calls an abort()?

If we let some user-defined NDEBUG fly through apr_base64.c the code
will never abort(), which we always want for this int/size overflow
UB.
So possibly something like the below:

Index: encoding/apr_base64.c
===
--- encoding/apr_base64.c(revision 1908764)
+++ encoding/apr_base64.c(working copy)
@@ -20,8 +20,27 @@
  * ugly 'len' functions, which is quite a nasty cost.
  */

-#undef NDEBUG /* always abort() on assert()ion failure */
+/* An APR__ASSERT()ion failure will abort() with or without printing
+ * the faulting condition (and code location) depending on NDEBUG.
+ */
+#ifndef NDEBUG  /* use assert()/system's printing before abort() mechanism */
 #include 
+#define APR__ASSERT(cond) assert(cond)
+#else   /* just abort() */
+#if APR_HAVE_STDLIB_H
+#include 
+#endif
+#if HAVE___BUILTIN_EXPECT
+#define APR__UNLIKELY(cond) __builtin_expect(!!(cond), 0)
+#else
+#define APR__UNLIKELY(cond) (!!(cond))
+#endif
+#define APR__ASSERT(cond) do { \
+if (APR__UNLIKELY(!(cond))) { \
+abort(); \
+} \
+} while (0)
+#endif

 #include "apr_base64.h"
 #if APR_CHARSET_EBCDIC
@@ -124,7 +143,7 @@ APR_DECLARE(int) apr_base64_decode_len(const char
 bufin = (const unsigned char *) bufcoded;
 while (pr2six[*(bufin++)] <= 63);
 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
-assert(nprbytes <= APR_BASE64_DECODE_MAX);
+APR__ASSERT(nprbytes <= APR_BASE64_DECODE_MAX);

 return (int)(((nprbytes + 3u) / 4u) * 3u + 1u);
 }
@@ -161,7 +180,7 @@ APR_DECLARE(int) apr_base64_decode_binary(unsigned
 bufin = (const unsigned char *) bufcoded;
 while (pr2six[*(bufin++)] <= 63);
 nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
-assert(nprbytes <= APR_BASE64_DECODE_MAX);
+APR__ASSERT(nprbytes <= APR_BASE64_DECODE_MAX);
 nbytesdecoded = (int)(((nprbytes + 3u) / 4u) * 3u);

 bufout = (unsigned char *) bufplain;
@@ -206,7 +225,7 @@ static const char basis_64[] =

 APR_DECLARE(int) apr_base64_encode_len(int len)
 {
-assert(len >= 0 && len <= APR_BASE64_ENCODE_MAX);
+APR__ASSERT(len >= 0 && len <= APR_BASE64_ENCODE_MAX);

 return ((len + 2) / 3 * 4) + 1;
 }
@@ -219,7 +238,7 @@ APR_DECLARE(int) apr_base64_encode(char *encoded,
 int i;
 char *p;

-assert(len >= 0 && len <= APR_BASE64_ENCODE_MAX);
+APR__ASSERT(len >= 0 && len <= APR_BASE64_ENCODE_MAX);

 p = encoded;
 for (i = 0; i < len - 2; i += 3) {
@@ -258,7 +277,7 @@ APR_DECLARE(int) apr_base64_encode_binary(char *en
 int i;
 char *p;

-assert(len >= 0 && len <= APR_BASE64_ENCODE_MAX);
+APR__ASSERT(len >= 0 && len &

Re: svn commit: r1908503 - in /apr/apr/trunk: build/crypto.m4 crypto/apr_crypto_openssl.c

2023-03-27 Thread Yann Ylavic
Hi Rainer;

On Mon, Mar 27, 2023 at 2:02 PM Rainer Jung  wrote:
>
> Am 18.03.23 um 17:33 schrieb yla...@apache.org:
> >
> > @@ -113,15 +112,13 @@ AC_DEFUN([APU_CHECK_CRYPTO_OPENSSL], [
> > AC_MSG_NOTICE(checking for openssl in $withval)
> > AC_CHECK_HEADERS(openssl/x509.h, [openssl_have_headers=1])
> > AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_new, openssl_have_libs=1)
> > -  if test "$openssl_have_headers" != "0" && test "$openssl_have_libs" 
> > != "0"; then
> > +  if test "$openssl_have_headers" = "1" && test "$openssl_have_libs" = 
> > "1"; then
> >   apu_have_openssl=1
> > -APR_ADDTO(LDFLAGS, [-L$withval/lib])
> > -APR_ADDTO(INCLUDES, [-I$withval/include])
>  > fi
>  > -
>  > -  AC_CHECK_DECLS([EVP_PKEY_CTX_new, OPENSSL_init_crypto], [], [],
>  > - [#include ])
>  > -
>  > +fi
>  > +if test "$apu_have_openssl" = "1"; then
>  > +AC_CHECK_LIB(crypto, OPENSSL_init_crypto)
>  > +AC_CHECK_FUNCS([OPENSSL_init_crypto])
>  >   fi
>
> Hmmm, for me this dropped "APR_ADDTO(INCLUDES,..." breaks the apr trunk
> build. The path to the OpenSSL header files gets no longer added to any
> INCLUDES variable for the build.

Ah yes, I thought both LDFLAGS and INCLUDES were already set above but
it is LDFLAGS and CPPFLAGS actually.
Restored in r1908749.

Thanks!
Yann.


Re: [VOTE] Release apr-1.7.3

2023-03-27 Thread Yann Ylavic
On Mon, Mar 27, 2023 at 10:18 AM Ruediger Pluem  wrote:
>
> 1.7.3-rc1 is here:
>
> https://apr.apache.org/dev/dist/
>
> For the release of apr-1.7.3

[X]  +1 looks great!

Tested on Debian 11 and 12.
All good with:
  apr_lock_method=USE_PROC_PTHREAD_SERIALIZE
  --enable-nonportable-atomics=yes
  --enable-posix-shm

Digests and sigs are OK, and directory name is w/o the -rc.

Thanks Rüdiger for RMing!


Re: Release APR 1.7.3 ?

2023-03-24 Thread Yann Ylavic
On Fri, Mar 24, 2023 at 3:56 PM Ruediger Pluem  wrote:
>
> Is someone opposed if I put an APR 1.7.x release for vote on the beginning of 
> next week?
> It would be my first APR release, but I think I should be able to do it with 
> the instructions in release.sh (thanks Eric).
> Otherwise I will ask here for help.
>
> We had a regression in apr-1-config that is now fixed and we have some nice 
> fixes / improvements for Windows.
> I know that people think of releasing 1.8., but another 1.7 release seems to 
> be the lower hanging fruit.

+1, the atomic64 changes are worth shipping ASAP too.


Regards;
Yann.


Re: svn commit: r1906889 - in /apr/apr/trunk: ./ build/ include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2023-03-21 Thread Yann Ylavic
On Tue, Mar 21, 2023 at 2:24 PM Yann Ylavic  wrote:
>
> Is there something I can #ifdef (or check at configure/run time) for
> SLELS11 or the kernel? This would document in the test that a minimal
> timeout is usually expected, but on this platform/kernel. Or I'll use
> 190ms for everyone, which looks "unfair".

Does r1908616 work for you?

>
> Regards;
> Yann.


Re: svn commit: r1906889 - in /apr/apr/trunk: ./ build/ include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2023-03-21 Thread Yann Ylavic
Hi Rainer;

On Mon, Mar 20, 2023 at 10:31 PM Rainer Jung  wrote:
>
> Am 17.03.23 um 15:11 schrieb Yann Ylavic:
> >
> > Hm OK, these commits were meant to address that precisely..
> > It looks like SLES has some special epoll_wait() implementation that
> > can return before the timeout. Could you printf the t2 - t1 diff in
> > the justsleep() test after apr_pollset_poll()? It could be interesting
> > to know if it's almost 200ms or close to zero (the latter could mean
> > epoll_wait() does not block if there is no fd in the pollset, which is
> > the case in this test).
>
> The observed time delta on this platform is between 197 and 198.5 ms
> instead of somewhat above 200ms. I should note it is an old patch level
> of SLES 11 using kernel 2.6.32.12-0.7.
>
> There are some old informations about the rounding of the timeout:
>
> https://linux-fsdevel.vger.kernel.narkive.com/9jp0o6FA/bug-epoll-wait-timeout-is-shorter-than-requested

Thanks for looking. Well, it seems that there is no guarantee of a
minimal timeout on this system.
There is something fishy though, the only change w.r.t. before is the
millisecond round _up_..

>
> On this system HZ is 100, so a jiffie is 10ms and probably this means it
> should suffice to accept 200-10=190ms as the minimum sleep time.

Is there something I can #ifdef (or check at configure/run time) for
SLELS11 or the kernel? This would document in the test that a minimal
timeout is usually expected, but on this platform/kernel. Or I'll use
190ms for everyone, which looks "unfair".


Regards;
Yann.


Re: svn commit: r1908433 - in /apr/apr/trunk: crypto/apr_crypto_openssl.c test/testcrypto.c

2023-03-17 Thread Yann Ylavic
On Fri, Mar 17, 2023 at 9:23 AM Ruediger Pluem  wrote:
>
> On 3/16/23 1:43 PM, yla...@apache.org wrote:
> > Author: ylavic
> > Date: Thu Mar 16 12:43:17 2023
> > New Revision: 1908433
> >
> > URL: http://svn.apache.org/viewvc?rev=1908433=rev
> > Log:
> > apr_crypto_openssl: Compatibility with OpenSSL 3+
> >
> > Modified:
> > apr/apr/trunk/crypto/apr_crypto_openssl.c
> > apr/apr/trunk/test/testcrypto.c
> >
> > Modified: apr/apr/trunk/crypto/apr_crypto_openssl.c
> > URL: 
> > http://svn.apache.org/viewvc/apr/apr/trunk/crypto/apr_crypto_openssl.c?rev=1908433=1908432=1908433=diff
> > ==
> > --- apr/apr/trunk/crypto/apr_crypto_openssl.c (original)
> > +++ apr/apr/trunk/crypto/apr_crypto_openssl.c Thu Mar 16 12:43:17 2023
> > @@ -32,6 +32,10 @@
> >
> >  #if APU_HAVE_CRYPTO
> >
> > +#ifndef OPENSSL_API_COMPAT
> > +#define OPENSSL_API_COMPAT 0x1010L /* for ENGINE API */
> > +#endif
>
> On RedHat 8 with openssl 1.1.1k this causes openssl/err.h which is included 
> openssl/engine.h to
> no longer define the noop macro ERR_free_strings and thus causing the 
> compilation to fail.
> Removing the above makes this go away. Why do we need to set it?

Hm, ERR_free_strings() shouldn't be used with openssl-1.1.1
(HAVE_DECL_OPENSSL_INIT_CRYPTO)?

OPENSSL_API_COMPAT is needed to avoid the warnings for the ENGINE api
with openssl >= 3, and moving to the new API (providers) is quite some
work FWICT. I thought it was a good compromise for now (and plan to do
the same thing for httpd FWIW), using the new API for what can be done
easily enough and setting OPENSSL_API_COMPAT for the rest (that is
mainly ENGINE..).

>
> > +#if !APR_USE_OPENSSL_PRE_3_0_API
> > +EVP_MAC *mac;
> > +#endif
>
> It looks like the usage of this field is not appropriately #If ed later on as 
> I get compilation failures like
>
> crypto/apr_crypto_openssl.c: In function ‘crypto_key_cleanup’:
> crypto/apr_crypto_openssl.c:301:12: error: ‘apr_crypto_key_t’ {aka ‘struct 
> apr_crypto_key_t’} has no member named ‘mac’
>  if (key->mac) {
[]
>
> crypto/apr_crypto_openssl.c: In function ‘crypto_digest_cleanup’:
> crypto/apr_crypto_openssl.c:355:14: error: ‘apr_crypto_digest_t’ {aka ‘struct 
> apr_crypto_digest_t’} has no member named ‘macCtx’;
> did you mean ‘mdCtx’?
>  if (ctx->macCtx) {

Should be good with now r1908448.


Regards;
Yann.


Re: svn commit: r1908433 - in /apr/apr/trunk: crypto/apr_crypto_openssl.c test/testcrypto.c

2023-03-17 Thread Yann Ylavic
On Thu, Mar 16, 2023 at 5:53 PM Ruediger Pluem  wrote:
>
> On 3/16/23 1:43 PM, yla...@apache.org wrote:
> > Author: ylavic
> > Date: Thu Mar 16 12:43:17 2023
> > New Revision: 1908433
> >
> > URL: http://svn.apache.org/viewvc?rev=1908433=rev
> > Log:
> > apr_crypto_openssl: Compatibility with OpenSSL 3+
> >
> > Modified:
> > apr/apr/trunk/crypto/apr_crypto_openssl.c
> > apr/apr/trunk/test/testcrypto.c
>
> Why don't we need to call crypto_digest_cleanup any longer? Does the pool 
> cleanup take of this now?

Cleanups were a bit scattered over normal/error exit codes while a
cleanup was always registered.
I missed that apr_crypto_block_t or apr_crypto_digest_t could be
reused in _init() though, so removing some cleanups here was leaky on
reuse.
I find it simpler/cleaner to do the cleanup or alloc+register in
_init() depending on reuse or not (respectively), so I did that in
r1908453 rather than restoring the cleanups as before.

Regards;
Yann.


Re: svn commit: r1906889 - in /apr/apr/trunk: ./ build/ include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2023-03-17 Thread Yann Ylavic
On Fri, Mar 17, 2023 at 2:30 PM Rainer Jung  wrote:
>
> Am 17.03.23 um 14:12 schrieb Yann Ylavic:
> > On Fri, Mar 17, 2023 at 11:20 AM Rainer Jung  
> > wrote:
> >>
> >> But: testpoll fails:
> >>
> >> testpoll:  Line 897: apr_pollset_poll() didn't sleep
> >>
> >> Unfortunately I don't know when it started. Any idea, what I should
> >> investigate?
> >>
> >> All this is on SLES11, haven't tried the recent APR trunk with newer
> >> Linuxes, but r1908005 worked on them including testpoll tests.
> >
> > I suppose SLES11 is using epoll implementation, so r1902236 and
> > r1902258 may help.
> > Does your APR contain those?
> >
> > Regards;
> > Yann.
>
> Yes, it contained everything until r1908442.

Hm OK, these commits were meant to address that precisely..
It looks like SLES has some special epoll_wait() implementation that
can return before the timeout. Could you printf the t2 - t1 diff in
the justsleep() test after apr_pollset_poll()? It could be interesting
to know if it's almost 200ms or close to zero (the latter could mean
epoll_wait() does not block if there is no fd in the pollset, which is
the case in this test).

Regards;
Yann.


Re: svn commit: r1906889 - in /apr/apr/trunk: ./ build/ include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2023-03-17 Thread Yann Ylavic
On Fri, Mar 17, 2023 at 11:20 AM Rainer Jung  wrote:
>
> But: testpoll fails:
>
> testpoll:  Line 897: apr_pollset_poll() didn't sleep
>
> Unfortunately I don't know when it started. Any idea, what I should
> investigate?
>
> All this is on SLES11, haven't tried the recent APR trunk with newer
> Linuxes, but r1908005 worked on them including testpoll tests.

I suppose SLES11 is using epoll implementation, so r1902236 and
r1902258 may help.
Does your APR contain those?

Regards;
Yann.


Re: svn commit: r1906889 - in /apr/apr/trunk: ./ build/ include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2023-03-16 Thread Yann Ylavic
On Thu, Mar 16, 2023 at 2:53 PM Ivan Zhakov  wrote:
>
> I have very little knowledge about autoconf stuff. The autoconf part was 
> suggest by Yann in [1]
>
> Yann: do you have any ideas why it does not work?

Does r1908438 fix it for you Rainer?

Regards;
Yann.


Re: Problems with atomics in 1.7.2

2023-02-14 Thread Yann Ylavic
Hi Stefan;

On Sun, Feb 5, 2023 at 9:44 PM Stefan Fritsch  wrote:
>
>
> On powerpc we got a segfault:
[]
> Fixed in http://svn.apache.org/viewvc?view=revision=1907442 .
[]
>
> On armel, we got a link error:
>
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to
> `__atomic_fetch_sub_8'
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to `__atomic_load_8'
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to
> `__atomic_exchange_8'
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to `__atomic_store_8'
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to
> `__atomic_fetch_add_8'
> /usr/bin/ld: ../.libs/libapr-1.so: undefined reference to
> `__atomic_compare_exchange_8'
>
> Build log at
> https://buildd.debian.org/status/logs.php?pkg=apr=armel=sid
> Fixed in http://svn.apache.org/viewvc?view=revision=1907441

Thanks!

>
>
> However, even with both fixes, there still seem to be problems. On
> powerpc, there was the same test failure as in PR 66457:
> testatomic: Line 908: Unexpected value
>
> Log at
> https://buildd.debian.org/status/fetch.php?pkg=apr=powerpc=1.7.2-2=1675512084=0

Fixed in http://svn.apache.org/r1907541

>
> If I am not mistaken, on 32 bit architectures you always need to ensure
> manually that both halves of a 64 bit value are written atomically. So
> code like this
>
> apr_atomic_set64()
> ...
> *mem = val;
>
> seems wrong.
>
> Also, this construct
>
> #if defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__)
> #define WEAK_MEMORY_ORDERING 1
> #else
> #define WEAK_MEMORY_ORDERING 0
> #endif
>
> seems to be very fragile.

I think we have several issues here:
1. we should set WEAK_MEMORY_ORDERING for anything but __i386__,
__x86_64__, __s390__ and __s390x__
2. we should not use direct 64bit load/store on 32bit systems for
atomic operations
3. on 32bit systems the alignment for an uint64_t is usually 4 (not 8
like on a 64bit systems), which hurts (at best) or prevents atomicity
even with builtins.

For 1. and 2. the generic/mutex case was addressed in r1907541
(apr_atomic_set64() was doing the right thing already), and the
builtins case is addressed in r1907637 (hopefully).
Windows code is also concerned but I believe it's doing the right
thing already by checking _M_X64 (x86_64 CPU) or should we check for
_WIN64 too (or APR_SIZEOF_VOIDP >= 8) for WIN32 running on x64? What
about the alignment of uint64_t on WIN32, the Interlocked*64()
functions seem to require 8-byte alignment so should we fall back to
generic/mutex on WIN32 too?

For 3., r1907642 should now take care of the alignment to define (or
not) HAVE_ATOMIC_BUILTINS64 and HAVE__ATOMIC_BUILTINS64, with a
fallback to USE_ATOMICS_GENERIC for cases where it matters. This was
tested by looking at the (32bit) assembly generated for different
compilers/options/builtins here: https://godbolt.org/z/r4daf6b4v
(comment in/out some "__attribute__((aligned(8)))" and/or "&& 0" to
see what helps or not).
Notably, while both gcc and clang seem to implement the same kind of
compare-and-swap loop for _read64 and _set64 with -m32 and the legacy
__sync_* builtins, they seem to disagree on whether __atomic builtins
should defer to libatomic (thus possibly mutex) when an uint64_t is
not 8-byte aligned. gcc will use some x87/FPU instructions
(fild/fistp) regardless of the alignment whereas clang will issue
calls to libatomic whenever apr_uint64_t is not forcibly 8-byte
aligned.
Dunno who's correct here (whether x87 instructions work with 4-byte
alignment, CPU cacheline crossing and so on..), but this seems to beg
for a forced "typedef uint64_t apr_uint64_t
__attribute__((aligned(8)));" (an ABI change) or a new API for 64bit
atomics (with properly aligned apr_atomic_u64_t) on the APR side
anyway to do the right thing on 32bit systems..
For now (after r1907642) this means that compiling a 32bit APR will
USE_ATOMICS_BUILTINS64 with gcc and NEED_ATOMICS_GENERIC64 with clang.

Does this all work for you?

Finally it seems that both -march=i[56]86 (but not i[34]86) provide
the same atomic builtins too (with gcc), so maybe we could use them
instead of the forced generic/mutex implementation (currently) if it's
how distros build 32bit APR (per
https://bz.apache.org/bugzilla/show_bug.cgi?id=66457). So I think
something like this would be fine:

Index: configure.in
===
--- configure.in(revision 1907642)
+++ configure.in(working copy)
@@ -566,6 +566,9 @@ if test "$ap_cv_atomic_builtins" = "yes" -o "$ap_c
 if test "$ap_cv__atomic_builtins" = "yes"; then
 AC_DEFINE(HAVE__ATOMIC_BUILTINS, 1, [Define if compiler
provides 32bit __atomic builtins])
 fi
+has_atomic_builtins=yes
+else
+has_atomic_builtins=no
 fi

 AC_CACHE_CHECK([whether the compiler provides 64bit atomic builtins],
[ap_cv_atomic_builtins64],
@@ -829,10 +832,15 @@ AC_ARG_ENABLE(nonportable-atomics,
force_generic_atomics=yes
  fi
 ],
-[case $host_cpu in
-   

Re: [VOTE] apr 1.7.2 and apr-util 1.6.3

2023-02-01 Thread Yann Ylavic
On Tue, Jan 31, 2023 at 10:23 PM Eric Covener  wrote:
>
> I hosed 1.7.1/1.6.2 and the archives have -rcX in them at the top
> level.  I would like to call for an expedited vote to replace them
> with version bumps.  I will proceed once we get 3 binding +1.
>
> I have re-tagged because I think the consensus will be that updating
> the tarballs and signatures is too confusing.
>
> candidates are here:
>
> https://apr.apache.org/dev/dist/
>
> For the release of apr-1.7.2 AND apr-util-1.6.3

+1 to both, big thanks Eric!

Regards;
Yann.


Re: VOTE: Release apr-1.7.1-rc2 as 1.7.1

2023-01-29 Thread Yann Ylavic
Argh, this vote was actually meant for apr-util-1.6.2-rc2 :/
Nevermind, my +1 for apr-util-1.6.2-rc3 on the other thread anyway.

On Wed, Jan 25, 2023 at 4:10 PM Yann Ylavic  wrote:
>
> On Fri, Jan 20, 2023 at 1:44 AM Eric Covener  wrote:
> >
> > 1.7.1-rc1 is here:
> >
> > https://apr.apache.org/dev/dist/
> >
> > For the release of apr-1.7.1
>
> [X]  +1 looks great!
>
> Testing on Debian 11 and 12+ (bookwork/sid) using apr-1.7.1(-rc2).
>
> No test failure, checksum/signature ok.
>
> Thanks Eric!
>
> Regards;
> Yann.


Re: [VOTE] release apr-1.6.2-rc3 as APR 1.6.2

2023-01-29 Thread Yann Ylavic
On Fri, Jan 27, 2023 at 2:42 PM Eric Covener  wrote:
>
> 1.6.2-rc3 is here:
>
> https://apr.apache.org/dev/dist/
>
> For the release of apr-util-1.6.2

[X]  +1 looks great

Debian 11 & 12. Did not test the new mariadb bits specifically.

Thanks Eric.

Regards;
Yann.


Re: VOTE: Release apr-1.7.1-rc2 as 1.7.1

2023-01-25 Thread Yann Ylavic
On Fri, Jan 20, 2023 at 1:44 AM Eric Covener  wrote:
>
> 1.7.1-rc1 is here:
>
> https://apr.apache.org/dev/dist/
>
> For the release of apr-1.7.1

[X]  +1 looks great!

Testing on Debian 11 and 12+ (bookwork/sid) using apr-1.7.1(-rc2).

No test failure, checksum/signature ok.

Thanks Eric!

Regards;
Yann.


Re: VOTE: Release apr-1.7.1-rc2 as 1.7.1

2023-01-23 Thread Yann Ylavic
On Fri, Jan 20, 2023 at 1:44 AM Eric Covener  wrote:
>
> For the release of apr-1.7.1

[X]  +1 looks great!

apr-1.7.1-rc2 tested on Debian 11 and 12+ (bookwork/sid).
All good with:
  apr_lock_method=USE_PROC_PTHREAD_SERIALIZE
  --enable-nonportable-atomics=yes
  --enable-posix-shm

Thanks a lot Eric for RMing!

Regards;
Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2022-10-17 Thread Yann Ylavic
On Mon, Jul 25, 2022 at 12:43 PM Ruediger Pluem  wrote:
>
>
>
> On 6/23/22 8:49 PM, Ruediger Pluem wrote:
> >
> >
> > On 6/23/22 5:12 PM, yla...@apache.org wrote:
> >> Author: ylavic
> >> Date: Thu Jun 23 15:12:47 2022
> >> New Revision: 1902206
> >
> >
> >> @@ -275,16 +284,17 @@ APR_DECLARE(int) apr_base64_encode_binar
> >>  }
> >>
> >>  *p++ = '\0';
> >> -return (int)(p - encoded);
> >> +return (unsigned int)(p - encoded);
> >>  }
> >>
> >>  APR_DECLARE(char *) apr_pbase64_encode(apr_pool_t *p, const char *string)
> >>  {
> >>  char *encoded;
> >> -int l = strlen(string);
> >> +apr_size_t len = strlen(string);
> >>
> >> -encoded = (char *) apr_palloc(p, apr_base64_encode_len(l));
> >> -apr_base64_encode(encoded, string, l);
> >> +assert(len <= (apr_size_t)APR_INT32_MAX);
> >
> > Shouldn't this be INT_MAX or APR_BASE64_ENCODE_MAX?
>
> Any update on this comment? I guess INT_MAX or APR_INT32_MAX is mood given 
> the result of the discussion in this thread, but it
> probably should be APR_BASE64_ENCODE_MAX?

Good point, r1904666.

>
> >
> >> +encoded = (char *) apr_palloc(p, apr_base64_encode_len((int)len));
> >> +apr_base64_encode(encoded, string, (int)len);
> >>
> >>  return encoded;
> >>  }


Regards;
Yann.


Re: Issues with shipping apr_thread_current() in APR 1.8.0 and an alternative approach for PCRE2 allocations in HTTPD

2022-07-12 Thread Yann Ylavic
On Tue, Jul 12, 2022 at 12:46 PM Ivan Zhakov  wrote:
>
> On Wed, 29 Jun 2022 at 01:28, Yann Ylavic  wrote:
> >
> > On Tue, Jun 28, 2022 at 6:08 PM Ivan Zhakov  wrote:
> > > >
> > > I meant a memory leak for native threads. For example, with an MPM
> > > that uses native Windows threadpool for worker threads.
> >
> > That's not mpm_winnt right? (it does not use native threads anymore
> > and plays no apr_thread_current_create() game, it just uses
> > apr_thread_create() so apr_thread_current() works automatically
> > there).
>
> No, it's not mpm_winnt, but still a possible real-world example. And there
> are multiple other users of APR besides the HTTP Server.

So we have a hypothetical issue for what exactly? Someone will be
using the new ap_thread API (or future APR one) for something that it
can't be used for?

>
> >
> > Probably the thread pool lets you pass the thread function? So you
> > could "apr_thread_current_create()" when entering the
> > function and "apr_pool_destroy(apr_thread_pool_get(mythread))" before
> > leaving?
> > That'd still leak if the thread calls TerminateThread() explicitly at
> > some point, but it seems that the native Windows thread API is not
> > very helpful for that since there is way to register a destructor for
> > when the thread terminates by any mean (like the pthread_key_create()
> > API's destructor for instance). If the native API does not help I
> > don't think that APR can do much better..
> >
> This sounds problematic to me, because the result is a memory leak unless
> the application code is changed (and the APR consumer has to somehow be aware
> of that).
>
> Also, native Windows thread pool works in a different way: it invokes a
> callback on the random thread created by OS. So there is no easy way to
> track the thread exit.

You call something that does not exist as problematic. If some native
threads can call TerminateThread() at any uncontrollable point then
don't use ap_thread_current_create(), and if this is in an MPM then
don't use that MPM at all if you are worried about leaks.
But threadpools usually let you provide the thread function, so you
have both an entry and exit point between which you are not supposed
to kill the thread (underneath the threadpool), right?

> >
> > As said above, this is how it works already when apr_thread_current() is 
> > NULL.
> > If it's not NULL, you get the nice behaviour that it reuses
> > efficiently the same vector (PCRE1) or context (PCRE2) for each call
> > on the same thread, with no allocation/free overhead or memory
> > fragmentation.
> >
>
> The code in server/util_pcre.c:342 was doing the following:
> [[[
> current = ap_thread_current();
> if (!current) {
> *to_free = 1;
> return alloc_match_data(size, small_vector);
> }
> ]]]
>
> Here alloc_match_data() was calling pcre2_match_data_create(), resulting
> in a malloc().

Yes OK, with the previous implementation there was no cache/stack
provided for PCRE2 for non APR threads (or !AP_HAS_THREAD_LOCAL).
You implemented that, but now what's missing is a per-thread cache
that works for all the patterns and is reused across the calls to
ap_regexec(), and for that you need
AP_THREAD_LOCAL/ap_thread_current().

So how about we still use the stack buffer only if it's enough, or use
some AP_THREAD_LOCAL/ap_thread_current() cache if available, or use
malloc() finally otherwise. Best of both worlds, should there be
regexes with many captures or PCRE2's START_FRAMES_SIZE be smaller for
some libpcre2 build or pcre2_match_data_create_with_frames() be
available on a future PCRE2 version (all of those cases would put more
pressure on private_malloc() with more frequent and/or larger calls
from pcre2_match()), then systems with
AP_THREAD_LOCAL/ap_thread_current() will still work efficiently.

Patch attached, thoughts?

Regards;
Yann.

PS: the patch also includes the fix from
https://bz.apache.org/bugzilla/show_bug.cgi?id=66119
Index: server/util_pcre.c
===
--- server/util_pcre.c	(revision 1902674)
+++ server/util_pcre.c	(working copy)
@@ -56,6 +56,11 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "apr_strings.h"
 #include "apr_tables.h"
 
+#if AP_HAS_THREAD_LOCAL
+#include "apr_thread_proc.h"
+#include "mpm_common.h" /* for ap_max_mem_free */
+#endif
+
 #ifdef HAVE_PCRE2
 #define PCRE2_CODE_UNIT_WIDTH 8
 #include "pcre2.h"
@@ -280,9 +285,24 @@ typedef int*  match_data_pt;
 typedef int*  match_vector_pt;
 #endif
 
+#if AP_HAS_THREAD_LOCAL && !defined(APREG_NO_THREAD_LOCAL)
+#define APREG_USE_THREAD_LOCAL 1
+#else
+#define APREG

Re: svn commit: r1902375 - in /apr/apr/branches/1.8.x: ./ CHANGES file_io/win32/readwrite.c test/testfile.c

2022-07-01 Thread Yann Ylavic
On Fri, Jul 1, 2022 at 1:35 PM Evgeny Kotkov
 wrote:
>
> Yann Ylavic  writes:
>
> > Why would buffered reads always be full reads (i.e. until the given
> > size of EOF)?
> >
> > For apr_file_read() I don't think this is expected, users might want
> > read() to return what is there when it's there (i.e. they handle short
> > reads by themselves), so implicit full reads will force them to use
> > small buffers artificially and they'll lose in throughput. On the
> > other hand, users that want full reads can do that already/currently
> > in their own code (by calling read() multiple times).
> >
> > For apr_file_gets() this is the same issue, why when some read returns
> > the \n would we need to continue reading to fill the buffer? In a pipe
> > scenario the peer would apr_file_write("Hello\n") and the consumer's
> > apr_file_read() would not return that to the user immediately?
> >
> > This has nothing to do with buffered vs non-buffered IMHO, there are
> > apr_file_{read,write}_full() already for that.
>
> One comment I have here is that this commit does not change the existing
> behavior of apr_file_read() for buffered files.  The read_buffered() helper
> isn't new by itself, as it has been merely factored out from apr_file_read().
>
> So, doing full reads for buffered files has been the current behavior
> for both unix and win32 and for a long time, I think.  For example, see
> unix/readwrite.c:file_read_buffered().  This applies to the unix version
> of apr_file_gets() as well.

Oh, and the loop seems to have been removed later in r1828509
"apr_file_read: Optimize large reads from buffered files on Windows"
(backported to 2.4.x in r1902379 too).
So Windows is doing the right thing now (not unix), right?

Sorry for the noise, and thanks for the fix/info :)


Regards;
Yann.


Re: svn commit: r1902378 - in /apr/apr/branches/1.8.x: ./ CHANGES file_io/win32/readwrite.c test/testfile.c

2022-07-01 Thread Yann Ylavic
On Fri, Jul 1, 2022 at 11:14 AM Ivan Zhakov  wrote:
>
> On Fri, 1 Jul 2022 at 01:10, Yann Ylavic  wrote:
> >
> > On Fri, Jul 1, 2022 at 12:00 AM Yann Ylavic  wrote:
> > >
> > > On Thu, Jun 30, 2022 at 7:28 PM  wrote:
> > > >
> > > > Author: ivan
> > > > Date: Thu Jun 30 17:28:50 2022
> > > > New Revision: 1902378
> > > >
> > > > URL: http://svn.apache.org/viewvc?rev=1902378=rev
> > > > Log:
> > > > On 1.8.x branch: Merge r1806299, r1806301, r1806308, r1806610:
> > > >   *) apr_file_write: Optimize large writes to buffered files on
> > > >  Windows.
> > > []
> > > >
> > > > --- apr/apr/branches/1.8.x/file_io/win32/readwrite.c (original)
> > > > +++ apr/apr/branches/1.8.x/file_io/win32/readwrite.c Thu Jun 30 
> > > > 17:28:50 2022
> > > > @@ -247,6 +247,91 @@ APR_DECLARE(apr_status_t) apr_file_read(
> > > >  return rv;
> > > >  }
> > > >
> > > > +/* Helper function that adapts WriteFile() to apr_size_t instead
> > > > + * of DWORD. */
> > > > +static apr_status_t write_helper(HANDLE filehand, const char *buf,
> > > > + apr_size_t len, apr_size_t *pwritten)
> > > > +{
> > > > +apr_size_t remaining = len;
> > > > +
> > > > +*pwritten = 0;
> > > > +do {
> > > > +DWORD to_write;
> > > > +DWORD written;
> > > > +
> > > > +if (remaining > APR_DWORD_MAX) {
> > > > +to_write = APR_DWORD_MAX;
> > > > +}
> > > > +else {
> > > > +to_write = (DWORD)remaining;
> > > > +}
> > > > +
> > > > +if (!WriteFile(filehand, buf, to_write, , NULL)) {
> > > > +*pwritten += written;
> > > > +return apr_get_os_error();
> > > > +}
> > > > +
> > > > +*pwritten += written;
> > > > +remaining -= written;
> > > > +buf += written;
> > > > +} while (remaining);
> > >
> > > So there's no writev() like syscall on Windows (something that
> > > provides atomicity)?
> >
> > I found WriteFileGather
> > (https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefilegather).
> > Maybe it can help with some logic à la apr_socket_sendv()?
> >
> [[[
> Each buffer must be at least the size of a system memory page and must be 
> aligned on a system memory page size boundary. The system writes one system 
> memory page of data from each buffer.
> ]]]
> [[[
> The total number of bytes to be written. Each element of aSegmentArray 
> contains a one-page chunk of this total. Because the file must be opened with 
> FILE_FLAG_NO_BUFFERING, the number of bytes must be a multiple of the sector 
> size of the file system where the file is located.
> ]]]

OK, I said "found it" not "looked at it in detail" :)
Too restrictive it seems (reminds me of O_DIRECT on unixes, we don't
want to use it here).

But the short-write argument stands, if Windows never short-writes
then the implicit full-write is unnecessary, but if it does
short-write then apr_file_write() has to return it too (for the user
to know), so in both cases the loop has to stop when written <
to_write (and probably return success if written > 0).
Users that don't expect short-writes should use apr_file_write_full().

Same on the apr_file_read() side.


Regards;
Yann.


Re: svn commit: r1902378 - in /apr/apr/branches/1.8.x: ./ CHANGES file_io/win32/readwrite.c test/testfile.c

2022-06-30 Thread Yann Ylavic
On Fri, Jul 1, 2022 at 12:00 AM Yann Ylavic  wrote:
>
> On Thu, Jun 30, 2022 at 7:28 PM  wrote:
> >
> > Author: ivan
> > Date: Thu Jun 30 17:28:50 2022
> > New Revision: 1902378
> >
> > URL: http://svn.apache.org/viewvc?rev=1902378=rev
> > Log:
> > On 1.8.x branch: Merge r1806299, r1806301, r1806308, r1806610:
> >   *) apr_file_write: Optimize large writes to buffered files on
> >  Windows.
> []
> >
> > --- apr/apr/branches/1.8.x/file_io/win32/readwrite.c (original)
> > +++ apr/apr/branches/1.8.x/file_io/win32/readwrite.c Thu Jun 30 17:28:50 
> > 2022
> > @@ -247,6 +247,91 @@ APR_DECLARE(apr_status_t) apr_file_read(
> >  return rv;
> >  }
> >
> > +/* Helper function that adapts WriteFile() to apr_size_t instead
> > + * of DWORD. */
> > +static apr_status_t write_helper(HANDLE filehand, const char *buf,
> > + apr_size_t len, apr_size_t *pwritten)
> > +{
> > +apr_size_t remaining = len;
> > +
> > +*pwritten = 0;
> > +do {
> > +DWORD to_write;
> > +DWORD written;
> > +
> > +if (remaining > APR_DWORD_MAX) {
> > +to_write = APR_DWORD_MAX;
> > +}
> > +else {
> > +to_write = (DWORD)remaining;
> > +}
> > +
> > +if (!WriteFile(filehand, buf, to_write, , NULL)) {
> > +*pwritten += written;
> > +return apr_get_os_error();
> > +}
> > +
> > +*pwritten += written;
> > +remaining -= written;
> > +buf += written;
> > +} while (remaining);
>
> So there's no writev() like syscall on Windows (something that
> provides atomicity)?

I found WriteFileGather
(https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefilegather).
Maybe it can help with some logic à la apr_socket_sendv()?

> I would stop the loop on written < to_write at least, apr_file_write()
> should be prepared to get a short/partial write (for whatever reason),
> or otherwise use apr_file_write_full().
>
> > +
> > +return APR_SUCCESS;
> > +}
> > +
> > +static apr_status_t write_buffered(apr_file_t *thefile, const char *buf,
> > +   apr_size_t len, apr_size_t *pwritten)
> > +{
> > +apr_status_t rv;
> > +
> > +if (thefile->direction == 0) {
> > +/* Position file pointer for writing at the offset we are 
> > logically reading from */
> > +apr_off_t offset = thefile->filePtr - thefile->dataRead + 
> > thefile->bufpos;
> > +DWORD offlo = (DWORD)offset;
> > +LONG offhi = (LONG)(offset >> 32);
> > +if (offset != thefile->filePtr)
> > +SetFilePointer(thefile->filehand, offlo, , FILE_BEGIN);
> > +thefile->bufpos = thefile->dataRead = 0;
> > +thefile->direction = 1;
> > +}
> > +
> > +*pwritten = 0;
> > +
> > +while (len > 0) {
> > +if (thefile->bufpos == thefile->bufsize) { /* write buffer is full 
> > */
> > +rv = apr_file_flush(thefile);
> > +if (rv) {
> > +return rv;
> > +}
> > +}
> > +/* If our buffer is empty, and we cannot fit the remaining chunk
> > + * into it, write the chunk with a single syscall and return.
> > + */
> > +if (thefile->bufpos == 0 && len > thefile->bufsize) {
> > +apr_size_t written;
> > +
> > +rv = write_helper(thefile->filehand, buf, len, );
> > +thefile->filePtr += written;
> > +*pwritten += written;
> > +return rv;
> > +}
> > +else {
> > +apr_size_t blocksize = len;
> > +
> > +if (blocksize > thefile->bufsize - thefile->bufpos) {
> > +blocksize = thefile->bufsize - thefile->bufpos;
> > +}
> > +memcpy(thefile->buffer + thefile->bufpos, buf, blocksize);
> > +thefile->bufpos += blocksize;
> > +buf += blocksize;
> > +len -= blocksize;
> > +*pwritten += blocksize;
> > +}
> > +}
>
> Likewise.
>
> > +
> > +return APR_SUCCESS;
> > +}
>
>
> Regards;
> Yann.


Re: svn commit: r1902378 - in /apr/apr/branches/1.8.x: ./ CHANGES file_io/win32/readwrite.c test/testfile.c

2022-06-30 Thread Yann Ylavic
On Thu, Jun 30, 2022 at 7:28 PM  wrote:
>
> Author: ivan
> Date: Thu Jun 30 17:28:50 2022
> New Revision: 1902378
>
> URL: http://svn.apache.org/viewvc?rev=1902378=rev
> Log:
> On 1.8.x branch: Merge r1806299, r1806301, r1806308, r1806610:
>   *) apr_file_write: Optimize large writes to buffered files on
>  Windows.
[]
>
> --- apr/apr/branches/1.8.x/file_io/win32/readwrite.c (original)
> +++ apr/apr/branches/1.8.x/file_io/win32/readwrite.c Thu Jun 30 17:28:50 2022
> @@ -247,6 +247,91 @@ APR_DECLARE(apr_status_t) apr_file_read(
>  return rv;
>  }
>
> +/* Helper function that adapts WriteFile() to apr_size_t instead
> + * of DWORD. */
> +static apr_status_t write_helper(HANDLE filehand, const char *buf,
> + apr_size_t len, apr_size_t *pwritten)
> +{
> +apr_size_t remaining = len;
> +
> +*pwritten = 0;
> +do {
> +DWORD to_write;
> +DWORD written;
> +
> +if (remaining > APR_DWORD_MAX) {
> +to_write = APR_DWORD_MAX;
> +}
> +else {
> +to_write = (DWORD)remaining;
> +}
> +
> +if (!WriteFile(filehand, buf, to_write, , NULL)) {
> +*pwritten += written;
> +return apr_get_os_error();
> +}
> +
> +*pwritten += written;
> +remaining -= written;
> +buf += written;
> +} while (remaining);

So there's no writev() like syscall on Windows (something that
provides atomicity)?
I would stop the loop on written < to_write at least, apr_file_write()
should be prepared to get a short/partial write (for whatever reason),
or otherwise use apr_file_write_full().

> +
> +return APR_SUCCESS;
> +}
> +
> +static apr_status_t write_buffered(apr_file_t *thefile, const char *buf,
> +   apr_size_t len, apr_size_t *pwritten)
> +{
> +apr_status_t rv;
> +
> +if (thefile->direction == 0) {
> +/* Position file pointer for writing at the offset we are logically 
> reading from */
> +apr_off_t offset = thefile->filePtr - thefile->dataRead + 
> thefile->bufpos;
> +DWORD offlo = (DWORD)offset;
> +LONG offhi = (LONG)(offset >> 32);
> +if (offset != thefile->filePtr)
> +SetFilePointer(thefile->filehand, offlo, , FILE_BEGIN);
> +thefile->bufpos = thefile->dataRead = 0;
> +thefile->direction = 1;
> +}
> +
> +*pwritten = 0;
> +
> +while (len > 0) {
> +if (thefile->bufpos == thefile->bufsize) { /* write buffer is full */
> +rv = apr_file_flush(thefile);
> +if (rv) {
> +return rv;
> +}
> +}
> +/* If our buffer is empty, and we cannot fit the remaining chunk
> + * into it, write the chunk with a single syscall and return.
> + */
> +if (thefile->bufpos == 0 && len > thefile->bufsize) {
> +apr_size_t written;
> +
> +rv = write_helper(thefile->filehand, buf, len, );
> +thefile->filePtr += written;
> +*pwritten += written;
> +return rv;
> +}
> +else {
> +apr_size_t blocksize = len;
> +
> +if (blocksize > thefile->bufsize - thefile->bufpos) {
> +blocksize = thefile->bufsize - thefile->bufpos;
> +}
> +memcpy(thefile->buffer + thefile->bufpos, buf, blocksize);
> +thefile->bufpos += blocksize;
> +buf += blocksize;
> +len -= blocksize;
> +*pwritten += blocksize;
> +}
> +}

Likewise.

> +
> +return APR_SUCCESS;
> +}


Regards;
Yann.


Re: svn commit: r1902375 - in /apr/apr/branches/1.8.x: ./ CHANGES file_io/win32/readwrite.c test/testfile.c

2022-06-30 Thread Yann Ylavic
On Thu, Jun 30, 2022 at 6:19 PM  wrote:
>
> Author: ivan
> Date: Thu Jun 30 16:18:51 2022
> New Revision: 1902375
>
> URL: http://svn.apache.org/viewvc?rev=1902375=rev
> Log:
> On 1.8.x branch: Merge r1785072, r1788930 from trunk:
>   *) apr_file_gets: Optimize for buffered files on Windows.
>  [Evgeny Kotkov ]
[]
>
> --- apr/apr/branches/1.8.x/file_io/win32/readwrite.c (original)
> +++ apr/apr/branches/1.8.x/file_io/win32/readwrite.c Thu Jun 30 16:18:51 2022
> @@ -141,6 +141,56 @@ static apr_status_t read_with_timeout(ap
>  return rv;
>  }
>
> +static apr_status_t read_buffered(apr_file_t *thefile, void *buf, apr_size_t 
> *len)
> +{
> +apr_status_t rv;
> +char *pos = (char *)buf;
> +apr_size_t blocksize;
> +apr_size_t size = *len;
> +
> +if (thefile->direction == 1) {
> +rv = apr_file_flush(thefile);
> +if (rv != APR_SUCCESS) {
> +return rv;
> +}
> +thefile->bufpos = 0;
> +thefile->direction = 0;
> +thefile->dataRead = 0;
> +}
> +
> +rv = 0;
> +while (rv == 0 && size > 0) {
> +if (thefile->bufpos >= thefile->dataRead) {
> +apr_size_t read;
> +rv = read_with_timeout(thefile, thefile->buffer,
> +   thefile->bufsize, );
> +if (read == 0) {
> +if (rv == APR_EOF)
> +thefile->eof_hit = TRUE;
> +break;
> +}
> +else {
> +thefile->dataRead = read;
> +thefile->filePtr += thefile->dataRead;
> +thefile->bufpos = 0;
> +}
> +}
> +
> +blocksize = size > thefile->dataRead - thefile->bufpos ? 
> thefile->dataRead - thefile->bufpos : size;
> +memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
> +thefile->bufpos += blocksize;
> +pos += blocksize;
> +size -= blocksize;
> +}

Why would buffered reads always be full reads (i.e. until the given
size of EOF)?

For apr_file_read() I don't think this is expected, users might want
read() to return what is there when it's there (i.e. they handle short
reads by themselves), so implicit full reads will force them to use
small buffers artificially and they'll lose in throughput. On the
other hand, users that want full reads can do that already/currently
in their own code (by calling read() multiple times).

For apr_file_gets() this is the same issue, why when some read returns
the \n would we need to continue reading to fill the buffer? In a pipe
scenario the peer would apr_file_write("Hello\n") and the consumer's
apr_file_read() would not return that to the user immediately?

This has nothing to do with buffered vs non-buffered IMHO, there are
apr_file_{read,write}_full() already for that.

I don't know if nonblocking reads take this path too, but if so this
also causes a second/useless read (because nonblocking are often short
reads) that is almost sure to return EAGAIN (or windows equivalent),
and the call would return EGAIN with *len > 0?

> +
> +*len = pos - (char *)buf;
> +if (*len) {
> +rv = APR_SUCCESS;
> +}
> +
> +return rv;
> +}


Re: svn commit: r1887497 - in /apr/apr/branches/1.7.x: ./ CHANGES mmap/unix/mmap.c test/data/mmap_large_datafile.txt test/testfnmatch.c test/testmmap.c

2022-06-30 Thread Yann Ylavic
On Wed, Jun 29, 2022 at 4:49 PM William A Rowe Jr  wrote:
>
> The eventual change still is present for apr
> 1.8 adopters.
>
> Thoughts? ylavic are you willing to revert?

It seems that no one is using apr_mmap_create() with an offset != 0 or
the bug would have been reported (PR 65158 proved to be a cifs
filesystem bug finally). Well, apr_bucket_file reads can use an mmap
offset if planets misalign still, and that's possibly why we had quite
some issues for "EnableMMap on" in httpd (IIRC), but since it was
never nailed to this bug it usually ends with "please EnableMMap =>
off"..
So let's revert, if something comes up around this, it's probably
another case where I'll first ask: can you reproduce with apr-1.8?

For 1.8.x then (we can fix it there right?), I'd rather we revert this
change and r1887508 to merge trunk's r1887060 and r1887506 directly
(i.e. without the API workaround-try of this 1.7.x merge).
That is, add the "poffset" field to (the end of) apr_mmap_t and be
done with no tricks. But since I'm not sure what we can or not do with
a minor bump I'll ask, can we do that?

Regards;
Yann.


Re: svn commit: r1884103 - in /apr/apr/branches/1.7.x: ./ include/arch/beos/ include/arch/netware/ include/arch/unix/ include/arch/win32/ memory/unix/ threadproc/beos/ threadproc/netware/ threadproc/o

2022-06-30 Thread Yann Ylavic
On Wed, Jun 29, 2022 at 6:09 PM Yann Ylavic  wrote:
>
> By making such impracticable policies for revision changes (semver
> sense), we are going to simply not fix anything but trivial changes
> without bumping minor, and no one would/should care about the old
> (though still "maintained") minor versions. What's the point of
> releasing 1.7.1 then? Let's go with 1.8.0 only, simpler (less
> maintenance) and better for everybody..

OK, by re-reading this I realize I was a bit harsh, a bit of
frustration here (fixes that don't get in..), sorry about that.

After a bit of diving into svn history, this commit was mainly to
address UAF with apr_thread_pool code when it was using detached
threads, which is not the case anymore (r1884110, r1889219).
So the scope of the fix might be for user detached thread usage "only"
(which may not be common), and APR_POOL_DEBUG (which is mainly never
by devs only, though something happening in APR_POOL_DEBUG mode might
happen without when the planets are no longer aligned).
I'll try to revert and see how it goes for, e.g., httpd's ci (where
mod_watchdog uses thread pools).

Anyway, if we get bug/crash reports for 1.7.1 and some (time
consuming) invertigations shows that it's fixed in 1.8, I'm going to
be a bit frustated too ;)

>
> Regards;
> Yann.


Re: svn commit: r1884103 - in /apr/apr/branches/1.7.x: ./ include/arch/beos/ include/arch/netware/ include/arch/unix/ include/arch/win32/ memory/unix/ threadproc/beos/ threadproc/netware/ threadproc/o

2022-06-29 Thread Yann Ylavic
On Wed, Jun 29, 2022 at 4:47 PM William A Rowe Jr  wrote:
>
> This change does introduce an API change, and a somewhat possibly dangerous
> structure size alteration, and seems to be out of bounds for apr 1.7.x branch.

AFAICT, this change only touches internal/opaque structures..
Are you talking about apr__pool_unmanage()? If so it was later removed
in r1897210.

About this change particularly, it fixes serious bugs in APR threads,
just run the tests with r1884102 (before this commit), APR_POOL_DEBUG
(to ease reproduction) and under ASan (Address Sanitizer,
-fsanitize=address), or maybe it was httpd's tests.
I can't remember the details and travis does not seem to keep builds
history that far (Dec 2020) so I can't point you to the stack traces /
reports.
I do remember that period where we started to run ASan builds though
(in httpd and later APR), this led to a series of fixes in APR,
including this one..

>
> Anyone using a build crossing runtimes between apr 1.7.0 and 1.7.1 may
> experience
> unintended side-effects.

Anyone running apr-1.7.x without these fixes and using threads is kind
of in UB land.

>
> While it's true that include/arch and include/private are not
> considered generally
> supported, folks are known to use them, and macros may cause the library to
> bleed internals.

Really? We don't install these headers, and they are opaque precisely
so that we can change them without breaking users.
If users copy private headers for their use cases, shouldn't they take
the burden of maintaining their codebase (depending on that) when
those headers change? This can't be on us..

By making such impracticable policies for revision changes (semver
sense), we are going to simply not fix anything but trivial changes
without bumping minor, and no one would/should care about the old
(though still "maintained") minor versions. What's the point of
releasing 1.7.1 then? Let's go with 1.8.0 only, simpler (less
maintenance) and better for everybody..


Regards;
Yann.


Re: svn commit: r1863234 - in /apr/apr/branches/1.7.x: ./ include/apr_pools.h memory/unix/apr_pools.c

2022-06-29 Thread Yann Ylavic
On Wed, Jun 29, 2022 at 4:41 PM William A Rowe Jr  wrote:
>
> This is the first commit which appeared to break APR in such a way
> that code compiled
> against apr 1.7.1 would be unable to run against apr 1.7.0 binaries.

I think it has been reverted already by http://svn.apache.org/r1902022

Regards;
Yann.


Re: Issues with shipping apr_thread_current() in APR 1.8.0 and an alternative approach for PCRE2 allocations in HTTPD

2022-06-28 Thread Yann Ylavic
On Tue, Jun 28, 2022 at 6:08 PM Ivan Zhakov  wrote:
>
> On Tue, 28 Jun 2022 at 00:24, Yann Ylavic  wrote:
> >
> > Hi Ivan,
> >
> > On Mon, Jun 27, 2022 at 8:19 PM Ivan Zhakov  wrote:
> > >
> > > For the longer version, let me first outline a few problems with the 
> > > current apr_thread_current() API:
> > >
> > > 1) apr_thread_current_create() leaks the memory allocated in 
> > > alloc_thread() after the thread exits.
> >
> > Hm, alloc_thread() creates an unmanaged pool (thread->pool) and
> > allocates everything for the thread on that pool (including the thread
> > itself).
> > This pool is destroyed when the thread is joined (for attached
> > threads), or for detached threads when apr_thread_exit() is called
> > explicitly otherwise when the thread function actually exits.
> > So which memory leaks precisely? apr_thread_current_create() for the
> > process' main thread may leak the thread pool on exit because it's
> > detached, it has not been apr_thread_create()d and is usually not
> > apr_thread_exit()ed, but when the main thread exits (hence the
> > process) nothing really leaks.. Should it matter we could also have an
> > explicit apr_thread_current_unleak().
> >
> > Or do you mean the apr_threadattr_t that can be passed to
> > apr_thread_current_create()? That one is on the caller's
> > responsibility, and it can be reused for multiple threads if needed.
> >
> I meant a memory leak for native threads. For example, with an MPM
> that uses native Windows threadpool for worker threads.

That's not mpm_winnt right? (it does not use native threads anymore
and plays no apr_thread_current_create() game, it just uses
apr_thread_create() so apr_thread_current() works automatically
there).

Probably the thread pool lets you pass the thread function? So you
could "apr_thread_current_create()" when entering the
function and "apr_pool_destroy(apr_thread_pool_get(mythread))" before
leaving?
That'd still leak if the thread calls TerminateThread() explicitly at
some point, but it seems that the native Windows thread API is not
very helpful for that since there is way to register a destructor for
when the thread terminates by any mean (like the pthread_key_create()
API's destructor for instance). If the native API does not help I
don't think that APR can do much better..

Also finally, if you want to leave native threads alone (i.e. not
APR-ize them), just do that, ap_regex will still work. The ap_regex
code is prepared to get apr_thread_current() == NULL, because it could
be called by a non-APR thread, and in this case it works exactly how
you propose it should (small stack with fall back to malloc/free for
PCRE1, or with PCRE2 using its native exec-context alloc/free since
it's opaque so you can't put it on the stack, but that'd be for every
ap_regexec() call).

Note that httpd could (hypothetically) later assert/assume, for some
other code, that it's never called from a non-APR thread and
enforce/omit the NULL checks, that's up to a "main" program to decide
since it has the full picture (httpd probably won't do that in a 2.x
version since it could break third-party MPMs creating native worker
threads only, but who knows if for 3.x it proves to be a nice/simpler
way to handle things in core/modules, then httpd-3.x could require
that the MPMs create APR worker threads only, or APR-ize them before
entering core/modules processing since there is an API for that..).

> > >
> > > 2) apr_thread_current_create() requires passing in the apr_threadattr_t 
> > > value that may be unknown to the caller, so the result may not correspond 
> > > to the actual thread attributes.
> >
> > This threadattr is for the users who know (attached vs detached
> > mainly), but if they don't know/care maybe they shouldn't use
> > apr_thread_current_create()?
> > It really matters if
> > apr_thread_detach()/apr_thread_join()/apr_thread_exit() is to be
> > called later anyway, but users that do this usually create their
> > thread with apr_thread_create(), and for these threads
> > apr_thread_current_create() is moot anyway (apr_thread_current() works
> > automagically for them).
> > The main usage of apr_thread_current_create() is for the main thread,
> > and this one is always detached per definition. But if users know the
> > nature/lifetime of the native threads they want to APR-ize,
> > apr_thread_current_create() can be useful too.
> >
> I think the problem is that in the general case the API user still
> needs to pass in the proper apr_threadattr_t to receive the proper
> current apr_thread_t object (even if there's a shortcut for some
> cases).

This is the case

Re: svn commit: r1902297 - in /apr/apr/branches/thread-name: include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2022-06-28 Thread Yann Ylavic
On Tue, Jun 28, 2022 at 9:24 PM Eric Covener  wrote:
>
> Ran out of time but I added a crude check to the branch in 1902326.

Argh, I missed your message (which showed up after I sent mine..).
Well, two solutions are better than none :)


Re: svn commit: r1902297 - in /apr/apr/branches/thread-name: include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2022-06-28 Thread Yann Ylavic
On Tue, Jun 28, 2022 at 8:06 PM Ivan Zhakov  wrote:
>
> On Tue, 28 Jun 2022 at 14:45, Yann Ylavic  wrote:
> >
> > On Tue, Jun 28, 2022 at 1:13 AM  wrote:
> > >
> > > Author: ivan
> > > Date: Mon Jun 27 23:13:52 2022
> > > New Revision: 1902297
> > >
> > > URL: http://svn.apache.org/viewvc?rev=1902297=rev
> > > Log:
> > > On 'thread-name' branch: Add apr_thread_name_get() and 
> > > apr_thread_name_set()
> > > API to get/set thread name.
> > >
> > []
> > > --- apr/apr/branches/thread-name/threadproc/unix/thread.c (original)
> > > +++ apr/apr/branches/thread-name/threadproc/unix/thread.c Mon Jun 27 
> > > 23:13:52 2022
> > []
> > > @@ -277,6 +282,48 @@ APR_DECLARE(apr_thread_t *) apr_thread_c
> > >  #endif
> > >  }
> > >
> > > +APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
> > > +  apr_thread_t *thread,
> > > +  apr_pool_t *pool)
> > > +{
> > > +pthread_t td;
> > > +
> > > +size_t name_len;
> > > +if (!name) {
> > > +return APR_BADARG;
> > > +}
> > > +
> > > +if (thread) {
> > > +td = *thread->td;
> > > +}
> > > +else {
> > > +td = pthread_self();
> > > +}
> > > +
> > > +name_len = strlen(name);
> > > +if (name_len >= TASK_COMM_LEN) {
> > > +name = name + name_len - TASK_COMM_LEN + 1;
> > > +}
> > > +
> > > +return pthread_setname_np(td, name);
> >
> > We probably need to check for HAVE_PTHREAD_SETNAME_NP since it's _np
> > (non-portable).
> Thanks for the suggestion!
>
> I'm not so familiar with autoconf stuff (that's why I created branch):
> can I just check for HAVE_PTHREAD_SETNAME_NP or do I need some
> autoconf magic to set it?

Maybe something like the attached patch, and then check for
HAVE_PTHREAD_GETNAME_SETNAME_NP for both functions (which pair
anyway).

Regards;
Yann.
Index: configure.in
===
--- configure.in	(revision 1902267)
+++ configure.in	(working copy)
@@ -2401,11 +2401,16 @@ APR_CHECK_DEFINE(SEM_UNDO, sys/sem.h)
 APR_CHECK_DEFINE_FILES(POLLIN, poll.h sys/poll.h)
 
 if test "$threads" = "1"; then
+AC_CHECK_HEADERS([pthread.h])
 APR_CHECK_DEFINE(PTHREAD_PROCESS_SHARED, pthread.h)
-AC_CHECK_FUNCS(pthread_mutex_timedlock pthread_mutexattr_setpshared)
+AC_CHECK_FUNCS(pthread_mutex_timedlock pthread_mutexattr_setpshared dnl
+   pthread_getname_np pthread_setname_np)
 APR_IFALLYES(header:pthread.h func:pthread_mutex_timedlock,
  have_pthread_mutex_timedlock="1", have_pthread_mutex_timedlock="0")
 AC_SUBST(have_pthread_mutex_timedlock)
+APR_IFALLYES(header:pthread.h func:pthread_getname_np func:pthread_setname_np,
+ have_pthread_getname_setname_np="1", have_pthread_getname_setname_np="0")
+AC_SUBST(have_pthread_getname_setname_np)
 # Some systems have setpshared and define PROCESS_SHARED, but don't 
 # really support PROCESS_SHARED locks.  So, we must validate that we 
 # can go through the steps without receiving some sort of system error.


Re: svn commit: r1902312 - /apr/apr/trunk/network_io/win32/sendrecv.c

2022-06-28 Thread Yann Ylavic
On Tue, Jun 28, 2022 at 1:53 PM Ivan Zhakov  wrote:
>
> On Tue, 28 Jun 2022 at 14:08,  wrote:
> >
> > Author: ylavic
> > Date: Tue Jun 28 11:08:32 2022
> > New Revision: 1902312
> >
> > URL: http://svn.apache.org/viewvc?rev=1902312=rev
> > Log:
> > apr_socket_sendv: WIN32: Limit the number of WSABUFs allocated for a single 
> > call.
> >
> > * network_io/win32/sendrecv.c():
> >   Define WSABUF_ON_HEAP to 500.
> >
> > * network_io/win32/sendrecv.c(apr_socket_sendv):
> >   Do not sendv more than WSABUF_ON_HEAP WSABUFs.
> >
> This commit changes the behavior for blocking sockets: now
> apr_socket_sendv() may result in a partial write.

It's always been like that for sockets, write[v]() has non-partial
guarantees on some systems only (Linux, Windows?) *and* for regular
files (and, IIRC, pipes up to PIPE_BUF).
There can't be any guarantee for communications with a negotiated
window size or datagrams, if you try to send 10GB of data in a single
call on a TCP socket it won't block until all the data have been sent
(unless you tune the SND_BUF?), not to talk about UDP.

>
> As far I see apr_socket_sendv() does not explicitly document whether
> partial writes are allowed for *blocking* sockets. Posix send() seems
> to send all data [1]:
> [[
> When the message does not fit into the send buffer of the socket,
> send() normally blocks, unless the socket has been placed in
> nonblocking I/O mode. In nonblocking mode it would fail with the error
> EAGAIN or EWOULDBLOCK in this case. The select(2) call may be used to
> determine when it is possible to send more data.
> ]]

This does not say it sends all data, whenever the send buffer gets
some space again the system will send what it can and return that (as
opposed to buffering the remaining data and loop).

>
> Also even APR code assumes that apr_socket_sendv() doesn't allow
> partial writes. See apr_memcache_delete() for example:
> https://demo-server.visualsvn.com/!/#asf/view/r1902313/apr/apr/trunk/memcache/apr_memcache.c?line=923

I don't think that the change breaks this case where nvec == 3 (given
that WSABUF_ON_HEAP == 500).

>
> Not too sure that limiting the size of the malloc() is worth it in
> this case. What are the reasons to limit it?

On a 64bit system, iov_len is a size_t (64bit) while WSABUF->len is a
DWORD (32bit), so we could create a really huge number of WSABUFs (~
2^32) with a single iovec. So I first had:

#define WSABUF_ON_HEAP (APR_SIZE_MAX / sizeof(WSABUF))

which would have limited nvec to the hard limits, and let
malloc(APR_SIZE_MAX) fail for pathological cases.
But I then thought someone calling apr_socket_sendv() with more than
500 iovecs (an arbitrary value admittedly, but that's 8KB for the
WSABUFs already) kind of deserves implicit partial writes..

>
> Another approach would be to split writes to multiple WSASend calls
> when iovec count is more than WSABUF_ON_STACK, but this would break
> implicit assumption that apr_socket_sendv() is atomic like writev [2].

There is no atomicity guarantee besides regular files and pipes (both
probably up to PIPE_BUF only).

>
> PS: Do we have a test for such apr_socket_sendv() call?

Looks like we don't, besides some calls in testmemcache and testredis..

>
> [1] https://linux.die.net/man/2/send
> [2] https://linux.die.net/man/2/writev

Regards;
Yann.


Re: svn commit: r1902297 - in /apr/apr/branches/thread-name: include/ include/arch/win32/ test/ threadproc/beos/ threadproc/netware/ threadproc/os2/ threadproc/unix/ threadproc/win32/

2022-06-28 Thread Yann Ylavic
On Tue, Jun 28, 2022 at 1:13 AM  wrote:
>
> Author: ivan
> Date: Mon Jun 27 23:13:52 2022
> New Revision: 1902297
>
> URL: http://svn.apache.org/viewvc?rev=1902297=rev
> Log:
> On 'thread-name' branch: Add apr_thread_name_get() and apr_thread_name_set()
> API to get/set thread name.
>
[]
> --- apr/apr/branches/thread-name/threadproc/unix/thread.c (original)
> +++ apr/apr/branches/thread-name/threadproc/unix/thread.c Mon Jun 27 23:13:52 
> 2022
[]
> @@ -277,6 +282,48 @@ APR_DECLARE(apr_thread_t *) apr_thread_c
>  #endif
>  }
>
> +APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
> +  apr_thread_t *thread,
> +  apr_pool_t *pool)
> +{
> +pthread_t td;
> +
> +size_t name_len;
> +if (!name) {
> +return APR_BADARG;
> +}
> +
> +if (thread) {
> +td = *thread->td;
> +}
> +else {
> +td = pthread_self();
> +}
> +
> +name_len = strlen(name);
> +if (name_len >= TASK_COMM_LEN) {
> +name = name + name_len - TASK_COMM_LEN + 1;
> +}
> +
> +return pthread_setname_np(td, name);

We probably need to check for HAVE_PTHREAD_SETNAME_NP since it's _np
(non-portable).
Some systems seem to implement "prctl(PR_SET_NAME, ...)" too, but
that's for pthread_self() only..

> +}
> +
> +APR_DECLARE(apr_status_t) apr_thread_name_get(char **name,
> +  apr_thread_t *thread,
> +  apr_pool_t *pool)
> +{
> +pthread_t td;
> +if (thread) {
> +td = *thread->td;
> +}
> +else {
> +td = pthread_self();
> +}
> +
> +*name = apr_pcalloc(pool, TASK_COMM_LEN);
> +return pthread_getname_np(td, *name, TASK_COMM_LEN);

Likewise for HAVE_PTHREAD_GETNAME_NP/prctl(PR_GET_NAME).

> +}


Re: Issues with shipping apr_thread_current() in APR 1.8.0 and an alternative approach for PCRE2 allocations in HTTPD

2022-06-27 Thread Yann Ylavic
Hi Ivan,

On Mon, Jun 27, 2022 at 8:19 PM Ivan Zhakov  wrote:
>
> For the longer version, let me first outline a few problems with the current 
> apr_thread_current() API:
>
> 1) apr_thread_current_create() leaks the memory allocated in alloc_thread() 
> after the thread exits.

Hm, alloc_thread() creates an unmanaged pool (thread->pool) and
allocates everything for the thread on that pool (including the thread
itself).
This pool is destroyed when the thread is joined (for attached
threads), or for detached threads when apr_thread_exit() is called
explicitly otherwise when the thread function actually exits.
So which memory leaks precisely? apr_thread_current_create() for the
process' main thread may leak the thread pool on exit because it's
detached, it has not been apr_thread_create()d and is usually not
apr_thread_exit()ed, but when the main thread exits (hence the
process) nothing really leaks.. Should it matter we could also have an
explicit apr_thread_current_unleak().

Or do you mean the apr_threadattr_t that can be passed to
apr_thread_current_create()? That one is on the caller's
responsibility, and it can be reused for multiple threads if needed.

>
> 2) apr_thread_current_create() requires passing in the apr_threadattr_t value 
> that may be unknown to the caller, so the result may not correspond to the 
> actual thread attributes.

This threadattr is for the users who know (attached vs detached
mainly), but if they don't know/care maybe they shouldn't use
apr_thread_current_create()?
It really matters if
apr_thread_detach()/apr_thread_join()/apr_thread_exit() is to be
called later anyway, but users that do this usually create their
thread with apr_thread_create(), and for these threads
apr_thread_current_create() is moot anyway (apr_thread_current() works
automagically for them).
The main usage of apr_thread_current_create() is for the main thread,
and this one is always detached per definition. But if users know the
nature/lifetime of the native threads they want to APR-ize,
apr_thread_current_create() can be useful too.

>
> 3) apr_thread_current() allows for situations where it can return NULL, such 
> as with !APR_THREAD_LOCAL, making the API easy to misuse.

Maybe we shouldn't define apr_thread_current{,_create}() when
!APR_THREAD_LOCAL? I find it useful though to determine if the current
thread is an APR one or not.

>
> 4) apr_thread_current_after_fork() callback has to be called by the API user 
> in the appropriate moments of time, allowing for a hard-to-spot API misuse.

Again, this one is a helper for native threads, if apr_fork() is used
there is nothing to be done on the user side (httpd could do that in
the unix threaded MPMs for instance to avoid the calls to
apr_thread_current_after_fork()).

>
> Since apr_thread_current() was added to implement the specific allocation 
> scheme for PCRE2,

I personally find the API qui useful per se, but admittedly I'm a bit
biased too..

> I think that we could try an alternative approach for that part of the 
> problem. The alternative approach would have the same characteristics as the 
> approach that had been used for PCRE1:
>
> -- Supply PCRE2 with a custom context with malloc and free implementations.
> -- Those implementations would work by either using a stack buffer for small 
> allocations or by doing a malloc().
> -- This allocation scheme would have the same properties as the existing 
> scheme used when compiling with PCRE1.

For PCRE2, you would malloc()/free() for every ap_regexec(), which can
be quite costly depending on the configuration/modules. This work was
done precisely for this concern, for the switch from PCRE1 to PCRE2 to
be as little costly as possible. The current implementation reuses the
same PCRE2 context per thread for the lifetime of httpd..
Same for PCRE1, besides the stack buffer for small vectors (which is
still there currently btw).

>
> With that in mind, the overall plan would be as follows:
>
> A) Implement the above approach for PCRE2 allocations in httpd.
> B) Remove the apr_thread_current() and APR_THREAD_LOCAL from APR trunk and 
> 1.8.x.
> C) Release APR 1.8.0.

Frankly, I find it hard to shoot down an API that works because it
could be misused when playing with native threads, whereas it works
transparently when using the APR threads directly.

Isn't somewhere:
 apr_thread_data_set(my_data, my_key, NULL, apr_thread_current());
And elsewhere:
 apr_thread_data_get(_data, my_key, apr_thread_current());
quite nice compared to creating a native threadkey (whose number is
usually limited) for each entry?


Regards;
Yann.


Re: svn commit: r1902285 - /apr/apr/trunk/test/testencode.c

2022-06-27 Thread Yann Ylavic
On Mon, Jun 27, 2022 at 8:35 PM Ivan Zhakov  wrote:
>
> On Mon, 27 Jun 2022 at 21:14, Yann Ylavic  wrote:
>>
>> On Mon, Jun 27, 2022 at 8:08 PM Ivan Zhakov  wrote:
>> >
>> > On Mon, 27 Jun 2022 at 21:01,  wrote:
>> >>
>> >> +#ifdef WIN32
>> >> +typedef apr_status_t (__stdcall *encdec_fn)(char*, const char*, 
>> >> apr_ssize_t, int, apr_size_t*);
>> >> +#else
>> >> +typedef apr_status_t (*encdec_fn)(char*, const char*, apr_ssize_t, int, 
>> >> apr_size_t*);
>> >> +#endif
>> >>
>> > This uses assumptions about calling convention used on the Win32 platform. 
>> > I don't think it's a good thing. Do we really need an array of callbacks? 
>> > May just inline all these calls?
>>
>> APR_DECLARE() seems to always __stdcall, as opposed to
>> APR_DECLARE_NONSTD()'s __cdecl.
>> But I barely understand these Windows subtleties, so yeah I can inline..
>>
>
> Yes, *currently* it is always a stdcall, but it could change so it's better 
> do not have such assumptions.

r1902286.

Thanks;
Yann.


Re: svn commit: r1902285 - /apr/apr/trunk/test/testencode.c

2022-06-27 Thread Yann Ylavic
On Mon, Jun 27, 2022 at 8:08 PM Ivan Zhakov  wrote:
>
> On Mon, 27 Jun 2022 at 21:01,  wrote:
>>
>> +#ifdef WIN32
>> +typedef apr_status_t (__stdcall *encdec_fn)(char*, const char*, 
>> apr_ssize_t, int, apr_size_t*);
>> +#else
>> +typedef apr_status_t (*encdec_fn)(char*, const char*, apr_ssize_t, int, 
>> apr_size_t*);
>> +#endif
>>
> This uses assumptions about calling convention used on the Win32 platform. I 
> don't think it's a good thing. Do we really need an array of callbacks? May 
> just inline all these calls?

APR_DECLARE() seems to always __stdcall, as opposed to
APR_DECLARE_NONSTD()'s __cdecl.
But I barely understand these Windows subtleties, so yeah I can inline..

Regards;
Yann.


Re: svn commit: r1902281 [1/2] - in /apr/apr/trunk: encoding/apr_encode.c encoding/apr_escape.c include/apr_encode.h include/private/apr_encode_private.h test/testencode.c

2022-06-27 Thread Yann Ylavic
On Mon, Jun 27, 2022 at 6:14 PM Yann Ylavic  wrote:
>
> On Mon, Jun 27, 2022 at 5:26 PM  wrote:
> >
> > Author: ylavic
> > Date: Mon Jun 27 15:26:09 2022
> > New Revision: 1902281
> >
> > URL: http://svn.apache.org/viewvc?rev=1902281=rev
> > Log:
> > encoding: Better check inputs of apr_{encode,decode}_* functions.
>
> This commit seems to cause a segfault on Windows 32bit:
> https://github.com/apache/apr/runs/7075975923?check_suite_focus=true#step:5:35
> Any stacktrace/hint someone?

Thanks Ivan, r1902283 helped ;)

>
> Regards;
> Yann.


Re: svn commit: r1902281 [1/2] - in /apr/apr/trunk: encoding/apr_encode.c encoding/apr_escape.c include/apr_encode.h include/private/apr_encode_private.h test/testencode.c

2022-06-27 Thread Yann Ylavic
On Mon, Jun 27, 2022 at 5:26 PM  wrote:
>
> Author: ylavic
> Date: Mon Jun 27 15:26:09 2022
> New Revision: 1902281
>
> URL: http://svn.apache.org/viewvc?rev=1902281=rev
> Log:
> encoding: Better check inputs of apr_{encode,decode}_* functions.

This commit seems to cause a segfault on Windows 32bit:
https://github.com/apache/apr/runs/7075975923?check_suite_focus=true#step:5:35
Any stacktrace/hint someone?

Regards;
Yann.


Re: svn commit: r1902219 - in /apr/apr/branches/1.8.x: ./ test/testlock.c

2022-06-26 Thread Yann Ylavic
On Sat, Jun 25, 2022 at 6:34 PM Christophe JAILLET
 wrote:
>
> Le 24/06/2022 à 11:06, yla...@apache.org a écrit :
> >
> > --- apr/apr/branches/1.8.x/test/testlock.c (original)
> > +++ apr/apr/branches/1.8.x/test/testlock.c Fri Jun 24 09:06:05 2022
> > @@ -111,6 +111,7 @@ static void *APR_THREAD_FUNC thread_mute
> >   break;
> >   }
> >   return NULL;
> > +return NULL;
>
> ???

Just in case :)
Fixed in r1902254, thanks.

Regards;
Yann.


apr_atomic_casptr2() in apr-1.8.x ?

2022-06-24 Thread Yann Ylavic
Daniel proposed in [1] that we introduce apr_atomic_casptr2() to
resolve the defect in the apr_atomic_casptr() API.
Namely the correct:
1. APR_DECLARE(void*) apr_atomic_casptr(void *volatile *mem, ...);
Versus the broken:
2. APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, ...);

The problem with 2 is that it does not prevent the compiler from
caching *mem into a local variable, which would break atomicity.

This is fixed in trunk already where we could change the API to 1, but
not in 1.x.
Anyone opposed to the attached patch (for 1.8.x only then)?

Regards;
Yann.

[1] https://bz.apache.org/bugzilla/show_bug.cgi?id=50731#c2
Index: atomic/netware/apr_atomic.c
===
--- atomic/netware/apr_atomic.c	(revision 1902233)
+++ atomic/netware/apr_atomic.c	(working copy)
@@ -72,6 +72,11 @@ APR_DECLARE(void *) apr_atomic_casptr(volatile voi
 return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
 }
 
+APR_DECLARE(void *) apr_atomic_casptr2(void *volatile *mem, void *with, const void *cmp)
+{
+return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 return (void*)atomic_xchg((unsigned long *)mem,(unsigned long)with);
Index: atomic/os390/atomic.c
===
--- atomic/os390/atomic.c	(revision 1902233)
+++ atomic/os390/atomic.c	(working copy)
@@ -94,6 +94,15 @@ void *apr_atomic_casptr(volatile void **mem_ptr,
_ptr);
  return (void *)cmp_ptr;
 }
+void *apr_atomic_casptr2(void *volatile *mem_ptr,
+ void *swap_ptr,
+ const void *cmp_ptr)
+{
+ __cs1(_ptr, /* automatically updated from mem on __cs1 failure  */
+   mem_ptr,  /* set from swap when __cs1 succeeds*/
+   _ptr);
+ return (void *)cmp_ptr;
+}
 #elif APR_SIZEOF_VOIDP == 8
 void *apr_atomic_casptr(volatile void **mem_ptr,
 void *swap_ptr,
@@ -104,6 +113,15 @@ void *apr_atomic_casptr(volatile void **mem_ptr,
_ptr);  
  return (void *)cmp_ptr;
 }
+void *apr_atomic_casptr2(void *volatile *mem_ptr,
+ void *swap_ptr,
+ const void *cmp_ptr)
+{
+ __csg(_ptr, /* automatically updated from mem on __csg failure  */
+   mem_ptr,  /* set from swap when __csg succeeds*/
+   _ptr);  
+ return (void *)cmp_ptr;
+}
 #else
 #error APR_SIZEOF_VOIDP value not supported
 #endif /* APR_SIZEOF_VOIDP */
Index: atomic/unix/builtins.c
===
--- atomic/unix/builtins.c	(revision 1902234)
+++ atomic/unix/builtins.c	(working copy)
@@ -121,6 +121,16 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 #endif
 }
 
+APR_DECLARE(void*) apr_atomic_casptr2(void *volatile *mem, void *ptr, const void *cmp)
+{
+#if HAVE__ATOMIC_BUILTINS
+__atomic_compare_exchange_n(mem, (void *), ptr, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+return (void *)cmp;
+#else
+return (void *)__sync_val_compare_and_swap(mem, (void *)cmp, ptr);
+#endif
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *ptr)
 {
 #if HAVE__ATOMIC_BUILTINS
Index: atomic/unix/ia32.c
===
--- atomic/unix/ia32.c	(revision 1902233)
+++ atomic/unix/ia32.c	(working copy)
@@ -111,6 +111,24 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 return prev;
 }
 
+APR_DECLARE(void*) apr_atomic_casptr2(void *volatile *mem, void *with, const void *cmp)
+{
+void *prev;
+#if APR_SIZEOF_VOIDP == 4
+asm volatile ("lock; cmpxchgl %2, %1"
+  : "=a" (prev), "=m" (*mem)
+  : "r" (with), "m" (*mem), "0" (cmp));
+#elif APR_SIZEOF_VOIDP == 8
+asm volatile ("lock; cmpxchgq %q2, %1"
+  : "=a" (prev), "=m" (*mem)
+  : "r" ((unsigned long)with), "m" (*mem),
+"0" ((unsigned long)cmp));
+#else
+#error APR_SIZEOF_VOIDP value not supported
+#endif
+return prev;
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 void *prev;
Index: atomic/unix/mutex.c
===
--- atomic/unix/mutex.c	(revision 1902233)
+++ atomic/unix/mutex.c	(working copy)
@@ -190,6 +190,21 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void
 return prev;
 }
 
+APR_DECLARE(void*) apr_atomic_casptr(void *volatile *mem, void *with, const void *cmp)
+{
+void *prev;
+DECLARE_MUTEX_LOCKED(mutex, *mem);
+
+prev = *(void **)mem;
+if (prev == cmp) {
+*mem = with;
+}
+
+MUTEX_UNLOCK(mutex);
+
+return prev;
+}
+
 APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
 {
 void *prev;

Re: GitHub Actions CI

2022-06-24 Thread Yann Ylavic
On Wed, Jun 22, 2022 at 2:26 PM Ivan Zhakov via dev  wrote:
>
> Suggestions and improvements are welcome.

I don't see any warning left in trunk and 1.8.x, possibly we'd have a
Windows /Werror build (or whatever appropriate msvc toggle is) to
better check the ones that would be introduced?

Regards;
Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2022-06-24 Thread Yann Ylavic
On Fri, Jun 24, 2022 at 11:56 AM Yann Ylavic  wrote:
>
> On Thu, Jun 23, 2022 at 8:50 PM Ruediger Pluem  wrote:
> >
> > On 6/23/22 5:12 PM, yla...@apache.org wrote:
> > >
> > > +/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int 
> > > >= 0 */
> > > +#define APR_BASE64_ENCODE_MAX 1610612733
> > > +
> > > +/* Above APR_BASE64_DECODE_MAX length the decoding can't fit in an int 
> > > >= 0 */
> > > +#define APR_BASE64_DECODE_MAX 2863311524u
> > > +
> >
> > Doesn't this depend on the storage size of int on the respective 
> > architecture and thus
> > should be derived from INT_MAX?
>
> There is no APR_INT_MAX unfortunately

By the way, I don't see much value in the
APR_{U,}INT{8,16,32,64}_{MIN,MAX} definitions we have, those values
have well known min/max (i.e. fixed).
I'd rather we define APR_{U,}{CHAR,SHORT,INT,LONG,LONGLONG}_MAX ones,
but without C99 (stdint.h, though most if not all platforms should
have this header now) it may be tricky (if not impossible) to define
them portably..

>
> Regards;
> Yann.


Re: svn commit: r1902206 - /apr/apr/trunk/encoding/apr_base64.c

2022-06-24 Thread Yann Ylavic
On Thu, Jun 23, 2022 at 8:50 PM Ruediger Pluem  wrote:
>
> On 6/23/22 5:12 PM, yla...@apache.org wrote:
> >
> > +/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int >= 
> > 0 */
> > +#define APR_BASE64_ENCODE_MAX 1610612733
> > +
> > +/* Above APR_BASE64_DECODE_MAX length the decoding can't fit in an int >= 
> > 0 */
> > +#define APR_BASE64_DECODE_MAX 2863311524u
> > +
>
> Doesn't this depend on the storage size of int on the respective architecture 
> and thus
> should be derived from INT_MAX?

There is no APR_INT_MAX unfortunately, I could do something like:

#if APR_HAVE_STDINT_H /* C99, but maintainer-mode is C89 */
#include 
#define APR_BASE64_LEN_MAX INT_MAX
#else
#define APR_BASE64_LEN_MAX APR_INT32_MAX
#endif

and use APR_BASE64_LEN_MAX instead of APR_INT32_MAX here and there,
but I doubt there are any architectures (we care about) where
sizeof(int) != 4.
I don't think we support < 32bit archs, do we?
For >= 32bit archs, of the 5 data models (LP32, ILP32, ILP64, LLP64
and LP64), only LP32 (i.e. WIN16 API, Apple Macintosh) and ILP64 ([1]
mentions HAL Computer Systems port of Solaris to the SPARC64) don't
have 32bit ints, and I don't think we care about those either.

So we should be safe assuming ints are 32bit?

Regards;
Yann.

[1] https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models


Re: svn commit: r1902196 - /apr/apr/trunk/json/apr_json_decode.c

2022-06-23 Thread Yann Ylavic
On Thu, Jun 23, 2022 at 5:57 PM Ruediger Pluem  wrote:
>
> On 6/23/22 1:43 PM, yla...@apache.org wrote:
> >
> > --- apr/apr/trunk/json/apr_json_decode.c (original)
> > +++ apr/apr/trunk/json/apr_json_decode.c Thu Jun 23 11:43:05 2022
> > @@ -353,7 +353,7 @@ static apr_status_t apr_json_decode_arra
> >  apr_json_value_t * array)
> >  {
> >  apr_status_t status = APR_SUCCESS;
> > -apr_size_t count = 0;
> > +int count = 0;
>
> Wouldn't we need to guard against overflow then?

Probably yes, r1902207.

Thanks for the review;
Yann.


Re: GitHub Actions CI

2022-06-22 Thread Yann Ylavic
On Thu, Jun 23, 2022 at 1:55 AM Eric Covener  wrote:
>
> On Wed, Jun 22, 2022 at 7:53 PM Yann Ylavic  wrote:
> >
> > On Thu, Jun 23, 2022 at 1:14 AM Eric Covener  wrote:
> > >
> > > On Wed, Jun 22, 2022 at 10:30 AM Yann Ylavic  wrote:
> > > >
> > > > On Wed, Jun 22, 2022 at 2:26 PM Ivan Zhakov via dev 
> > > >  wrote:
> > > > >
> > > > > As far I understand Apache Infra recommends to migrate Continuous 
> > > > > Integration builds from Travis to GitHub Actions.
> > > > >
> > > > > I've added initial configuration for GitHub Actions for APR project:
> > > > > https://svn.apache.org/repos/asf/apr/apr/trunk/.github/workflows/
> > > > >
> > > > > GitHub supports Linux, macOS and Windows runners.
> > > >
> > > > Nice work Ivan, thanks a bunch!
> > > >
> > > > Regards;
> > > > Yann.
> > > >
> > > > PS: now the macos guys have some work
> > > > (https://github.com/apache/apr/runs/7004338300?check_suite_focus=true)
> > >
> > > I think on mac we do not have xml2-config and build/xml.m4 does not
> > > actually set xml2_LIBS to anything when xml2 is auto-detected.
> > > I think a similar path is wrong when --with-xml2 passes a dir instead
> > > of a path to xml2-config.
> > >
> > > I am testing this which seemed to just work for the no xml2 args at
> > > all case w/ no xml2-config:
> >
> > Looks good to me, though I can't test on macos..
> >
> > apr_file_datasync() is failing in test_datasync_on_stream() with errno=45:
> > https://github.com/apache/apr/runs/7014421531?check_suite_focus=true#step:6:297
> > We already ignore EINVAL which is returned by Linux (meaning ENOTIMPL
> > there IIRC), any idea what errno=45 is on macos?
>
> ENOTSUP
> 45: Operation not supported

Thanks, looks like we can ignore that one too (r1902180).


Re: GitHub Actions CI

2022-06-22 Thread Yann Ylavic
On Thu, Jun 23, 2022 at 1:14 AM Eric Covener  wrote:
>
> On Wed, Jun 22, 2022 at 10:30 AM Yann Ylavic  wrote:
> >
> > On Wed, Jun 22, 2022 at 2:26 PM Ivan Zhakov via dev  
> > wrote:
> > >
> > > As far I understand Apache Infra recommends to migrate Continuous 
> > > Integration builds from Travis to GitHub Actions.
> > >
> > > I've added initial configuration for GitHub Actions for APR project:
> > > https://svn.apache.org/repos/asf/apr/apr/trunk/.github/workflows/
> > >
> > > GitHub supports Linux, macOS and Windows runners.
> >
> > Nice work Ivan, thanks a bunch!
> >
> > Regards;
> > Yann.
> >
> > PS: now the macos guys have some work
> > (https://github.com/apache/apr/runs/7004338300?check_suite_focus=true)
>
> I think on mac we do not have xml2-config and build/xml.m4 does not
> actually set xml2_LIBS to anything when xml2 is auto-detected.
> I think a similar path is wrong when --with-xml2 passes a dir instead
> of a path to xml2-config.
>
> I am testing this which seemed to just work for the no xml2 args at
> all case w/ no xml2-config:

Looks good to me, though I can't test on macos..

apr_file_datasync() is failing in test_datasync_on_stream() with errno=45:
https://github.com/apache/apr/runs/7014421531?check_suite_focus=true#step:6:297
We already ignore EINVAL which is returned by Linux (meaning ENOTIMPL
there IIRC), any idea what errno=45 is on macos?

Regards;
Yann.


Re: Spurious testreslist failures on Windows (was Re: GitHub Actions CI)

2022-06-22 Thread Yann Ylavic
On Wed, Jun 22, 2022 at 5:57 PM Ivan Zhakov  wrote:
>
> On Wed, 22 Jun 2022 at 17:29, Yann Ylavic  wrote:
>
>>
>> PS: now the macos guys have some work
>> (https://github.com/apache/apr/runs/7004338300?check_suite_focus=true)
>> :)
>
>
> Also testreslist fails sometimes on Windows:
> https://github.com/apache/apr/runs/7003387964?check_suite_focus=true
> [[[
> 48/77 Test #48: testreslist ..***Failed 1.05 sec
> testreslist : Line 258: expected <10>, but saw <11>
> Line 258: expected <10>, but saw <12>
> FAILED 2 of 3
> Failed Tests Total Fail Failed %
> ===
> testreslist 3 2 66.67%
> ]]]
>
> Sometimes it works as expected:
> https://github.com/apache/apr/actions/runs/2542369041
>
> Anyone have any ideas why it may happen?

Possibly fixed in r1902169.
AIUI it was apr_sleep(RESLIST_TTL / RESLIST_HMAX), i.e. apr_sleep(17)
thus Sleep(0) on Windows, which is not enough for the reslist entries
to expire.
By rounding up to Sleep(1) instead, the last build passed, we'll see
the next ones.. unless you can reproduce the failure locally with
r1902169 already?

Regards;
Yann.


>
> --
> Ivan Zhakov


Re: GitHub Actions CI

2022-06-22 Thread Yann Ylavic
On Wed, Jun 22, 2022 at 2:26 PM Ivan Zhakov via dev  wrote:
>
> As far I understand Apache Infra recommends to migrate Continuous Integration 
> builds from Travis to GitHub Actions.
>
> I've added initial configuration for GitHub Actions for APR project:
> https://svn.apache.org/repos/asf/apr/apr/trunk/.github/workflows/
>
> GitHub supports Linux, macOS and Windows runners.

Nice work Ivan, thanks a bunch!

Regards;
Yann.

PS: now the macos guys have some work
(https://github.com/apache/apr/runs/7004338300?check_suite_focus=true)
:)


Re: svn commit: r1902143 - /apr/apr/trunk/.github/workflows/linux.yml

2022-06-22 Thread Yann Ylavic
On Wed, Jun 22, 2022 at 12:35 AM Ivan Zhakov  wrote:
>
> I see two runs for every commit, but one is for Windows and another is for 
> Linux. Do I miss something?

No, brain fart all along on my side..

Regards;
Yann.


Re: svn commit: r1902143 - /apr/apr/trunk/.github/workflows/linux.yml

2022-06-21 Thread Yann Ylavic
On Tue, Jun 21, 2022 at 6:21 PM Ivan Zhakov  wrote:
>
> On Tue, 21 Jun 2022 at 19:16, Yann Ylavic  wrote:
>>
>> On Tue, Jun 21, 2022 at 5:58 PM Ivan Zhakov  wrote:
>> >
>> > On Tue, 21 Jun 2022 at 18:33, Yann Ylavic  wrote:
>> >>
>> >> Hi Ivan,
>> >>
>> >> I'm responding randomly to one of your ci commits, first to say
>> >> thanks, really nice and valuable work!
>> >>
>> >> I have a question too :) Sorry if it's premature, but I'm also
>> >> wondering why we don't see the outputs of the jobs in the github UI,
>> >> for instance in [1] for both succeeding and failing jobs the details
>> >> of the steps shows "Error:" only without more output (i.e. something
>> >> that could help us fix errors).
>> >> Do you know if there is a way to show the stdout/stderr of the
>> >> commands/scripts instead?
>> >>
>> > I see error output in testlog:
>>
>> Ah yes, I actually expected the outputs to be viewable by developing
>> the failing step (with the arrow), but the logs are actually available
>> via "View raw logs" in the configuration like icon..
>>
> I see outputs when click on the failing step. See screenshot in attachement.

Argh, sorry for the noise and your time, the blame is on a javascript
filter on my firefox :/

Well, I'm hesitating for my second remark now, but I'm going for it anyway :p
It seems that setting both branches like you did in this commit (r1902143):

-branches: [ "trunk" ]
+branches: [ "trunk", "1.8.x" ]

is causing two runs to be launched by gh actions whenever either
apr-trunk or apr-1.8.x is modified.
Don't we want "trunk" only in "trunk/.github/workflows/linux.yml" and
"1.8.x" only in "1.8.x/.github/workflows/linux.yml" instead?
I'm double checking but https://github.com/apache/apr/actions really
seem to show this behaviour, and somehow one of the build is failing..

Regards;
Yann.


Re: svn commit: r1902143 - /apr/apr/trunk/.github/workflows/linux.yml

2022-06-21 Thread Yann Ylavic
On Tue, Jun 21, 2022 at 5:58 PM Ivan Zhakov  wrote:
>
> On Tue, 21 Jun 2022 at 18:33, Yann Ylavic  wrote:
>>
>> Hi Ivan,
>>
>> I'm responding randomly to one of your ci commits, first to say
>> thanks, really nice and valuable work!
>>
>> I have a question too :) Sorry if it's premature, but I'm also
>> wondering why we don't see the outputs of the jobs in the github UI,
>> for instance in [1] for both succeeding and failing jobs the details
>> of the steps shows "Error:" only without more output (i.e. something
>> that could help us fix errors).
>> Do you know if there is a way to show the stdout/stderr of the
>> commands/scripts instead?
>>
> I see error output in testlog:

Ah yes, I actually expected the outputs to be viewable by developing
the failing step (with the arrow), but the logs are actually available
via "View raw logs" in the configuration like icon..

Thanks!


Re: svn commit: r1902143 - /apr/apr/trunk/.github/workflows/linux.yml

2022-06-21 Thread Yann Ylavic
Hi Ivan,

I'm responding randomly to one of your ci commits, first to say
thanks, really nice and valuable work!

I have a question too :) Sorry if it's premature, but I'm also
wondering why we don't see the outputs of the jobs in the github UI,
for instance in [1] for both succeeding and failing jobs the details
of the steps shows "Error:" only without more output (i.e. something
that could help us fix errors).
Do you know if there is a way to show the stdout/stderr of the
commands/scripts instead?

Regards;
Yann.

[1] https://github.com/apache/apr/runs/6982048399?check_suite_focus=true


Re: svn commit: r1902120 - in /apr/apr/branches/1.8.x: ./ test/testfile.c

2022-06-21 Thread Yann Ylavic
On Mon, Jun 20, 2022 at 11:57 PM  wrote:
>
> Author: ivan
> Date: Mon Jun 20 21:57:13 2022
> New Revision: 1902120
>
> URL: http://svn.apache.org/viewvc?rev=1902120=rev
>
[]
> --- apr/apr/branches/1.8.x/test/testfile.c (original)
> +++ apr/apr/branches/1.8.x/test/testfile.c Mon Jun 20 21:57:13 2022
[]
> @@ -1298,8 +1366,7 @@ abts_suite *testfile(abts_suite *suite)
>  abts_run_test(suite, test_fail_read_flush, NULL);
>  abts_run_test(suite, test_buffer_set_get, NULL);
>  abts_run_test(suite, test_xthread, NULL);
> -abts_run_test(suite, test_datasync_on_file, NULL);
> -abts_run_test(suite, test_datasync_on_stream, NULL);

Were these two removed intentionally? This causes the below warnings
at least currently:

testfile.c:1243:13: error: ‘test_datasync_on_stream’ defined but not
used [-Werror=unused-function]
testfile.c:1222:13: error: ‘test_datasync_on_file’ defined but not
used [-Werror=unused-function]

> +abts_run_test(suite, test_append, NULL);
>
>  return suite;
>  }

Regards;
Yann.


Re: Need Pointers on Cores.

2022-03-29 Thread Yann Ylavic
Hi,

On Mon, Mar 28, 2022 at 2:50 PM Ramapandi Muniyasamy -X (ramapmun -
WIPRO LIMITED at Cisco)  wrote:
>
> I am getting a crash when I am newly migrating to openssl 1.1.1l with version 
> 2.4.39

You need to re-build httpd with the new openssl (./configure
--with-openssl=/path/to/openssl 1.1.1l ...), and verify that httpd is
linked to the new openssl at runtime (`ldd modules/mod_ssl.so` should
show the new paths for openssl, and/or LD_LIBRARY_PATH should be
used).


Regards;
Yann.


Re: svn commit: r1897207 - in /apr/apr/trunk: include/apr_thread_proc.h threadproc/beos/thread.c threadproc/netware/thread.c threadproc/os2/thread.c threadproc/unix/thread.c threadproc/win32/thread.c

2022-02-08 Thread Yann Ylavic
On Tue, Feb 8, 2022 at 7:56 PM Evgeny Kotkov
 wrote:
>
> Yann Ylavic  writes:
>
> > +APR_DECLARE(apr_status_t) apr_thread_current_create(apr_thread_t **current,
> > +apr_threadattr_t *attr,
> > +apr_pool_t *pool)
> > +{
> > +apr_status_t stat;
> > +
> > +*current = apr_thread_current();
> > +if (*current) {
> > +return APR_EEXIST;
> > +}
> > +
> > +stat = alloc_thread(current, attr, NULL, NULL, pool);
> > +if (stat != APR_SUCCESS) {
> > +return stat;
> > +}
> > +
> > +if (!(attr && attr->detach)) {
> > +(*new)->td = apr_os_thread_current();
> > +}
>
> Hi Yann,
>
> It looks like this hunk doesn't compile on Windows:
>
>   …\threadproc\win32\thread.c(193): error C2065: 'new': undeclared identifier
>   …\threadproc\win32\thread.c(193): error C2100: illegal indirection
>   …\threadproc\win32\thread.c(193): error C2223: left of '->td' must point
>   to struct/union

Thanks, hopefully fixed in r1897879.


Regards;
Yann.


Re: svn commit: r1897209 - in /apr/apr/branches/1.7.x: ./ include/apr_pools.h memory/unix/apr_pools.c

2022-01-20 Thread Yann Ylavic
On Thu, Jan 20, 2022 at 4:37 PM Yann Ylavic  wrote:
>
> On Thu, Jan 20, 2022 at 3:56 PM William A Rowe Jr  wrote:
> >
> > On Thu, Jan 20, 2022 at 8:50 AM Eric Covener  wrote:
> > >
> > > > Code that will compile on 1.7.1 release
> > > > still won't compile on 1.7.0, unless I misunderstand something.
> > >
> > > Is it a requirement in this direction?
> > > https://apr.apache.org/versioning.html says "later versions"
> >
> > That's why I raise the question, I don't have the authoritative answer.
> >
> > Our SVN participants who adopted and recommended strongly that
> > APR follow the semantic versioning [1] approach so they could -also-
> > adopt it probably feel more strongly about this.
>
> It was proposed in another thread to add the APU macros to 1.7.x to
> ease later migration to 2.x, I don't think that adding these apr_pool_
> macros can have more compat issues..

My bad, re-reading the thread the proposal was a compat apu_ -> apr_
layer in APR *util* 1.7.x, yet since apr-util 1.7.0 is released
already it would be the same kind of compat issue.


>
>
> Cheers;
> Yann.


Re: svn commit: r1897209 - in /apr/apr/branches/1.7.x: ./ include/apr_pools.h memory/unix/apr_pools.c

2022-01-20 Thread Yann Ylavic
On Thu, Jan 20, 2022 at 3:56 PM William A Rowe Jr  wrote:
>
> On Thu, Jan 20, 2022 at 8:50 AM Eric Covener  wrote:
> >
> > > Code that will compile on 1.7.1 release
> > > still won't compile on 1.7.0, unless I misunderstand something.
> >
> > Is it a requirement in this direction?
> > https://apr.apache.org/versioning.html says "later versions"
>
> That's why I raise the question, I don't have the authoritative answer.
>
> Our SVN participants who adopted and recommended strongly that
> APR follow the semantic versioning [1] approach so they could -also-
> adopt it probably feel more strongly about this.

It was proposed in another thread to add the APU macros to 1.7.x to
ease later migration to 2.x, I don't think that adding these apr_pool_
macros can have more compat issues..


Cheers;
Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-19 Thread Yann Ylavic
On Thu, Jan 13, 2022 at 7:04 PM Ivan Zhakov  wrote:
>
> On Fri, 7 Jan 2022 at 17:33, Yann Ylavic  wrote:
> >
> > I think that most if not all of the changes to 1.7.x since 1.7.0 are
> > fixes for bugs that were there before 1.7 already, not regressions
> > introduced by 1.7.0.
>
> Agreed on the bugfix/regressions part. I have misunderstood that
> r1896510 is a bugfix, perhaps, due to its size, and was thinking that
> it adds new functionality.

So after reverting r1896510, the reported bug in [1] is still
addressed by r1894916, but only on unixes then.

[1] https://lists.apache.org/thread/mgosgwpqpxqrhh1q06z9okqgfqr46q24


Re: svn commit: r1897021 - /apr/apr/branches/1.8.x/

2022-01-19 Thread Yann Ylavic
On Fri, Jan 14, 2022 at 1:59 AM William A Rowe Jr  wrote:
>
> A quick review of nm against libapr-1.so between 1.7.0 and 1.7.x
> indicates that 1.7.1
> isn't releasable as-is. Any hints?
>
> +T apr_pool_find
> +T apr_pool_join
> +T apr_pool_lock
> +T apr_pool_num_bytes

These should have disappeared with r1897209.

> +T apr__pool_unmanage

And this one with r1897210.


Cheers;
Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-19 Thread Yann Ylavic
On Fri, Jan 14, 2022 at 4:20 PM Ivan Zhakov  wrote:
>
> 1. Revert this change from 1.7.x

Done in r1897222.

Regards;
Yann.


Re: svn commit: r1897208 - in /apr/apr/branches/win32-pollset-wakeup-no-file-socket-emulation: file_io/win32/ include/arch/unix/ include/arch/win32/ poll/unix/

2022-01-19 Thread Yann Ylavic
On Wed, Jan 19, 2022 at 5:42 PM  wrote:
>
> Author: ivan
> Date: Wed Jan 19 16:41:59 2022
> New Revision: 1897208
>
> URL: http://svn.apache.org/viewvc?rev=1897208=rev
> Log:
> On 'win32-pollset-wakeup-no-file-socket-emulation' branch:
>
> Windows: For the pollset wakeup, use apr_socket_t directly instead of using a
> socket disguised as an apr_file_t.
[]
>
> -apr_status_t apr_file_socket_pipe_create(apr_file_t **in,
> - apr_file_t **out,
> +apr_status_t apr_file_socket_pipe_create(apr_socket_t **in,
> + apr_socket_t **out,
>   apr_pool_t *p)
>  {
>  apr_status_t rv;
>  SOCKET rd;
>  SOCKET wr;
>
> +*in = NULL;
> +*out = NULL;
> +
>  if ((rv = create_socket_pipe(, )) != APR_SUCCESS) {
>  return rv;
>  }
> -(*in) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
> -(*in)->pool = p;
> -(*in)->fname = NULL;
> -(*in)->ftype = APR_FILETYPE_SOCKET;
> -(*in)->timeout = 0; /* read end of the pipe is non-blocking */
> -(*in)->ungetchar = -1;
> -(*in)->eof_hit = 0;
> -(*in)->filePtr = 0;
> -(*in)->bufpos = 0;
> -(*in)->dataRead = 0;
> -(*in)->direction = 0;
> -(*in)->pOverlapped = NULL;
> -(*in)->filehand = (HANDLE)rd;
> -
> -(*out) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t));
> -(*out)->pool = p;
> -(*out)->fname = NULL;
> -(*out)->ftype = APR_FILETYPE_SOCKET;
> -(*out)->timeout = -1;
> -(*out)->ungetchar = -1;
> -(*out)->eof_hit = 0;
> -(*out)->filePtr = 0;
> -(*out)->bufpos = 0;
> -(*out)->dataRead = 0;
> -(*out)->direction = 0;
> -(*out)->pOverlapped = NULL;
> -(*out)->filehand = (HANDLE)wr;
> +apr_os_sock_put(in, , p);
> +apr_os_sock_put(out, , p);

I think that the *in apr_socket and the underlying socket descriptor
are not aligned w.r.t. non-blocking.
We probably need to call apr_socket_timeout_set(*in, 0) here to make
that happen, thus remove the last ioctlsocket() in
create_socket_pipe() that sets the descriptor non-blocking before
leaving (which would be useless now).

Something like the below on top of your branch?

Index: file_io/win32/pipe.c
===
--- file_io/win32/pipe.c(revision 1897212)
+++ file_io/win32/pipe.c(working copy)
@@ -381,14 +381,7 @@ static apr_status_t create_socket_pipe(SOCKET *rd,
 goto cleanup;
 }
 if (nrd == (int)sizeof(uid) && memcmp(iid, uid, sizeof(uid)) == 0) {
-/* Got the right identifier, put the poll()able read side of
- * the pipe in nonblocking mode and return.
- */
-bm = 1;
-if (ioctlsocket(*rd, FIONBIO, ) == SOCKET_ERROR) {
-rv = apr_get_netos_error();
-goto cleanup;
-}
+/* Got the right identifier, return. */
 break;
 }
 closesocket(*rd);
@@ -438,6 +431,9 @@ apr_status_t apr_file_socket_pipe_create(apr_socke
 apr_os_sock_put(in, , p);
 apr_os_sock_put(out, , p);

+/* read end of the pipe is non-blocking */
+apr_socket_timeout_set(*in, 0);
+
 apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup,
   apr_pool_cleanup_null);
 apr_pool_cleanup_register(p, (void *)(*out), socket_pipe_cleanup,
--


Regards;
Yann.


Re: svn commit: r1895508 - in /apr/apr/trunk: dso/win32/ file_io/win32/ locks/win32/ misc/unix/ misc/win32/ network_io/unix/ network_io/win32/ passwd/ shmem/win32/ threadproc/win32/ time/win32/ user/w

2022-01-19 Thread Yann Ylavic
On Thu, Dec 2, 2021 at 10:21 PM  wrote:
>
> Author: mturk
> Date: Thu Dec  2 21:21:18 2021
> New Revision: 1895508
>
> URL: http://svn.apache.org/viewvc?rev=1895508=rev
> Log:
> Stage 3 in dismantling _WIN32_WCE ... cleanup code
>
[]
> Modified: apr/apr/trunk/threadproc/win32/thread.c
> URL: 
> http://svn.apache.org/viewvc/apr/apr/trunk/threadproc/win32/thread.c?rev=1895508=1895507=1895508=diff
> ==
> --- apr/apr/trunk/threadproc/win32/thread.c (original)
> +++ apr/apr/trunk/threadproc/win32/thread.c Thu Dec  2 21:21:18 2021
> @@ -138,21 +138,12 @@ APR_DECLARE(apr_status_t) apr_thread_cre
>  /* Use 0 for default Thread Stack Size, because that will
>   * default the stack to the same size as the calling thread.
>   */
> -#ifndef _WIN32_WCE
>  if ((handle = (HANDLE)_beginthreadex(NULL,
>  (DWORD) (attr ? attr->stacksize : 0),
>  (unsigned int (APR_THREAD_FUNC *)(void 
> *))dummy_worker,
>  (*new), 0, )) == 0) {
>  return APR_FROM_OS_ERROR(_doserrno);
>  }
> -#else
> -   if ((handle = CreateThread(NULL,
> -attr && attr->stacksize > 0 ? attr->stacksize : 0,
> -(unsigned int (APR_THREAD_FUNC *)(void 
> *))dummy_worker,
> -(*new), 0, )) == 0) {
> -return apr_get_os_error();
> -}
> -#endif

I'm a bit surprised that _WIN32_WCE used CreateThread() while more
recent ones use _beginthreadex(), shouldn't it be the opposite?
CreateThread() aligns more with the usual/modern naming convention on Windows..

Regards;
Yann.


Re: apr/trunk netware and os2

2022-01-17 Thread Yann Ylavic
On Tue, Jan 18, 2022 at 2:08 AM Yann Ylavic  wrote:
>
> On Tue, Nov 30, 2021 at 11:46 PM Mladen Turk  wrote:
> >
> > According to Wikipedia NetWare was discontinued in 2009
> > and OS/2 in 2001, so if anyone can explain why we have
> > those in trunk/apr-2 (that will be hopefully released one day).
>
> What about BeOS? We have some specifics for that too.

Ditto for os390, also present in include/arch.

>
> Regards;
> Yann.


Re: apr/trunk netware and os2

2022-01-17 Thread Yann Ylavic
On Tue, Nov 30, 2021 at 11:46 PM Mladen Turk  wrote:
>
> According to Wikipedia NetWare was discontinued in 2009
> and OS/2 in 2001, so if anyone can explain why we have
> those in trunk/apr-2 (that will be hopefully released one day).

What about BeOS? We have some specifics for that too.

Regards;
Yann.


Re: svn commit: r1897021 - /apr/apr/branches/1.8.x/

2022-01-15 Thread Yann Ylavic
On Sat, Jan 15, 2022 at 2:00 AM William A Rowe Jr  wrote:
>
> On Fri, Jan 14, 2022 at 5:07 AM Yann Ylavic  wrote:
> >
> > On Fri, Jan 14, 2022 at 1:59 AM William A Rowe Jr  wrote:
> > >
> > > A quick review of nm against libapr-1.so between 1.7.0 and 1.7.x
> > > indicates that 1.7.1
> > > isn't releasable as-is. Any hints?
> > >
> > > +T apr_pool_find
> > > +T apr_pool_join
> > > +T apr_pool_lock
> > > +T apr_pool_num_bytes
> >
> > Those come from r1863234 [1], possibly we can let them as empty macros
> > in 1.7.x and still add the ones for apr_pool_join() and
> > apr_pool_num_bytes() which were missing for !APR_POOL_DEBUG?
> > Yet it might make apps using them from 1.7.1 (w/o #ifdef
> > APR_POOL_DEBUG) not compilable with 1.7.0 (though still ABI compatible
> > with all 1.7.x), but no one would be able to use them as function
> > pointers for instance, which would be a ABI/runtime breakage. Could
> > that hurt actually?
>
> Worse, a macro -> function without a major bump? That's awkward. Remember
> the .so remains loadable throughout apr-1.so lifespan.

Yes I see your point for macro -> function.

>
> Afraid this has to be rejected outright on apr-1.7. There are contracts with 
> our
> developers that they can load the 1.7.0 .so in place of a binary built
> against 1.7.2
> and **nothing bad can happen** (other than the 'whoops - you wanted
> that bug fix.)
> The binaries won't fail to load. This sets us up for failure, and why put 
> macro
> stubs here if they will be no-ops? What purpose is this serving to break what
> has been a pretty reliable solution in developers' hands?

What I'm thinking is to revert r1863234 in 1.7.x, thus back to
r1863233's apr_pools.h code do:

Index: include/apr_pools.h
===
--- include/apr_pools.h(revision 1863233)
+++ include/apr_pools.h(working copy)
@@ -799,6 +799,16 @@ APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool,
 #endif
 #define apr_pool_join(a,b)

+#ifdef apr_pool_find
+#undef apr_pool_find
+#endif
+#define apr_pool_find(mem) (NULL)
+
+#ifdef apr_pool_num_bytes
+#undef apr_pool_num_bytes
+#endif
+#define apr_pool_num_bytes(p, rec) ((apr_size_t)0)
+
 #ifdef apr_pool_lock
 #undef apr_pool_lock
 #endif
--

So yes, that's two new macros so any (new) code using them when
!APR_POOL_DEBUG would build with 1.7.1 but not 1.7.0, though it would
_run_ with both apr-1.7.[01].so (no ABI change).

>
> See https://apr.apache.org/versioning.html
>
> What's the actual reservation about 1.8.0? (After a prompt 1.7.1)?

No reservation if we are able to release faster than we used to lately..
I also advocate for people who work on the APR code, for their changes
to be integrated (as much/reasonable as possible) in the version they
actually use.

>
>
> > > +T apr__pool_unmanage
> >
> > That one is for internal use only (from [2]), not APR_DECLAREd so
> > should be fine?
>
> Still, exported on linux, curious how to avoid that. Even as an
> internal, not an issue
> in 1.8.0, an issue on 1.7.x branch now.

That's no different than other arch/private yet exported functions,
but yes introducing it in a patch release makes an app build with
1.7.1 not runnable with apr-1.7.0.so.

This function serves a real bugfix though, apr threads had real pool
lifetime issues before that (raised by the httpd tests suite built/run
under AddressSanitizer).
I don't remember all the details of the change but possibly for this
particular apr__pool_unmanage() introduction it's only about
apr_thread_detach() correctness, so the other option might be to
APR_ENOTIMPL there in 1.7.1, or leave a known defect, not sure it
helps more..

At this point I question the relevance of releasing 1.7.1 at all, I
think most people will be interested in 1.8.0 and I'd advise distros
to upgrade to that too. Who will be using 1.7.1? What is the rationale
for releasing both and how confusing will that be?
Hopefully Ivan can address the Windows apr_file_t (as suitable) soon
enough, in this case could we release 1.8.0 only?

Cheers;
Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-14 Thread Yann Ylavic
On Fri, Jan 14, 2022 at 4:40 PM Yann Ylavic  wrote:
>
> On Fri, Jan 14, 2022 at 4:20 PM Ivan Zhakov  wrote:
> >
> > 1. Revert this change from 1.7.x
> > 2. Release 1.7.1
> > 3. Rework this code on trunk without changing the apr_file_t's behavior
> > 4. Backport it to 1.7.x/1.8.x
> >
> > And if this plan makes sense, I am ready to proceed with steps (1), (3) and 
> > (4).
>
> +1, not sure we'd later release both 1.7.2 and 1.8.0 later on,
> probably only the latter.

Btw, I don't think the _behaviour_ of apr_file_t changed, the
implementation of apr_file_socket_pipe did but it should be
transparent for the user.

>
> Cheers;
> Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-14 Thread Yann Ylavic
On Fri, Jan 14, 2022 at 4:20 PM Ivan Zhakov  wrote:
>
> 1. Revert this change from 1.7.x
> 2. Release 1.7.1
> 3. Rework this code on trunk without changing the apr_file_t's behavior
> 4. Backport it to 1.7.x/1.8.x
>
> And if this plan makes sense, I am ready to proceed with steps (1), (3) and 
> (4).

+1, not sure we'd later release both 1.7.2 and 1.8.0 later on,
probably only the latter.

Cheers;
Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-14 Thread Yann Ylavic
Hi Ivan;

On Thu, Jan 13, 2022 at 7:04 PM Ivan Zhakov  wrote:
>
> On Fri, 7 Jan 2022 at 17:33, Yann Ylavic  wrote:
> >
> > I was missing backport of r1895178, does r1896808 compile now?
> > (Sorry, no Windows at hand..).
> Yes, it builds now. Thanks!

Great, thanks for testing.

> >
> > I think that most if not all of the changes to 1.7.x since 1.7.0 are
> > fixes for bugs that were there before 1.7 already, not regressions
> > introduced by 1.7.0.
>
> Agreed on the bugfix/regressions part. I have misunderstood that
> r1896510 is a bugfix, perhaps, due to its size, and was thinking that
> it adds new functionality. But even with that in mind, I still think
> that the size of the change might be just too large for it to be an
> appropriate fit for a patch release.

The bugfix part is quite probable though still theoretical on the
httpd side. As you may know mpm_event makes heavy use of the wakeup
pipe with potentially plenty of worker threads waking up one listener
thread, and that should not block for obvious event scheme scalability
reasons. But there is actually no bug report about this since blocking
would not result in a deadlock and httpd users have not tested the new
implementation performance wise, yet. Theoretically it may happen..
So since mpm_event is unix(es) only, this change is mainly aimed at
fixing the unix implementation of the wakeup pipe (write a single byte
atomically/once until it's consumed), but that can't happen portably
on the APR side without adapting the Windows implementation given that
there is no synchronous/nonblocking ReadFile().
Using {Read,Write}File() on a SOCKET seems to be supported by Windows,
but if the SOCKET is set nonblocking it does not behave accordingly
(from what I could read on the subject), hence the switch to
WSA{Recv,Send}(). Note that there was already a special "pipe"
handling in Windows' apr_file_t, the "socket" one is just a third
case.
I don't find it too cumbersome personally, but if you have a better
option I'm all for it!

>
> Speaking of the change itself, I think that there might be an
> alternative to making the apr_file_t also handle sockets on Windows.
> It might be better to specifically change the pollset implementation
> so that on Windows it would add a socket and use it for wakeup,
> instead of using the socket disguised as a file.

AIUI, that's already what OS/2 does (using an UDP socket), having its
own apr_pollset_wakeup() implementation and its own draining directly
in apr_pollset_poll() instead of reusing the common
apr_poll_drain_wakeup_pipe(), which is the one performing the
apr_file_read() currently.
That's certainly an option for Windows too, and in that area it may be
interesting to look at an IOCB implementation for polling rather than
select (but that's probably another story given the different
semantics of IOCB vs epoll/kqueue..).

>
> If this alternative approach sounds fine, I could try to implement it.

Looks good to me, not sure it should block the current implementation
in 1.7.x though because AFAIK it passes the tests suite on Windows too
(which Mladen Turk made work and tried IIRC). The changes are not
trivial but quite straightforward given the previous/existing socket
as pipe implementation in apr_file_t.

But I don't want to push anything, mpm_event has worked like this for
quite some time now and it can probably wait for 1.8.x for this
supposed fix/improvement.


Regards;
Yann.


Re: svn commit: r1897021 - /apr/apr/branches/1.8.x/

2022-01-14 Thread Yann Ylavic
[plus [1] and [2] links..]

On Fri, Jan 14, 2022 at 12:06 PM Yann Ylavic  wrote:
>
> On Fri, Jan 14, 2022 at 1:59 AM William A Rowe Jr  wrote:
> >
> > A quick review of nm against libapr-1.so between 1.7.0 and 1.7.x
> > indicates that 1.7.1
> > isn't releasable as-is. Any hints?
> >
> > +T apr_pool_find
> > +T apr_pool_join
> > +T apr_pool_lock
> > +T apr_pool_num_bytes
>
> Those come from r1863234 [1], possibly we can let them as empty macros
> in 1.7.x and still add the ones for apr_pool_join() and
> apr_pool_num_bytes() which were missing for !APR_POOL_DEBUG?
> Yet it might make apps using them from 1.7.1 (w/o #ifdef
> APR_POOL_DEBUG) not compilable with 1.7.0 (though still ABI compatible
> with all 1.7.x), but no one would be able to use them as function
> pointers for instance, which would be a ABI/runtime breakage. Could
> that hurt actually?
>
> > +T apr__pool_unmanage
>
> That one is for internal use only (from [2]), not APR_DECLAREd so
> should be fine?

[1] https://svn.apache.org/r1863234
[2] https://svn.apache.org/r1884103


Re: svn commit: r1897021 - /apr/apr/branches/1.8.x/

2022-01-14 Thread Yann Ylavic
On Fri, Jan 14, 2022 at 1:59 AM William A Rowe Jr  wrote:
>
> A quick review of nm against libapr-1.so between 1.7.0 and 1.7.x
> indicates that 1.7.1
> isn't releasable as-is. Any hints?
>
> +T apr_pool_find
> +T apr_pool_join
> +T apr_pool_lock
> +T apr_pool_num_bytes

Those come from r1863234 [1], possibly we can let them as empty macros
in 1.7.x and still add the ones for apr_pool_join() and
apr_pool_num_bytes() which were missing for !APR_POOL_DEBUG?
Yet it might make apps using them from 1.7.1 (w/o #ifdef
APR_POOL_DEBUG) not compilable with 1.7.0 (though still ABI compatible
with all 1.7.x), but no one would be able to use them as function
pointers for instance, which would be a ABI/runtime breakage. Could
that hurt actually?

> +T apr__pool_unmanage

That one is for internal use only (from [2]), not APR_DECLAREd so
should be fine?


Regards;
Yann.


Re: APR 1.7.1 release?

2022-01-12 Thread Yann Ylavic
On Thu, Dec 23, 2021 at 7:37 AM William A Rowe Jr  wrote:
>
> On Fri, Dec 17, 2021 at 10:09 AM Yann Ylavic  wrote:
> >
> > On Fri, Sep 3, 2021 at 3:44 AM William A Rowe Jr  
> > wrote:
> > >
> > > But I'd be happier co-RM'ing this with a newer committer/PMC
> > > participant who wants to learn the ropes. Any volunteers?
> >
> > \o_ thanks for helping! Anytime for, maybe in early 2022 days?
>
> 1. Is that an offer?

Sure it is :) I'm happy to assist you in the release process and learn about it.
I looked at the release.sh script which is quite simple and the
preliminar tagging process from the previous release, but following
someone who knows is always better..

>
> In any case I see us shipping a minimal APR 1.7.x with the fixes at hand and 
> for
> Windows FS that frustrated some svn users. The scope of the unix domain socket
> enablement are probably late into January/early Feb. Unsure what other folks 
> are
> working on that fit into the 1.8 bump.

I already backported the unix socket changes to 1.7.x, though Ivan
objected already given the non trivial changes.
I'd like it to be in 1.7.1 (mainly because of the new atomic/once
wakeup which is useful for httpd's mpm_event usage), but not a strong
opinion either so I could revert it's an uncomfortable change.

Besides, current 1.7.x is not a minimal change already w.r.t. 1.7.0,
some not-so-trivial backports are to address issues raised by running
ASAN built APR and httpd through their test suites (namely apr_pool's
r1884100, apr_thread's r1884103, apr_thread_pool's r1884110).
Those have landed for quite some time now, but more eyes are always welcome.

>
> We all need to review APR-util 1.7.0-dev, to ensure it's ready. That
> could happen
> before year end, or early next year, depending on how stable it is.

+1

>
> So yes, I'd be grateful for your help, and more than happy to help you :)

Great, let's go whenever you have the time for it ;)


Cheers;
Yann.


Re: svn commit: r1893204 - in /apr/apr/trunk/file_io: os2/filedup.c unix/filedup.c win32/filedup.c

2022-01-07 Thread Yann Ylavic
On Fri, Jan 7, 2022 at 3:58 PM Ruediger Pluem  wrote:
>
> On 1/7/22 3:02 PM, Yann Ylavic wrote:
> >
> > Should we be consistent here then, and always use the passed in reqpool?
> > I.e. something like the below (on the current code):
>
> Maybe a good idea.

r1896812.

Thanks;
Yann.


Re: svn commit: r1896510 - in /apr/apr/branches/1.7.x: ./ file_io/win32/ include/arch/unix/ include/arch/win32/ network_io/os2/ poll/os2/ poll/unix/

2022-01-07 Thread Yann Ylavic
Hi Ivan,

On Fri, Jan 7, 2022 at 2:50 PM Ivan Zhakov  wrote:
>
> This change does not compile on Windows in APR 1.7.x:
> [[[
> file_io\win32\readwrite.c(325): error C2065: 'file': undeclared identifier
> file_io\win32\readwrite.c(325): error C2223: left of '->filehand' must
> point to struct/union

I was missing backport of r1895178, does r1896808 compile now?
(Sorry, no Windows at hand..).

>
> I also have a high-level objection against backporting this change to
> APR 1.7.x: IMHO APR 1.7.x is a stable branch and I think that only
> regression fixes should be backported to the stable branch. r1896510
> is a significant change and as far as I understand it's not a
> regression fix. So I think it would be better to revert r1896510 and
> release it as part of APR 2.0 (or 1.8.x).

I think that most if not all of the changes to 1.7.x since 1.7.0 are
fixes for bugs that were there before 1.7 already, not regressions
introduced by 1.7.0.

But I'm fine with switching to 1.8.x and releasing 1.8.0 if that's the
policy, not sure that 1.7.1 is needed then (and we'd need to revert
quite some changes in 1.7.x..).

Regards;
Yann.


Re: svn commit: r1893204 - in /apr/apr/trunk/file_io: os2/filedup.c unix/filedup.c win32/filedup.c

2022-01-07 Thread Yann Ylavic
On Fri, Sep 10, 2021 at 5:49 PM Yann Ylavic  wrote:
>
> On Fri, Sep 10, 2021 at 4:44 PM Ruediger Pluem  wrote:
> >
> > On 9/10/21 4:04 PM, Yann Ylavic wrote:
> > > Index: buckets/apr_buckets_file.c
> > > ===
> > > --- buckets/apr_buckets_file.c(revision 1893196)
> > > +++ buckets/apr_buckets_file.c(working copy)
> >
> > > @@ -223,11 +223,33 @@ APR_DECLARE(apr_status_t) apr_bucket_file_set_buf_
> > >  return APR_SUCCESS;
> > >  }
> > >
> > > -if (!apr_pool_is_ancestor(a->readpool, reqpool)) {
> > > -a->readpool = reqpool;
> > > +/* If the file is shared/split accross multiple buckets, this bucket 
> > > can't
> > > + * take exclusive ownership with apr_file_setaside() (thus 
> > > invalidating the
> > > + * current/old a->fd), let's apr_file_dup() in this case instead.
> > > + */
> > > +if (a->refcount.refcount > 1) {
> > > +apr_bucket_file *new;
> > > +apr_status_t rv;
> > > +
> > > +rv = apr_file_dup(, f, reqpool);
> > > +if (rv != APR_SUCCESS) {
> > > +return rv;
> > > +}
> > > +
> > > +new = apr_bucket_alloc(sizeof(*new), b->list);
> > > +memcpy(new, a, sizeof(*new));
> > > +new->refcount.refcount = 1;
> > > +new->readpool = reqpool;
> >
> > Why is the above no longer conditional on apr_pool_is_ancestor(a->readpool, 
> > reqpool) like in the else branch?
>
> Good question..
> Since we created a new apr_bucket_file and apr_file_t above with the
> given reqpool's lifetime, I thought the reads would use it too just
> like apr_bucket_file_make() uses the given pool.
>
> But I don't really understand in the first place why we need to keep
> the existing ->readpool if it's an ancestor of the given reqpool.
> It's been so from the very beginning of the reqpool parameter
> (r58312!), but if one wants to setaside on a subpool it may not be
> thread-safe to keep using the parent pool.
> While calling apr_file_setaside (or apr_file_dup now) makes sure that
> the (new) file has the requested lifetime, why use the parent pool for
> mmaping or !XTHREAD reopening the file?

Should we be consistent here then, and always use the passed in reqpool?
I.e. something like the below (on the current code):

Index: buckets/apr_buckets_file.c
===
--- buckets/apr_buckets_file.c(revision 1896509)
+++ buckets/apr_buckets_file.c(working copy)
@@ -239,7 +239,6 @@ static apr_status_t file_bucket_setaside(apr_bucke
 new = apr_bucket_alloc(sizeof(*new), b->list);
 memcpy(new, a, sizeof(*new));
 new->refcount.refcount = 1;
-new->readpool = reqpool;

 a->refcount.refcount--;
 a = b->data = new;
@@ -246,11 +245,9 @@ static apr_status_t file_bucket_setaside(apr_bucke
 }
 else {
 apr_file_setaside(, f, reqpool);
-if (!apr_pool_is_ancestor(a->readpool, reqpool)) {
-a->readpool = reqpool;
-}
 }
 a->fd = fd;
+a->readpool = reqpool;
 return APR_SUCCESS;
 }

>
> Regards;
> Yann.


Re: APR 1.7.1 release?

2021-12-17 Thread Yann Ylavic
Hi Bill,

On Fri, Sep 3, 2021 at 3:44 AM William A Rowe Jr  wrote:
>
> I'm willing to RM APR and APR-util 1.7 releases.

Any news on this?

>
> But I'd be happier co-RM'ing this with a newer committer/PMC
> participant who wants to learn the ropes. Any volunteers?

\o_ thanks for helping! Anytime for, maybe in early 2022 days?


Cheers;
Yann.


  1   2   3   4   5   >