Repository: tikv/tikv
File: components/resolved_ts/src/endpoint.rs (Rust)

Code before:
    }
}

impl fmt::Display for Task {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl<T, E, S> Runnable for Endpoint<T, E, S>
where
    T: 'static + CdcHandle<E>,
    E: KvEngine,
    S: StoreRegionMeta,
{
    type Task = Task;

    fn run(&mut self, task: Task) {
        debug!("run resolved-ts task"; "task" => ?task);
        if self.last_active_memory_quota_check.elapsed()
            >= self.cfg.memory_quota_active_check_interval.0
        {
            self.last_active_memory_quota_check = std::time::Instant::now();
            // Check whether memory quota is exceeded actively.
            if let Err(e) = self.memory_quota.alloc(0) {
                self.re_register_all_regions(Some(e.to_string().as_str()));
            }
        }

        match task {
            Task::RegionDestroyed(region) => self.region_destroyed(region),
            Task::RegionUpdated(region) => self.region_updated(region),
            Task::RegisterRegion { region } => self.register_region(region, None),
            Task::DeRegisterRegion { region_id } => self.deregister_region(region_id),
            Task::ReRegisterRegion {
                region_id,
                observe_id,
                cause,
            } => self.re_register_region(
                region_id,
                observe_id,
                Some(cause.to_string().as_str()),
                None,
            ),
            Task::AdvanceResolvedTs { leader_resolver } => {
                self.handle_advance_resolved_ts(leader_resolver)
            }
            Task::ResolvedTsAdvanced {
                regions,
                ts,
                ts_source,

Review comment (bug):
Converting `e.to_string().as_str()` creates a temporary String that is immediately converted to a string slice. The temporary String is dropped at the end of the statement, making the string slice invalid. This is a use-after-free bug. Instead, pass `&e.to_string()` or use a temporary variable to store the String.

Code after:
    }
}

impl fmt::Display for Task {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl<T, E, S> Runnable for Endpoint<T, E, S>
where
    T: 'static + CdcHandle<E>,
    E: KvEngine,
    S: StoreRegionMeta,
{
    type Task = Task;

    fn run(&mut self, task: Task) {
        debug!("run resolved-ts task"; "task" => ?task);
        if self.last_active_memory_quota_check.elapsed()
            >= self.cfg.memory_quota_active_check_interval.0
        {
            self.last_active_memory_quota_check = std::time::Instant::now();
            // Check whether memory quota is exceeded actively.
            if let Err(e) = self.memory_quota.alloc(0) {
                self.re_register_all_regions(Some(&e.to_string()));
            }
        }

        match task {
            Task::RegionDestroyed(region) => self.region_destroyed(region),
            Task::RegionUpdated(region) => self.region_updated(region),
            Task::RegisterRegion { region } => self.register_region(region, None),
            Task::DeRegisterRegion { region_id } => self.deregister_region(region_id),
            Task::ReRegisterRegion {
                region_id,
                observe_id,
                cause,
            } => self.re_register_region(region_id, observe_id, Some(&cause.to_string()), None),
            Task::AdvanceResolvedTs { leader_resolver } => {
                self.handle_advance_resolved_ts(leader_resolver)
            }
            Task::ResolvedTsAdvanced {
                regions,
                ts,
                ts_source,
            } => self.handle_resolved_ts_advanced(regions, ts, ts_source),
            Task::ChangeLog { cmd_batch } => {
                self.handle_change_log(cmd_batch);
            }
            Task::ScanLocks {