From 62001839d5cd4187538a750752b3d7a30db4e2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Wed, 25 Oct 2017 13:01:22 +0200 Subject: Stop assuming that all schedulers are managed when updating msacc This fixes statistics_SUITE:msacc when dirty schedulers are used during the test. --- erts/emulator/beam/erl_msacc.h | 32 +++++++++++++++++++++++--------- erts/emulator/beam/erl_process.c | 16 ++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/erts/emulator/beam/erl_msacc.h b/erts/emulator/beam/erl_msacc.h index d64ef8c8b9..3f6273f214 100644 --- a/erts/emulator/beam/erl_msacc.h +++ b/erts/emulator/beam/erl_msacc.h @@ -279,18 +279,32 @@ void erts_msacc_init_thread(char *type, int id, int liberty); #define ERTS_MSACC_PUSH_STATE_M() \ ERTS_MSACC_DECLARE_CACHE(); \ ERTS_MSACC_PUSH_STATE_CACHED_M() -#define ERTS_MSACC_PUSH_STATE_CACHED_M() \ - __erts_msacc_state = ERTS_MSACC_IS_ENABLED_CACHED() ? \ - erts_msacc_get_state_m__(__erts_msacc_cache) : ERTS_MSACC_STATE_OTHER +#define ERTS_MSACC_PUSH_STATE_CACHED_M() \ + do { \ + if (ERTS_MSACC_IS_ENABLED_CACHED()) { \ + ASSERT(!__erts_msacc_cache->unmanaged); \ + __erts_msacc_state = erts_msacc_get_state_m__(__erts_msacc_cache); \ + } else { \ + __erts_msacc_state = ERTS_MSACC_STATE_OTHER; \ + } \ + } while(0) #define ERTS_MSACC_SET_STATE_M(state) \ ERTS_MSACC_DECLARE_CACHE(); \ ERTS_MSACC_SET_STATE_CACHED_M(state) -#define ERTS_MSACC_SET_STATE_CACHED_M(state) \ - if (ERTS_MSACC_IS_ENABLED_CACHED()) \ - erts_msacc_set_state_m__(__erts_msacc_cache, state, 1) -#define ERTS_MSACC_POP_STATE_M() \ - if (ERTS_MSACC_IS_ENABLED_CACHED()) \ - erts_msacc_set_state_m__(__erts_msacc_cache, __erts_msacc_state, 0) +#define ERTS_MSACC_SET_STATE_CACHED_M(state) \ + do { \ + if (ERTS_MSACC_IS_ENABLED_CACHED()) { \ + ASSERT(!__erts_msacc_cache->unmanaged); \ + erts_msacc_set_state_m__(__erts_msacc_cache, state, 1); \ + } \ + } while(0) +#define ERTS_MSACC_POP_STATE_M() \ + do { \ + if (ERTS_MSACC_IS_ENABLED_CACHED()) { \ + ASSERT(!__erts_msacc_cache->unmanaged); \ + erts_msacc_set_state_m__(__erts_msacc_cache, __erts_msacc_state, 0); \ + } \ + } while(0) #define ERTS_MSACC_PUSH_AND_SET_STATE_M(state) \ ERTS_MSACC_PUSH_STATE_M(); ERTS_MSACC_SET_STATE_CACHED_M(state) diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b72bac00c1..099aa02f10 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -3417,7 +3417,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) int thr_prgr_active = 1; erts_aint32_t flgs; #endif - ERTS_MSACC_PUSH_STATE_M(); + ERTS_MSACC_PUSH_STATE(); #ifdef ERTS_SMP ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(rq)); @@ -3542,9 +3542,9 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) - 1) + 1; } else timeout = -1; - ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_SLEEP); + ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_SLEEP); res = erts_tse_twait(ssi->event, timeout); - ERTS_MSACC_POP_STATE_M(); + ERTS_MSACC_POP_STATE(); current_time = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 : erts_get_monotonic_time(esdp); } while (res == EINTR); @@ -3743,12 +3743,12 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) ASSERT(!erts_port_task_have_outstanding_io_tasks()); - ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_CHECK_IO); + ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_CHECK_IO); LTTNG2(scheduler_poll, esdp->no, 0); erl_sys_schedule(0); - ERTS_MSACC_POP_STATE_M(); + ERTS_MSACC_POP_STATE(); if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) { ErtsMonotonicTime current_time = erts_get_monotonic_time(esdp); @@ -10350,7 +10350,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) | ERTS_PROC_LOCK_STATUS | ERTS_PROC_LOCK_TRACE)); - ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_OTHER); + ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_OTHER); #ifdef ERTS_SMP if (state & ERTS_PSFLG_FREE) { @@ -10642,7 +10642,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) case 0: /* No process at all */ default: ASSERT(qmask == 0); - ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_OTHER); + ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_OTHER); goto check_activities_to_run; } @@ -10766,7 +10766,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) } - ERTS_MSACC_SET_STATE_CACHED_M(ERTS_MSACC_STATE_EMULATOR); + ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_EMULATOR); #ifdef ERTS_SMP -- cgit v1.2.3 From 9b1f2439845e5627a00fb816244af06d77c2d70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Wed, 1 Nov 2017 16:53:51 +0100 Subject: Only apply EOS behaviors if there's pending data --- erts/emulator/nifs/common/zlib_nif.c | 5 ++--- lib/kernel/test/zlib_SUITE.erl | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c index fa29b4fb71..104e52754a 100644 --- a/erts/emulator/nifs/common/zlib_nif.c +++ b/erts/emulator/nifs/common/zlib_nif.c @@ -929,7 +929,7 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar return enif_raise_exception(env, am_not_initialized); } - if(d->eos_seen) { + if(d->eos_seen && enif_ioq_size(d->input_queue) > 0) { int res; switch(d->eos_behavior) { @@ -943,11 +943,10 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar } d->eos_seen = 0; + break; case EOS_BEHAVIOR_CUT: zlib_reset_input(d); - - return enif_make_tuple2(env, am_finished, enif_make_list(env, 0)); } } diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl index 1afcd155b3..b20d64ec6a 100644 --- a/lib/kernel/test/zlib_SUITE.erl +++ b/lib/kernel/test/zlib_SUITE.erl @@ -652,6 +652,11 @@ api_g_un_zip(Config) when is_list(Config) -> Concatenated = <>, ?m(Concatenated, zlib:gunzip([Comp, Comp])), + %% Don't explode if the uncompressed size is a perfect multiple of the + %% internal inflate chunk size. + ChunkSizedData = <<0:16384/unit:8>>, + ?m(ChunkSizedData, zlib:gunzip(zlib:gzip(ChunkSizedData))), + %% Bad CRC; bad length. BadCrc = bad_crc_data(), ?m(?EXIT(data_error),(catch zlib:gunzip(BadCrc))), -- cgit v1.2.3 From b1ce8325624d22fa34b76407932947a543754962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 7 Nov 2017 07:16:31 +0100 Subject: Emasculate writable binaries on entering an iovec The lack of this caused serious data corruption when a binary was altered after entering the queue. This went unnoticed because it was never used without erlang:iolist_to_iovec, which always emasculates binaries. --- erts/emulator/beam/erl_nif.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index ac4ecd77e5..8342070521 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -3488,6 +3488,10 @@ static void inspect_raw_binary_data(Eterm binary, ErlNifBinary *result) { if (thing_subtag(*parent_header) == REFC_BINARY_SUBTAG) { ProcBin *pb = (ProcBin*)parent_header; + if (pb->flags & (PB_IS_WRITABLE | PB_ACTIVE_WRITER)) { + erts_emasculate_writable_binary(pb); + } + ASSERT(pb->val != NULL); ASSERT(byte_offset < pb->size); ASSERT(&pb->bytes[byte_offset] >= (byte*)(pb->val)->orig_bytes); -- cgit v1.2.3 From c221ada91c0027bbd74e3e5bff2865df7765a2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 7 Nov 2017 11:30:27 +0100 Subject: Ignore empty binaries in enif_inspect_iovec --- erts/emulator/beam/erl_nif.c | 49 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 8342070521..3ade17b10d 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -3426,36 +3426,38 @@ static int examine_iovec_term(Eterm list, UWord max_length, iovec_slice_t *resul size = binary_size(binary); binary_header = binary_val(binary); - /* If we're a sub-binary we'll need to check our underlying binary to - * determine whether we're on-heap or not. */ - if(thing_subtag(*binary_header) == SUB_BINARY_SUBTAG) { - ErlSubBin *sb = (ErlSubBin*)binary_header; - - /* Reject bitstrings */ - if((sb->bitoffs + sb->bitsize) > 0) { - return 0; + if (size > 0) { + /* If we're a sub-binary we'll need to check our underlying binary + * to determine whether we're on-heap or not. */ + if (thing_subtag(*binary_header) == SUB_BINARY_SUBTAG) { + ErlSubBin *sb = (ErlSubBin*)binary_header; + + /* Reject bitstrings */ + if((sb->bitoffs + sb->bitsize) > 0) { + return 0; + } + + ASSERT(size <= binary_size(sb->orig)); + binary_header = binary_val(sb->orig); } - ASSERT(size <= binary_size(sb->orig)); - binary_header = binary_val(sb->orig); - } - - if(thing_subtag(*binary_header) == HEAP_BINARY_SUBTAG) { - ASSERT(size <= ERL_ONHEAP_BIN_LIMIT); + if (thing_subtag(*binary_header) == HEAP_BINARY_SUBTAG) { + ASSERT(size <= ERL_ONHEAP_BIN_LIMIT); - result->iovec_len += 1; - result->onheap_size += size; - } else { - ASSERT(thing_subtag(*binary_header) == REFC_BINARY_SUBTAG); + result->iovec_len += 1; + result->onheap_size += size; + } else { + ASSERT(thing_subtag(*binary_header) == REFC_BINARY_SUBTAG); - result->iovec_len += 1 + size / MAX_SYSIOVEC_IOVLEN; - result->offheap_size += size; + result->iovec_len += 1 + size / MAX_SYSIOVEC_IOVLEN; + result->offheap_size += size; + } } result->sublist_length += 1; lookahead = CDR(cell); - if(result->sublist_length >= max_length) { + if (result->sublist_length >= max_length) { break; } } @@ -3535,7 +3537,7 @@ static int fill_iovec_with_slice(ErlNifEnv *env, /* If this isn't a refc binary, copy its contents to the onheap buffer * and reference that instead. */ - if (raw_data.ref_bin == NULL) { + if (raw_data.size > 0 && raw_data.ref_bin == NULL) { ASSERT(onheap_offset < onheap_data.size); ASSERT(slice->onheap_size > 0); @@ -3546,12 +3548,11 @@ static int fill_iovec_with_slice(ErlNifEnv *env, raw_data.ref_bin = onheap_data.ref_bin; } - ASSERT(raw_data.ref_bin != NULL); - while (raw_data.size > 0) { UWord chunk_len = MIN(raw_data.size, MAX_SYSIOVEC_IOVLEN); ASSERT(iovec_idx < iovec->iovcnt); + ASSERT(raw_data.ref_bin != NULL); iovec->iov[iovec_idx].iov_base = raw_data.data; iovec->iov[iovec_idx].iov_len = chunk_len; -- cgit v1.2.3 From 8cfe9496873fa36eccda939e56bf7a922e945ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 7 Nov 2017 17:24:55 +0100 Subject: Fix deflateParams on zlib 1.2.11 1.2.11 started bailing when avail_out==0 regardless of whether there's anything to flush or not, and there's no point in adapting the old method since it was vulnerable to bugs in other zlib versions which updated the deflate parameters even on failure. The api_deflateParams test has been expanded accordingly, and two white-box cases in zip_usage has been updated to make fewer assumptions about the output; the validity of the compressed data is what matters, not whether it's exactly the same as the test vector. --- erts/emulator/nifs/common/zlib_nif.c | 25 ++++++++++++++++--- erts/preloaded/ebin/zlib.beam | Bin 19784 -> 19744 bytes erts/preloaded/src/zlib.erl | 13 +++++----- lib/kernel/test/zlib_SUITE.erl | 46 ++++++++++++++++++++++++++++++----- 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c index fa29b4fb71..9565a5a059 100644 --- a/erts/emulator/nifs/common/zlib_nif.c +++ b/erts/emulator/nifs/common/zlib_nif.c @@ -717,7 +717,9 @@ static ERL_NIF_TERM zlib_deflateEnd(ErlNifEnv *env, int argc, const ERL_NIF_TERM static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { zlib_data_t *d; + int res, level, strategy; + Bytef dummy_buffer; if(argc != 3 || !get_zlib_data(env, argv[0], &d) || !enif_get_int(env, argv[1], &level) @@ -729,12 +731,27 @@ static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_T return enif_raise_exception(env, am_not_initialized); } - /* deflateParams will flush everything currently in the stream, corrupting - * the heap unless it's empty. We therefore pretend to have a full output - * buffer, forcing a Z_BUF_ERROR if there's anything left to be flushed. */ - d->s.avail_out = 0; + /* This is a bit of a hack; deflateParams flushes with Z_BLOCK which won't + * stop at a byte boundary, so we can't split this operation up, and we + * can't allocate a buffer large enough to fit it in one go since we have + * to support zlib versions that lack deflatePending. + * + * We therefore flush everything prior to this call to ensure that we are + * stopped on a byte boundary and have no pending data. We then hand it a + * dummy buffer to detect when this assumption doesn't hold (Hopefully + * never), and to smooth over an issue with zlib 1.2.11 which always + * returns Z_BUF_ERROR when d->s.avail_out is 0, regardless of whether + * there's any pending data or not. */ + + d->s.next_out = &dummy_buffer; + d->s.avail_out = 1; + res = deflateParams(&d->s, level, strategy); + if(d->s.avail_out == 0) { + return zlib_return(env, Z_STREAM_ERROR); + } + return zlib_return(env, res); } diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam index f388bc723a..4ad5f37434 100644 Binary files a/erts/preloaded/ebin/zlib.beam and b/erts/preloaded/ebin/zlib.beam differ diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl index 03c9ae38a1..a4ef42204d 100644 --- a/erts/preloaded/src/zlib.erl +++ b/erts/preloaded/src/zlib.erl @@ -188,14 +188,13 @@ deflateReset_nif(_Z) -> deflateParams(Z, Level0, Strategy0) -> Level = arg_level(Level0), Strategy = arg_strategy(Strategy0), + Progress = deflate(Z, <<>>, sync), case deflateParams_nif(Z, Level, Strategy) of - buf_error -> - %% We had data left in the pipe; flush everything and stash it away - %% for the next deflate call before trying again. - Output = deflate(Z, <<>>, full), - save_progress(Z, deflate, Output), - deflateParams_nif(Z, Level, Strategy); - Any -> Any + ok -> + save_progress(Z, deflate, Progress), + ok; + Other -> + Other end. deflateParams_nif(_Z, _Level, _Strategy) -> erlang:nif_error(undef). diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl index 1afcd155b3..6f40c74ee8 100644 --- a/lib/kernel/test/zlib_SUITE.erl +++ b/lib/kernel/test/zlib_SUITE.erl @@ -213,12 +213,46 @@ api_deflateReset(Config) when is_list(Config) -> %% Test deflateParams. api_deflateParams(Config) when is_list(Config) -> + Levels = [none, default, best_speed, best_compression] ++ lists:seq(0, 9), + Strategies = [filtered, huffman_only, rle, default], + Z1 = zlib:open(), ?m(ok, zlib:deflateInit(Z1, default)), - ?m(L when is_list(L), zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, none)), - ?m(ok, zlib:deflateParams(Z1, best_compression, huffman_only)), - ?m(L when is_list(L), zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, sync)), - ?m(ok, zlib:close(Z1)). + + ApiTest = + fun(Level, Strategy) -> + ?m(ok, zlib:deflateParams(Z1, Level, Strategy)), + ?m(ok, zlib:deflateReset(Z1)) + end, + + [ ApiTest(Level, Strategy) || Level <- Levels, Strategy <- Strategies ], + + ?m(ok, zlib:close(Z1)), + + FlushTest = + fun FlushTest(Size, Level, Strategy) -> + Z = zlib:open(), + ok = zlib:deflateInit(Z, default), + Data = gen_determ_rand_bytes(Size), + case zlib:deflate(Z, Data, none) of + [<<120, 156>>] -> + %% All data is present in the internal zlib state, and will + %% be flushed on deflateParams. + + ok = zlib:deflateParams(Z, Level, Strategy), + Compressed = [<<120, 156>>, zlib:deflate(Z, <<>>, finish)], + Data = zlib:uncompress(Compressed), + zlib:close(Z), + + FlushTest(Size + (1 bsl 10), Level, Strategy); + _Other -> + ok + end + end, + + [ FlushTest(1, Level, Strategy) || Level <- Levels, Strategy <- Strategies ], + + ok. %% Test deflate. api_deflate(Config) when is_list(Config) -> @@ -762,13 +796,13 @@ zip_usage({run,ZIP,ORIG}) -> ?m(ok, zlib:deflateInit(Z, default, deflated, -15, 8, default)), C2 = zlib:deflate(Z, ORIG, finish), - ?m(true, C1 == list_to_binary(C2)), + ?m(ORIG, zlib:unzip(C2)), ?m(ok, zlib:deflateEnd(Z)), ?m(ok, zlib:deflateInit(Z, none, deflated, -15, 8, filtered)), ?m(ok, zlib:deflateParams(Z, default, default)), C3 = zlib:deflate(Z, ORIG, finish), - ?m(true, C1 == list_to_binary(C3)), + ?m(ORIG, zlib:unzip(C3)), ?m(ok, zlib:deflateEnd(Z)), ok = zlib:close(Z), -- cgit v1.2.3 From e96969083dbfebfaaa600d2ba6c2cf6d5a690cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 7 Nov 2017 17:31:18 +0100 Subject: Avoid WindowBits=8 as per the manual The docs for zlib:deflateInit/6 explicitly mention that 8 is broken and should not be used unless we know for certain that our zlib version supports it. --- lib/kernel/test/zlib_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl index 6f40c74ee8..6d4e21b8cf 100644 --- a/lib/kernel/test/zlib_SUITE.erl +++ b/lib/kernel/test/zlib_SUITE.erl @@ -166,7 +166,7 @@ api_deflateInit(Config) when is_list(Config) -> ?m(ok, zlib:deflateInit(Z12,default,deflated,-Wbits,8,default)), ?m(ok,zlib:close(Z11)), ?m(ok,zlib:close(Z12)) - end, lists:seq(8, 15)), + end, lists:seq(9, 15)), lists:foreach(fun(MemLevel) -> Z = zlib:open(), -- cgit v1.2.3 From 4dcabdcc5ab7f41189ec3937e84b323d80d6df57 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Tue, 7 Nov 2017 10:25:16 +0100 Subject: inets: Add missing guard Add test in the correct place which was the reason the guard became missing without being noticed. --- lib/inets/src/http_server/httpd_esi.erl | 2 +- lib/inets/src/http_server/httpd_example.erl | 2 +- lib/inets/test/http_format_SUITE.erl | 5 ++++- lib/inets/test/httpd_SUITE.erl | 7 +++++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/inets/src/http_server/httpd_esi.erl b/lib/inets/src/http_server/httpd_esi.erl index fd50934d00..f5493f6fad 100644 --- a/lib/inets/src/http_server/httpd_esi.erl +++ b/lib/inets/src/http_server/httpd_esi.erl @@ -86,7 +86,7 @@ handle_headers([], NewHeaders, StatusCode, _) -> handle_headers([Header | Headers], NewHeaders, StatusCode, NoESIStatus) -> {FieldName, FieldValue} = httpd_response:split_header(Header, []), case FieldName of - "location" -> + "location" when NoESIStatus == true -> handle_headers(Headers, [{FieldName, FieldValue} | NewHeaders], 302, NoESIStatus); diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl index adbbf64685..47a8c48d01 100644 --- a/lib/inets/src/http_server/httpd_example.erl +++ b/lib/inets/src/http_server/httpd_example.erl @@ -91,7 +91,7 @@ yahoo(_Env,_Input) -> "Location: http://www.yahoo.com\r\n\r\n". new_status_and_location(_Env,_Input) -> - "status:201\r\n Location: http://www.yahoo.com\r\n\r\n". + "status:201 Created\r\n Location: http://www.yahoo.com\r\n\r\n". default(Env,Input) -> [header(), diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl index 9a13ed3d17..647eff4f7c 100644 --- a/lib/inets/test/http_format_SUITE.erl +++ b/lib/inets/test/http_format_SUITE.erl @@ -536,7 +536,10 @@ esi_parse_headers(Config) when is_list(Config) -> httpd_esi:handle_headers(Headers2), {ok,[{"location","/foo/bar.html"}], 302} = - httpd_esi:handle_headers("location:/foo/bar.html\r\n"). + httpd_esi:handle_headers("location:/foo/bar.html\r\n"), + + {ok,[{"location","http://foo/bar.html"}],201} = + httpd_esi:handle_headers("status:201 Created\r\nlocation:http://foo/bar.html\r\n"). %%-------------------------------------------------------------------- cgi_parse_headers() -> diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl index 0c649d9abf..9a85c51d24 100644 --- a/lib/inets/test/httpd_SUITE.erl +++ b/lib/inets/test/httpd_SUITE.erl @@ -923,8 +923,11 @@ esi(Config) when is_list(Config) -> {no_header, "cache-control"}]), ok = http_status("GET /cgi-bin/erl/httpd_example:peer ", Config, [{statuscode, 200}, - {header, "peer-cert-exist", peer(Config)}]). - + {header, "peer-cert-exist", peer(Config)}]), + ok = http_status("GET /cgi-bin/erl/httpd_example:new_status_and_location ", + Config, [{statuscode, 201}, + {header, "location"}]). + %%------------------------------------------------------------------------- esi_put() -> [{doc, "Test mod_esi PUT"}]. -- cgit v1.2.3 From 07bfe477c0a06fbd7df5e216a7c072594fd17e4d Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 9 Nov 2017 11:23:49 +0100 Subject: inets: Prepare for release --- lib/inets/src/inets_app/inets.appup.src | 4 ++++ lib/inets/vsn.mk | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index a86413147c..fdf4cc6e07 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,10 +18,14 @@ %% %CopyrightEnd% {"%VSN%", [ + {<<"6.4.3">>, [{load_module, httpd_esi, + soft_purge, soft_purge, []}]}, {<<"6\\..*">>,[{restart_application, inets}]}, {<<"5\\..*">>,[{restart_application, inets}]} ], [ + {<<"6.4.3">>, [{load_module, httpd_esi, + soft_purge, soft_purge, []}]}, {<<"6\\..*">>,[{restart_application, inets}]}, {<<"5\\..*">>,[{restart_application, inets}]} ] diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 108d259823..560d524bac 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 6.4.3 +INETS_VSN = 6.4.4 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" -- cgit v1.2.3 From de930e60f1a6352491ac543b5d50d13122c10745 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 9 Nov 2017 16:15:43 +0100 Subject: Update version numbers --- erts/vsn.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erts/vsn.mk b/erts/vsn.mk index a788b2e491..220c3b5f6c 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 9.1.3 +VSN = 9.1.4 # Port number 4365 in 4.2 # Port number 4366 in 4.3 -- cgit v1.2.3 From 2ad665902380f1d18d6ad0b175b00b9e66dec77c Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 9 Nov 2017 16:15:57 +0100 Subject: Update release notes --- erts/doc/src/notes.xml | 43 +++++++++++++++++++++++++++++++++++++++++++ lib/inets/doc/src/notes.xml | 21 ++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 2507451533..1d309f8f86 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,49 @@

This document describes the changes made to the ERTS application.

+
Erts 9.1.4 + +
Fixed Bugs and Malfunctions + + +

Microstate accounting sometimes produced incorrect + results for dirty schedulers.

+

+ Own Id: OTP-14707

+
+ +

Fixed a regression in zlib:gunzip/1 that + prevented it from working when the decompressed size was + a perfect multiple of 16384. This regression was + introduced in 20.1.1

+

+ Own Id: OTP-14730 Aux Id: ERL-507

+
+ +

Fixed a memory corruption bug in + enif_inspect_iovec; writable binaries stayed + writable after entering the iovec.

+

+ Own Id: OTP-14745

+
+ +

Fixed a crash in enif_inspect_iovec on + encountering empty binaries.

+

+ Own Id: OTP-14750

+
+ +

zlib:deflateParams/3 will no longer return + buf_error when called after zlib:deflate/2 + with zlib 1.2.11.

+

+ Own Id: OTP-14751

+
+
+
+ +
+
Erts 9.1.3
Fixed Bugs and Malfunctions diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 1ff6aefaa7..07e29b5542 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,26 @@ notes.xml -
Inets 6.4.3 +
Inets 6.4.4 + +
Fixed Bugs and Malfunctions + + +

+ Correct the handling of location headers so that the + status code is not hard coded. This should have been + fixed by commit 2cc5ba70cbbc6b3ace81a2a0324417c3b65265bb + but unfortunately was broken during a code refactoring + and unnoticed due to a faulty placed test case.

+

+ Own Id: OTP-14761

+
+
+
+ +
+ +
Inets 6.4.3
Improvements and New Features -- cgit v1.2.3 From 84f29ab803e8f36ef058a47f4c2b224f4dd58220 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 9 Nov 2017 16:15:59 +0100 Subject: Updated OTP version --- OTP_VERSION | 2 +- otp_versions.table | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OTP_VERSION b/OTP_VERSION index 286ad61f58..0d9f38d420 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -20.1.4 +20.1.5 diff --git a/otp_versions.table b/otp_versions.table index 509912eab2..15ffbd5ed6 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-20.1.5 : erts-9.1.4 inets-6.4.4 # asn1-5.0.3 common_test-1.15.2 compiler-7.1.3 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.1 debugger-4.2.3 dialyzer-3.2.2 diameter-2.1.2 edoc-0.9.1 eldap-1.2.2 erl_docgen-0.7.1 erl_interface-3.10 et-1.6.1 eunit-2.3.4 hipe-3.16.1 ic-4.4.2 jinterface-1.8 kernel-5.4 megaco-3.18.2 mnesia-4.15.1 observer-2.5 odbc-2.12 orber-3.8.3 os_mon-2.4.3 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.5 reltool-0.7.5 runtime_tools-1.12.2 sasl-3.1 snmp-5.2.8 ssh-4.6.1 ssl-8.2.1 stdlib-3.4.2 syntax_tools-2.1.3 tools-2.11 wx-1.8.2 xmerl-1.3.15 : OTP-20.1.4 : inets-6.4.3 # asn1-5.0.3 common_test-1.15.2 compiler-7.1.3 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.1 debugger-4.2.3 dialyzer-3.2.2 diameter-2.1.2 edoc-0.9.1 eldap-1.2.2 erl_docgen-0.7.1 erl_interface-3.10 erts-9.1.3 et-1.6.1 eunit-2.3.4 hipe-3.16.1 ic-4.4.2 jinterface-1.8 kernel-5.4 megaco-3.18.2 mnesia-4.15.1 observer-2.5 odbc-2.12 orber-3.8.3 os_mon-2.4.3 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.5 reltool-0.7.5 runtime_tools-1.12.2 sasl-3.1 snmp-5.2.8 ssh-4.6.1 ssl-8.2.1 stdlib-3.4.2 syntax_tools-2.1.3 tools-2.11 wx-1.8.2 xmerl-1.3.15 : OTP-20.1.3 : diameter-2.1.2 erts-9.1.3 snmp-5.2.8 # asn1-5.0.3 common_test-1.15.2 compiler-7.1.3 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.1 debugger-4.2.3 dialyzer-3.2.2 edoc-0.9.1 eldap-1.2.2 erl_docgen-0.7.1 erl_interface-3.10 et-1.6.1 eunit-2.3.4 hipe-3.16.1 ic-4.4.2 inets-6.4.2 jinterface-1.8 kernel-5.4 megaco-3.18.2 mnesia-4.15.1 observer-2.5 odbc-2.12 orber-3.8.3 os_mon-2.4.3 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.5 reltool-0.7.5 runtime_tools-1.12.2 sasl-3.1 ssh-4.6.1 ssl-8.2.1 stdlib-3.4.2 syntax_tools-2.1.3 tools-2.11 wx-1.8.2 xmerl-1.3.15 : OTP-20.1.2 : diameter-2.1.1 erts-9.1.2 # asn1-5.0.3 common_test-1.15.2 compiler-7.1.3 cosEvent-2.2.1 cosEventDomain-1.2.1 cosFileTransfer-1.2.1 cosNotification-1.2.2 cosProperty-1.2.2 cosTime-1.2.2 cosTransactions-1.3.2 crypto-4.1 debugger-4.2.3 dialyzer-3.2.2 edoc-0.9.1 eldap-1.2.2 erl_docgen-0.7.1 erl_interface-3.10 et-1.6.1 eunit-2.3.4 hipe-3.16.1 ic-4.4.2 inets-6.4.2 jinterface-1.8 kernel-5.4 megaco-3.18.2 mnesia-4.15.1 observer-2.5 odbc-2.12 orber-3.8.3 os_mon-2.4.3 otp_mibs-1.1.1 parsetools-2.1.5 public_key-1.5 reltool-0.7.5 runtime_tools-1.12.2 sasl-3.1 snmp-5.2.7 ssh-4.6.1 ssl-8.2.1 stdlib-3.4.2 syntax_tools-2.1.3 tools-2.11 wx-1.8.2 xmerl-1.3.15 : -- cgit v1.2.3