{"task":"Review these selected C source excerpts from PHP 8.2.34. Identify a concrete defect supported by the code, cite the original file and line numbers, and trace the operations that cause it. Propose a minimal unified diff against this version that addresses the defect while preserving upload progress. Suggest a benign regression test with an explicit before/after result. Separate facts established by the excerpts from hypotheses requiring omitted code or runtime evidence. Keep the answer concise enough to include the diagnosis, patch and test within the output limit.","answer_language":"Spanish","file":"php82_session_excerpt.c.txt","lines":[{"line":1,"text":"/* Selected, non-contiguous excerpts from PHP 8.2.34. Not a standalone C file. */"},{"line":2,"text":""},{"line":3,"text":"/*"},{"line":4,"text":"   +----------------------------------------------------------------------+"},{"line":5,"text":"   | Copyright (c) The PHP Group                                          |"},{"line":6,"text":"   +----------------------------------------------------------------------+"},{"line":7,"text":"   | This source file is subject to version 3.01 of the PHP license,      |"},{"line":8,"text":"   | that is bundled with this package in the file LICENSE, and is        |"},{"line":9,"text":"   | available through the world-wide-web at the following url:           |"},{"line":10,"text":"   | https://www.php.net/license/3_01.txt                                 |"},{"line":11,"text":"   | If you did not receive a copy of the PHP license and are unable to   |"},{"line":12,"text":"   | obtain it through the world-wide-web, please send a note to          |"},{"line":13,"text":"   | license@php.net so we can mail you a copy immediately.               |"},{"line":14,"text":"   +----------------------------------------------------------------------+"},{"line":15,"text":"   | Authors: Sascha Schumann <sascha@schumann.cx>                        |"},{"line":16,"text":"   |          Andrei Zmievski <andrei@php.net>                            |"},{"line":17,"text":"   +----------------------------------------------------------------------+"},{"line":18,"text":" */"},{"line":19,"text":""},{"line":20,"text":"#line 123 \"ext/session/php_session.h\""},{"line":21,"text":"typedef struct _php_session_rfc1867_progress {"},{"line":22,"text":"\tsize_t    sname_len;"},{"line":23,"text":"\tzval      sid;"},{"line":24,"text":"\tsmart_str key;"},{"line":25,"text":""},{"line":26,"text":"\tzend_long      update_step;"},{"line":27,"text":"\tzend_long      next_update;"},{"line":28,"text":"\tdouble    next_update_time;"},{"line":29,"text":"\tbool cancel_upload;"},{"line":30,"text":"\tbool apply_trans_sid;"},{"line":31,"text":"\tsize_t    content_length;"},{"line":32,"text":""},{"line":33,"text":"\tzval      data;                 /* the array exported to session data */"},{"line":34,"text":"\tzval\t *post_bytes_processed; /* data[\"bytes_processed\"] */"},{"line":35,"text":"\tzval      files;                /* data[\"files\"] array */"},{"line":36,"text":"\tzval      current_file;         /* array of currently uploading file */"},{"line":37,"text":"\tzval\t *current_file_bytes_processed;"},{"line":38,"text":"} php_session_rfc1867_progress;"},{"line":39,"text":""},{"line":40,"text":"#line 2960 \"ext/session/session.c\""},{"line":41,"text":"static void php_session_rfc1867_update(php_session_rfc1867_progress *progress, int force_update) /* {{{ */"},{"line":42,"text":"{"},{"line":43,"text":"\tif (!force_update) {"},{"line":44,"text":"\t\tif (Z_LVAL_P(progress->post_bytes_processed) < progress->next_update) {"},{"line":45,"text":"\t\t\treturn;"},{"line":46,"text":"\t\t}"},{"line":47,"text":"#ifdef HAVE_GETTIMEOFDAY"},{"line":48,"text":"\t\tif (PS(rfc1867_min_freq) > 0.0) {"},{"line":49,"text":"\t\t\tstruct timeval tv = {0};"},{"line":50,"text":"\t\t\tdouble dtv;"},{"line":51,"text":"\t\t\tgettimeofday(&tv, NULL);"},{"line":52,"text":"\t\t\tdtv = (double) tv.tv_sec + tv.tv_usec / 1000000.0;"},{"line":53,"text":"\t\t\tif (dtv < progress->next_update_time) {"},{"line":54,"text":"\t\t\t\treturn;"},{"line":55,"text":"\t\t\t}"},{"line":56,"text":"\t\t\tprogress->next_update_time = dtv + PS(rfc1867_min_freq);"},{"line":57,"text":"\t\t}"},{"line":58,"text":"#endif"},{"line":59,"text":"\t\tprogress->next_update = Z_LVAL_P(progress->post_bytes_processed) + progress->update_step;"},{"line":60,"text":"\t}"},{"line":61,"text":""},{"line":62,"text":"\tphp_session_initialize();"},{"line":63,"text":"\tPS(session_status) = php_session_active;"},{"line":64,"text":"\tIF_SESSION_VARS() {"},{"line":65,"text":"\t\tzval *sess_var = Z_REFVAL(PS(http_session_vars));"},{"line":66,"text":"\t\tSEPARATE_ARRAY(sess_var);"},{"line":67,"text":""},{"line":68,"text":"\t\tprogress->cancel_upload |= php_check_cancel_upload(progress);"},{"line":69,"text":"\t\tZ_TRY_ADDREF(progress->data);"},{"line":70,"text":"\t\tzend_hash_update(Z_ARRVAL_P(sess_var), progress->key.s, &progress->data);"},{"line":71,"text":"\t}"},{"line":72,"text":"\tphp_session_flush(1);"},{"line":73,"text":"} /* }}} */"},{"line":74,"text":""},{"line":75,"text":"#line 3083 \"ext/session/session.c\""},{"line":76,"text":"\t\t\t\tarray_init(&progress->files);"},{"line":77,"text":""},{"line":78,"text":"\t\t\t\tadd_assoc_long_ex(&progress->data, \"start_time\", sizeof(\"start_time\") - 1, (zend_long)sapi_get_request_time());"},{"line":79,"text":"\t\t\t\tadd_assoc_long_ex(&progress->data, \"content_length\",  sizeof(\"content_length\") - 1, progress->content_length);"},{"line":80,"text":"\t\t\t\tadd_assoc_long_ex(&progress->data, \"bytes_processed\", sizeof(\"bytes_processed\") - 1, data->post_bytes_processed);"},{"line":81,"text":"\t\t\t\tadd_assoc_bool_ex(&progress->data, \"done\", sizeof(\"done\") - 1, 0);"},{"line":82,"text":"\t\t\t\tadd_assoc_zval_ex(&progress->data, \"files\", sizeof(\"files\") - 1, &progress->files);"},{"line":83,"text":""},{"line":84,"text":"\t\t\t\tprogress->post_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->data), \"bytes_processed\", sizeof(\"bytes_processed\") - 1);"},{"line":85,"text":""},{"line":86,"text":""},{"line":87,"text":"#line 3103 \"ext/session/session.c\""},{"line":88,"text":"\t\t\tarray_init(&progress->current_file);"},{"line":89,"text":""},{"line":90,"text":"\t\t\t/* Each uploaded file has its own array. Trying to make it close to $_FILES entries. */"},{"line":91,"text":"\t\t\tadd_assoc_string_ex(&progress->current_file, \"field_name\", sizeof(\"field_name\") - 1, data->name);"},{"line":92,"text":"\t\t\tadd_assoc_string_ex(&progress->current_file, \"name\", sizeof(\"name\") - 1, *data->filename);"},{"line":93,"text":"\t\t\tadd_assoc_null_ex(&progress->current_file, \"tmp_name\", sizeof(\"tmp_name\") - 1);"},{"line":94,"text":"\t\t\tadd_assoc_long_ex(&progress->current_file, \"error\", sizeof(\"error\") - 1, 0);"},{"line":95,"text":""},{"line":96,"text":"\t\t\tadd_assoc_bool_ex(&progress->current_file, \"done\", sizeof(\"done\") - 1, 0);"},{"line":97,"text":"\t\t\tadd_assoc_long_ex(&progress->current_file, \"start_time\", sizeof(\"start_time\") - 1, (zend_long)time(NULL));"},{"line":98,"text":"\t\t\tadd_assoc_long_ex(&progress->current_file, \"bytes_processed\", sizeof(\"bytes_processed\") - 1, 0);"},{"line":99,"text":""},{"line":100,"text":"\t\t\tadd_next_index_zval(&progress->files, &progress->current_file);"},{"line":101,"text":""},{"line":102,"text":"\t\t\tprogress->current_file_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->current_file), \"bytes_processed\", sizeof(\"bytes_processed\") - 1);"},{"line":103,"text":""},{"line":104,"text":"\t\t\tZ_LVAL_P(progress->current_file_bytes_processed) =  data->post_bytes_processed;"},{"line":105,"text":"\t\t\tphp_session_rfc1867_update(progress, 0);"},{"line":106,"text":"\t\t}"},{"line":107,"text":"\t\tbreak;"},{"line":108,"text":"\t\tcase MULTIPART_EVENT_FILE_DATA: {"},{"line":109,"text":"\t\t\tmultipart_event_file_data *data = (multipart_event_file_data *) event_data;"},{"line":110,"text":""},{"line":111,"text":"\t\t\tif (!Z_TYPE(progress->sid) || !progress->key.s) {"},{"line":112,"text":"\t\t\t\tbreak;"},{"line":113,"text":"\t\t\t}"},{"line":114,"text":""},{"line":115,"text":"\t\t\tZ_LVAL_P(progress->current_file_bytes_processed) = data->offset + data->length;"},{"line":116,"text":"\t\t\tZ_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed;"},{"line":117,"text":""},{"line":118,"text":"\t\t\tphp_session_rfc1867_update(progress, 0);"},{"line":119,"text":"\t\t}"},{"line":120,"text":""},{"line":121,"text":"#line 3147 \"ext/session/session.c\""},{"line":122,"text":"\t\t\tadd_assoc_long_ex(&progress->current_file, \"error\", sizeof(\"error\") - 1, data->cancel_upload);"},{"line":123,"text":"\t\t\tadd_assoc_bool_ex(&progress->current_file, \"done\", sizeof(\"done\") - 1,  1);"},{"line":124,"text":""},{"line":125,"text":"\t\t\tZ_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed;"},{"line":126,"text":""},{"line":127,"text":"\t\t\tphp_session_rfc1867_update(progress, 0);"},{"line":128,"text":"\t\t}"},{"line":129,"text":"\t\tbreak;"},{"line":130,"text":"\t\tcase MULTIPART_EVENT_END: {"},{"line":131,"text":"\t\t\tmultipart_event_end *data = (multipart_event_end *) event_data;"},{"line":132,"text":""},{"line":133,"text":"\t\t\tif (Z_TYPE(progress->sid) && progress->key.s) {"},{"line":134,"text":"\t\t\t\tif (PS(rfc1867_cleanup)) {"},{"line":135,"text":"\t\t\t\t\tphp_session_rfc1867_cleanup(progress);"},{"line":136,"text":"\t\t\t\t} else {"},{"line":137,"text":"\t\t\t\t\tif (!Z_ISUNDEF(progress->data)) {"},{"line":138,"text":"\t\t\t\t\t\tSEPARATE_ARRAY(&progress->data);"},{"line":139,"text":"\t\t\t\t\t\tadd_assoc_bool_ex(&progress->data, \"done\", sizeof(\"done\") - 1, 1);"},{"line":140,"text":"\t\t\t\t\t\tZ_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed;"},{"line":141,"text":"\t\t\t\t\t\tphp_session_rfc1867_update(progress, 1);"},{"line":142,"text":"\t\t\t\t\t}"},{"line":143,"text":"\t\t\t\t}"},{"line":144,"text":"\t\t\t\tphp_rshutdown_session_globals();"},{"line":145,"text":"\t\t\t}"},{"line":146,"text":""},{"line":147,"text":"\t\t\tif (!Z_ISUNDEF(progress->data)) {"},{"line":148,"text":"\t\t\t\tzval_ptr_dtor(&progress->data);"},{"line":149,"text":"\t\t\t}"},{"line":150,"text":"\t\t\tzval_ptr_dtor(&progress->sid);"},{"line":151,"text":"\t\t\tsmart_str_free(&progress->key);"},{"line":152,"text":"\t\t\tefree(progress);"},{"line":153,"text":"\t\t\tprogress = NULL;"},{"line":154,"text":"\t\t\tPS(rfc1867_progress) = NULL;"},{"line":155,"text":"\t\t}"}]}
