加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

我为 Windows 10 修复了一个 bug

发布时间:2019-06-27 21:20:22 所属栏目:Windows 来源:局长
导读:副标题#e# 本文讲述了一名开发者为 Windows 计算器应用修复bug 的经历。 据这名开发者(下用 Peter 代称)介绍,他某日在 Reddit 闲逛时,一个位于 Windows 10 子版块下的帖子引起了他的注意。帖子内容如下: 和大家一样,在计算两个日期之间的相隔天数时,
副标题[/!--empirenews.page--]

本文讲述了一名开发者为 Windows 计算器应用修复 bug 的经历。

据这名开发者(下用 Peter 代称)介绍,他某日在 Reddit 闲逛时,一个位于 Windows 10 子版块下的帖子引起了他的注意。帖子内容如下:

我为 Windows 10 修复了一个 bug

和大家一样,在计算两个日期之间的相隔天数时,Peter 也发现了关于周数的描述明显是错误的,如此大的数值看起来应该是上溢或者下溢之类的问题,要不就是差一错误(off-by-one)等常见的逻辑错误。

本着对这个 bug 的好奇心,再加上 Windows 10 计算器是开源项目,Peter 认为解决这个问题应该不会太复杂,所以他希望亲自找到 bug 并进行修复。

他先在自己的电脑上测试看是否能复现,按照帖子的示例,在测试 7.31-12.31 的间隔天数时,计算器返回的结果是正确的 —— “5个月”。接着 Peter 稍微改了一下日期,改成 7.31-12.30 时,bug 复现了,计算器显示的值为:“5 months, 613566756 weeks, 3 days”,这明显是错误的。

我为 Windows 10 修复了一个 bug

确定了 bug 的存在,Peter 决定从 Windows 计算器的 GitHub 仓库下载源码来研究一番。从 repo 把源码下载到本地后,由于在 IDE 运行 Windows 计算器项目需要 UWP workload,所以 Peter 还为 Visual Studio 添加了 UWP workload。不过 Peter 表示搭建开发环境也十分顺利,修 bug 第一步至此完成。

接着 Peter 打开了解决方案文件(solution file),查看 “Calculator” 项目,并搜索看似相关的任何文件。他找到了界面文件DateCalculator.xaml,接着从相关的文件DateDiff_FromDate追踪到了DateCalculatorViewModel.cpp,最后找到DateCalculator.cpp

然后 Peter 开始设置断点并观察相关变量的变化,他发现 final 变量DateDifference 的值有误。因此他判断这个 bug 不是由转换为字符串存在错误而导致的,而是实实在在的计算错误。

既然计算存在问题,那就看看它的计算逻辑是如何实现的。

Windows 计算器对间隔日期的计算逻辑用伪代码表示如下:

  1. DateDifference calculate_difference(start_date, end_date) { 
  2.     uint[] diff_types = [year, month, week, day] 
  3.     uint[] typical_days_in_type = [365, 31, 7, 1] 
  4.     uint[] calculated_difference = [0, 0, 0, 0] 
  5.     date temp_pivot_date 
  6.     date pivot_date = start_date 
  7.     uint days_diff = calculate_days_difference(start_date, end_date) 
  8.  
  9.     for(type in differenceTypes) { 
  10.         temp_pivot_date = pivot_date 
  11.         uint current_guess = days_diff /typicalDaysInType[type]  
  12.         if(current_guess !=0) 
  13.             pivot_date = advance_date_by(pivot_date, type, current_guess) 
  14.          
  15.         int diff_remaining 
  16.         bool best_guess_hit = false 
  17.         do{ 
  18.             diff_remaining = calculate_days_difference(pivot_date, end_date) 
  19.             if(diff_remaining < 0) { 
  20.                 // pivotDate has gone over the end date; start from the beginning of this unit 
  21.                 current_guess = current_guess - 1 
  22.                 pivot_date = temp_pivot_date 
  23.                 pivot_date = advance_date_by(pivot_date, type, current_guess) 
  24.                 best_guess_hit = true 
  25.             } else if(diff_remaining > 0) { 
  26.                 // pivot_date is still below the end date 
  27.                 if(best_guess_hit) 
  28.                     break; 
  29.                 current_guess = current_guess + 1 
  30.                 pivot_date = advance_date_by(pivot_date, type, 1) 
  31.             } 
  32.         } while(diff_remaining!=0) 
  33.  
  34.         temp_pivot_date = advance_date_by(temp_pivot_date, type, current_guess) 
  35.         pivot_date = temp_pivot_date  
  36.         calculated_difference[type] = current_guess 
  37.         days_diff = calculate_days_difference(pivot_date, end_date) 
  38.     } 
  39.     calculcated_difference[day] = days_diff 
  40.     return calculcated_difference 

上面的代码主要做了这些事:先算出相差的年数、然后计算相差的月数、接着计算相差的周数、最后计算相差的天数。

Peter 表示这看起来很正常,他没发现其中的逻辑存在错误。

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读