微信支付.NET SDK 中的BUG(存疑)

BUG出现在类文件WxPayData.cs中的FromXml(string xml)方法

 1  /**
 2         * @将xml转为WxPayData对象并返回对象内部的数据
 3         * @param string 待转换的xml串
 4         * @return 经转换得到的Dictionary
 5         * @throws WxPayException
 6         */
 7         public SortedDictionary<string, object> FromXml(string xml)
 8         {
 9             if (string.IsNullOrEmpty(xml))
10             {
11                 Log.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!");
12                 throw new WxPayException("将空的xml串转换为WxPayData不合法!");
13             }
14 
15             
16             SafeXmlDocument xmlDoc = new SafeXmlDocument();
17             xmlDoc.LoadXml(xml);
18             XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
19             XmlNodeList nodes = xmlNode.ChildNodes;
20             foreach (XmlNode xn in nodes)
21             {
22                 XmlElement xe = (XmlElement)xn;
23                 m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
24             }
25             
26             try
27             {
28                 //2015-06-29 错误是没有签名
29                 if(m_values["return_code"] != "SUCCESS")
30                 {
31                     return m_values;
32                 }
33                 CheckSign();//验证签名,不通过会抛异常
34             }
35             catch(WxPayException ex)
36             {
37                 throw new WxPayException(ex.Message);
38             }
39 
40             return m_values;
41         }

根据VS代码提示 ,可能非有意的引用比较;左侧需要强制转换。

经调试监听,即使m_values["return_code"]返回值为SUCCESS,此处判断也是true。这样就绕过了CheckSign()验证签名的方法。

如果按照VS代码提示进行修改:

    //2015-06-29 错误是没有签名
                if(m_values["return_code"].ToString() != "SUCCESS")
                {
                    return m_values;
                }
                CheckSign();//验证签名,不通过会抛异常

经调试,m_values["return_code"]返回值为SUCCESS,下一步走CheckSign()验证签名的方法,然后报“WxPayData字段数据类型错误!”

然后下载Java SDK进行代码对比,发现只要m_values["return_code"]返回值为SUCCESS,就要进行签名验证,Java代码如下

/**
     * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。
     * @param xmlStr API返回的XML格式数据
     * @return Map类型数据
     * @throws Exception
     */
    public Map<String, String> processResponseXml(String xmlStr) throws Exception {
        String RETURN_CODE = "return_code";
        String return_code;
        Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);
        if (respData.containsKey(RETURN_CODE)) {
            return_code = respData.get(RETURN_CODE);
        }
        else {
            throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
        }

        if (return_code.equals(WXPayConstants.FAIL)) {
            return respData;
        }
        else if (return_code.equals(WXPayConstants.SUCCESS)) {
           if (this.isResponseSignatureValid(respData)) {
               return respData;
           }
           else {
               throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
           }
        }
        else {
            throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
        }
    }

对于.NET SDK 中这个处理,不太明白。还请大神指点迷津!

posted on 2020-08-13 14:12  沐小淘  阅读(312)  评论(0编辑  收藏  举报

导航