Преглед изворни кода

chore(*) fix sue of isNaN

- It can throw exceptions
- It doesn't return false on things which are not Number, just on things
  that are not NaN

Fixes: https://github.com/jitsi/lib-jitsi-meet/issues/2743
dev0
Saúl Ibarra Corretgé пре 6 месеци
родитељ
комит
154817b640

+ 11
- 10
JitsiConference.js Прегледај датотеку

35
 import SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';
35
 import SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';
36
 import Statistics from './modules/statistics/statistics';
36
 import Statistics from './modules/statistics/statistics';
37
 import EventEmitter from './modules/util/EventEmitter';
37
 import EventEmitter from './modules/util/EventEmitter';
38
-import { safeSubtract } from './modules/util/MathUtil';
38
+import { isValidNumber, safeSubtract } from './modules/util/MathUtil';
39
 import RandomUtil from './modules/util/RandomUtil';
39
 import RandomUtil from './modules/util/RandomUtil';
40
 import { getJitterDelay } from './modules/util/Retry';
40
 import { getJitterDelay } from './modules/util/Retry';
41
 import ComponentsVersions from './modules/version/ComponentsVersions';
41
 import ComponentsVersions from './modules/version/ComponentsVersions';
247
      */
247
      */
248
     this.deferredStartP2PTask = null;
248
     this.deferredStartP2PTask = null;
249
 
249
 
250
-    const delay
251
-        = parseInt(options.config.p2p && options.config.p2p.backToP2PDelay, 10);
250
+    const delay = Number.parseInt(options.config.p2p?.backToP2PDelay, 10);
252
 
251
 
253
     /**
252
     /**
254
      * A delay given in seconds, before the conference switches back to P2P
253
      * A delay given in seconds, before the conference switches back to P2P
255
      * after the 3rd participant has left.
254
      * after the 3rd participant has left.
256
      * @type {number}
255
      * @type {number}
257
      */
256
      */
258
-    this.backToP2PDelay = isNaN(delay) ? 5 : delay;
257
+    this.backToP2PDelay = isValidNumber(delay) ? delay : 5;
259
     logger.info(`backToP2PDelay: ${this.backToP2PDelay}`);
258
     logger.info(`backToP2PDelay: ${this.backToP2PDelay}`);
260
 
259
 
261
     /**
260
     /**
3078
         done = true;
3077
         done = true;
3079
     }
3078
     }
3080
 
3079
 
3081
-    if (!isNaN(this.p2pEstablishmentDuration)
3082
-        && !isNaN(this.jvbEstablishmentDuration)) {
3080
+    if (isValidNumber(this.p2pEstablishmentDuration)
3081
+            && isValidNumber(this.jvbEstablishmentDuration)) {
3083
         const establishmentDurationDiff
3082
         const establishmentDurationDiff
3084
             = this.p2pEstablishmentDuration - this.jvbEstablishmentDuration;
3083
             = this.p2pEstablishmentDuration - this.jvbEstablishmentDuration;
3085
 
3084
 
3678
  * @returns {boolean} true if the operation is successful, false otherwise.
3677
  * @returns {boolean} true if the operation is successful, false otherwise.
3679
  */
3678
  */
3680
 JitsiConference.prototype.setDesktopSharingFrameRate = function(maxFps) {
3679
 JitsiConference.prototype.setDesktopSharingFrameRate = function(maxFps) {
3681
-    if (typeof maxFps !== 'number' || isNaN(maxFps)) {
3680
+    if (!isValidNumber(maxFps)) {
3682
         logger.error(`Invalid value ${maxFps} specified for desktop capture frame rate`);
3681
         logger.error(`Invalid value ${maxFps} specified for desktop capture frame rate`);
3683
 
3682
 
3684
         return false;
3683
         return false;
3685
     }
3684
     }
3686
 
3685
 
3687
-    this._desktopSharingFrameRate = maxFps;
3686
+    const fps = Number(maxFps);
3687
+
3688
+    this._desktopSharingFrameRate = fps;
3688
 
3689
 
3689
     // Set capture fps for screenshare.
3690
     // Set capture fps for screenshare.
3690
-    this.jvbJingleSession && this.jvbJingleSession.peerconnection.setDesktopSharingFrameRate(maxFps);
3691
+    this.jvbJingleSession && this.jvbJingleSession.peerconnection.setDesktopSharingFrameRate(fps);
3691
 
3692
 
3692
     // Set the capture rate for desktop sharing.
3693
     // Set the capture rate for desktop sharing.
3693
-    this.rtc.setDesktopSharingFrameRate(maxFps);
3694
+    this.rtc.setDesktopSharingFrameRate(fps);
3694
 
3695
 
3695
     return true;
3696
     return true;
3696
 };
3697
 };

+ 4
- 3
modules/RTC/JitsiLocalTrack.js Прегледај датотеку

21
 } from '../../service/statistics/AnalyticsEvents';
21
 } from '../../service/statistics/AnalyticsEvents';
22
 import browser from '../browser';
22
 import browser from '../browser';
23
 import Statistics from '../statistics/statistics';
23
 import Statistics from '../statistics/statistics';
24
+import { isValidNumber } from '../util/MathUtil';
24
 
25
 
25
 import JitsiTrack from './JitsiTrack';
26
 import JitsiTrack from './JitsiTrack';
26
 import RTCUtils from './RTCUtils';
27
 import RTCUtils from './RTCUtils';
116
                 }
117
                 }
117
 
118
 
118
                 // If the constraints are still empty, fallback to the constraints used for initial gUM.
119
                 // If the constraints are still empty, fallback to the constraints used for initial gUM.
119
-                if (isNaN(this._constraints.height.ideal) && isNaN(this._constraints.width.ideal)) {
120
+                if (!isValidNumber(this._constraints.height.ideal) && !isValidNumber(this._constraints.width.ideal)) {
120
                     this._constraints.height = { ideal: constraints.height.ideal };
121
                     this._constraints.height = { ideal: constraints.height.ideal };
121
                     this._constraints.width = { ideal: constraints.width.ideal };
122
                     this._constraints.width = { ideal: constraints.width.ideal };
122
                 }
123
                 }
126
             // picked for the given constraints, fallback to the constraints if MediaStreamTrack.getSettings() doesn't
127
             // picked for the given constraints, fallback to the constraints if MediaStreamTrack.getSettings() doesn't
127
             // return the height.
128
             // return the height.
128
             this.resolution = this.getHeight();
129
             this.resolution = this.getHeight();
129
-            if (isNaN(this.resolution) && this._constraints.height?.ideal) {
130
+            if (!isValidNumber(this.resolution) && this._constraints.height?.ideal) {
130
                 this.resolution = this._constraints.height.ideal;
131
                 this.resolution = this._constraints.height.ideal;
131
             }
132
             }
132
             this.maxEnabledResolution = this.resolution;
133
             this.maxEnabledResolution = this.resolution;
931
      * @param {number} ssrc The SSRC.
932
      * @param {number} ssrc The SSRC.
932
      */
933
      */
933
     setSsrc(ssrc) {
934
     setSsrc(ssrc) {
934
-        if (!isNaN(ssrc)) {
935
+        if (isValidNumber(ssrc)) {
935
             this._ssrc = ssrc;
936
             this._ssrc = ssrc;
936
         }
937
         }
937
     }
938
     }

+ 2
- 1
modules/RTC/JitsiRemoteTrack.js Прегледај датотеку

3
 import { createTtfmEvent } from '../../service/statistics/AnalyticsEvents';
3
 import { createTtfmEvent } from '../../service/statistics/AnalyticsEvents';
4
 import TrackStreamingStatusImpl, { TrackStreamingStatus } from '../connectivity/TrackStreamingStatus';
4
 import TrackStreamingStatusImpl, { TrackStreamingStatus } from '../connectivity/TrackStreamingStatus';
5
 import Statistics from '../statistics/statistics';
5
 import Statistics from '../statistics/statistics';
6
+import { isValidNumber } from '../util/MathUtil';
6
 
7
 
7
 import JitsiTrack from './JitsiTrack';
8
 import JitsiTrack from './JitsiTrack';
8
 
9
 
329
         const gumStart = window.connectionTimes['obtainPermissions.start'];
330
         const gumStart = window.connectionTimes['obtainPermissions.start'];
330
         const gumEnd = window.connectionTimes['obtainPermissions.end'];
331
         const gumEnd = window.connectionTimes['obtainPermissions.end'];
331
         const gumDuration
332
         const gumDuration
332
-            = !isNaN(gumEnd) && !isNaN(gumStart) ? gumEnd - gumStart : 0;
333
+            = isValidNumber(gumEnd) && isValidNumber(gumStart) ? gumEnd - gumStart : 0;
333
 
334
 
334
         // Subtract the muc.joined-to-session-initiate duration because jicofo
335
         // Subtract the muc.joined-to-session-initiate duration because jicofo
335
         // waits until there are 2 participants to start Jingle sessions.
336
         // waits until there are 2 participants to start Jingle sessions.

+ 2
- 5
modules/RTC/RTCUtils.js Прегледај датотеку

12
 import browser from '../browser';
12
 import browser from '../browser';
13
 import Statistics from '../statistics/statistics';
13
 import Statistics from '../statistics/statistics';
14
 import Listenable from '../util/Listenable';
14
 import Listenable from '../util/Listenable';
15
+import { isValidNumber } from '../util/MathUtil';
15
 
16
 
16
 import screenObtainer from './ScreenObtainer';
17
 import screenObtainer from './ScreenObtainer';
17
 
18
 
336
         return new Promise((resolve, reject) => {
337
         return new Promise((resolve, reject) => {
337
             let gumTimeout, timeoutExpired = false;
338
             let gumTimeout, timeoutExpired = false;
338
 
339
 
339
-            if (typeof timeout === 'number' && !isNaN(timeout) && timeout > 0) {
340
+            if (isValidNumber(timeout) && timeout > 0) {
340
                 gumTimeout = setTimeout(() => {
341
                 gumTimeout = setTimeout(() => {
341
                     timeoutExpired = true;
342
                     timeoutExpired = true;
342
                     gumTimeout = undefined;
343
                     gumTimeout = undefined;
369
                     if (jitsiError.name === JitsiTrackErrors.PERMISSION_DENIED) {
370
                     if (jitsiError.name === JitsiTrackErrors.PERMISSION_DENIED) {
370
                         this._updateGrantedPermissions(umDevices, undefined);
371
                         this._updateGrantedPermissions(umDevices, undefined);
371
                     }
372
                     }
372
-
373
-                    // else {
374
-                    // Probably the error is not caused by the lack of permissions and we don't need to update them.
375
-                    // }
376
                 });
373
                 });
377
         });
374
         });
378
     }
375
     }

+ 3
- 2
modules/RTC/TraceablePeerConnection.js Прегледај датотеку

21
 import SdpSimulcast from '../sdp/SdpSimulcast';
21
 import SdpSimulcast from '../sdp/SdpSimulcast';
22
 import { SdpTransformWrap } from '../sdp/SdpTransformUtil';
22
 import { SdpTransformWrap } from '../sdp/SdpTransformUtil';
23
 import Statistics from '../statistics/statistics';
23
 import Statistics from '../statistics/statistics';
24
+import { isValidNumber } from '../util/MathUtil';
24
 
25
 
25
 import JitsiRemoteTrack from './JitsiRemoteTrack';
26
 import JitsiRemoteTrack from './JitsiRemoteTrack';
26
 import RTCUtils from './RTCUtils';
27
 import RTCUtils from './RTCUtils';
922
     const trackSsrc = Number(ssrcStr);
923
     const trackSsrc = Number(ssrcStr);
923
     const ownerEndpointId = this.signalingLayer.getSSRCOwner(trackSsrc);
924
     const ownerEndpointId = this.signalingLayer.getSSRCOwner(trackSsrc);
924
 
925
 
925
-    if (isNaN(trackSsrc) || trackSsrc < 0) {
926
+    if (!isValidNumber(trackSsrc) || trackSsrc < 0) {
926
         logger.error(`Invalid SSRC for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`
927
         logger.error(`Invalid SSRC for remote stream[ssrc=${trackSsrc},id=${streamId},type=${mediaType}]`
927
                 + 'track creation failed!');
928
                 + 'track creation failed!');
928
 
929
 
2065
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2066
  * @returns {Promise} promise that will be resolved when the operation is successful and rejected otherwise.
2066
  */
2067
  */
2067
 TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeight, localVideoTrack, preferredCodec) {
2068
 TraceablePeerConnection.prototype.setSenderVideoConstraints = function(frameHeight, localVideoTrack, preferredCodec) {
2068
-    if (frameHeight < 0 || isNaN(frameHeight)) {
2069
+    if (frameHeight < 0 || !isValidNumber(frameHeight)) {
2069
         throw new Error(`Invalid frameHeight: ${frameHeight}`);
2070
         throw new Error(`Invalid frameHeight: ${frameHeight}`);
2070
     }
2071
     }
2071
     if (!localVideoTrack) {
2072
     if (!localVideoTrack) {

+ 2
- 1
modules/qualitycontrol/QualityController.ts Прегледај датотеку

12
 } from '../../service/RTC/StandardVideoQualitySettings';
12
 } from '../../service/RTC/StandardVideoQualitySettings';
13
 import JitsiLocalTrack from '../RTC/JitsiLocalTrack';
13
 import JitsiLocalTrack from '../RTC/JitsiLocalTrack';
14
 import TraceablePeerConnection from '../RTC/TraceablePeerConnection';
14
 import TraceablePeerConnection from '../RTC/TraceablePeerConnection';
15
+import { isValidNumber } from '../util/MathUtil';
15
 import JingleSessionPC from '../xmpp/JingleSessionPC';
16
 import JingleSessionPC from '../xmpp/JingleSessionPC';
16
 
17
 
17
 import { CodecSelection } from './CodecSelection';
18
 import { CodecSelection } from './CodecSelection';
318
         const { encodeResolution, localTrack, qualityLimitationReason, tpc } = sourceStats;
319
         const { encodeResolution, localTrack, qualityLimitationReason, tpc } = sourceStats;
319
 
320
 
320
         // Older browser versions might not report the resolution in the stats.
321
         // Older browser versions might not report the resolution in the stats.
321
-        if (Number.isNaN(encodeResolution)) {
322
+        if (!isValidNumber(encodeResolution)) {
322
             return;
323
             return;
323
         }
324
         }
324
         const trackId = localTrack.rtcId;
325
         const trackId = localTrack.rtcId;

+ 13
- 12
modules/statistics/AvgRTPStatsReporter.js Прегледај датотеку

11
     createTransportStatsEvent
11
     createTransportStatsEvent
12
 } from '../../service/statistics/AnalyticsEvents';
12
 } from '../../service/statistics/AnalyticsEvents';
13
 import browser from '../browser';
13
 import browser from '../browser';
14
+import { isValidNumber } from '../util/MathUtil';
14
 
15
 
15
 import Statistics from './statistics';
16
 import Statistics from './statistics';
16
 
17
 
46
 
47
 
47
         if (typeof nextValue !== 'number') {
48
         if (typeof nextValue !== 'number') {
48
             logger.error(`${this.name} - invalid value for idx: ${this.count}`, nextValue);
49
             logger.error(`${this.name} - invalid value for idx: ${this.count}`, nextValue);
49
-        } else if (!isNaN(nextValue)) {
50
+        } else if (isValidNumber(nextValue)) {
50
             this.sum += nextValue;
51
             this.sum += nextValue;
51
             this.samples.push(nextValue);
52
             this.samples.push(nextValue);
52
             this.count += 1;
53
             this.count += 1;
222
                     const jvbEnd2EndRTT = this
223
                     const jvbEnd2EndRTT = this
223
                         ._avgRtpStatsReporter.jvbStatsMonitor._avgEnd2EndRTT;
224
                         ._avgRtpStatsReporter.jvbStatsMonitor._avgEnd2EndRTT;
224
 
225
 
225
-                    if (!isNaN(jvbEnd2EndRTT)) {
226
+                    if (isValidNumber(jvbEnd2EndRTT)) {
226
                         // eslint-disable-next-line dot-notation
227
                         // eslint-disable-next-line dot-notation
227
                         batchReport['rtt_diff']
228
                         batchReport['rtt_diff']
228
                             = this._avgRTT.calculate() - jvbEnd2EndRTT;
229
                             = this._avgRTT.calculate() - jvbEnd2EndRTT;
234
 
235
 
235
                     this._avgEnd2EndRTT = avgLocalRTT + avgRemoteRTT;
236
                     this._avgEnd2EndRTT = avgLocalRTT + avgRemoteRTT;
236
 
237
 
237
-                    if (!isNaN(avgLocalRTT) && !isNaN(avgRemoteRTT)) {
238
+                    if (isValidNumber(avgLocalRTT) && isValidNumber(avgRemoteRTT)) {
238
                         // eslint-disable-next-line dot-notation
239
                         // eslint-disable-next-line dot-notation
239
                         batchReport['end2end_rtt_avg'] = this._avgEnd2EndRTT;
240
                         batchReport['end2end_rtt_avg'] = this._avgEnd2EndRTT;
240
                     }
241
                     }
261
         for (const remoteAvg of this._avgRemoteRTTMap.values()) {
262
         for (const remoteAvg of this._avgRemoteRTTMap.values()) {
262
             const avg = remoteAvg.calculate();
263
             const avg = remoteAvg.calculate();
263
 
264
 
264
-            if (!isNaN(avg)) {
265
+            if (isValidNumber(avg)) {
265
                 sum += avg;
266
                 sum += avg;
266
                 count += 1;
267
                 count += 1;
267
                 remoteAvg.reset();
268
                 remoteAvg.reset();
715
             this._avgPacketLossTotal.appendReport(batchReport);
716
             this._avgPacketLossTotal.appendReport(batchReport);
716
 
717
 
717
             this._avgRemoteFPS.appendReport(batchReport);
718
             this._avgRemoteFPS.appendReport(batchReport);
718
-            if (!isNaN(this._avgRemoteScreenFPS.calculate())) {
719
+            if (isValidNumber(this._avgRemoteScreenFPS.calculate())) {
719
                 this._avgRemoteScreenFPS.appendReport(batchReport);
720
                 this._avgRemoteScreenFPS.appendReport(batchReport);
720
             }
721
             }
721
             this._avgLocalFPS.appendReport(batchReport);
722
             this._avgLocalFPS.appendReport(batchReport);
722
-            if (!isNaN(this._avgLocalScreenFPS.calculate())) {
723
+            if (isValidNumber(this._avgLocalScreenFPS.calculate())) {
723
                 this._avgLocalScreenFPS.appendReport(batchReport);
724
                 this._avgLocalScreenFPS.appendReport(batchReport);
724
             }
725
             }
725
 
726
 
726
             this._avgRemoteCameraPixels.appendReport(batchReport);
727
             this._avgRemoteCameraPixels.appendReport(batchReport);
727
-            if (!isNaN(this._avgRemoteScreenPixels.calculate())) {
728
+            if (isValidNumber(this._avgRemoteScreenPixels.calculate())) {
728
                 this._avgRemoteScreenPixels.appendReport(batchReport);
729
                 this._avgRemoteScreenPixels.appendReport(batchReport);
729
             }
730
             }
730
             this._avgLocalCameraPixels.appendReport(batchReport);
731
             this._avgLocalCameraPixels.appendReport(batchReport);
731
-            if (!isNaN(this._avgLocalScreenPixels.calculate())) {
732
+            if (isValidNumber(this._avgLocalScreenPixels.calculate())) {
732
                 this._avgLocalScreenPixels.appendReport(batchReport);
733
                 this._avgLocalScreenPixels.appendReport(batchReport);
733
             }
734
             }
734
 
735
 
769
                     const peerAvgPixels = this._calculatePeerAvgVideoPixels(
770
                     const peerAvgPixels = this._calculatePeerAvgVideoPixels(
770
                         videosResolution, participant, videoType);
771
                         videosResolution, participant, videoType);
771
 
772
 
772
-                    if (!isNaN(peerAvgPixels)) {
773
+                    if (isValidNumber(peerAvgPixels)) {
773
                         peerPixelsSum += peerAvgPixels;
774
                         peerPixelsSum += peerAvgPixels;
774
                         peerCount += 1;
775
                         peerCount += 1;
775
                     }
776
                     }
829
                 = Number(videos[ssrc].height) * Number(videos[ssrc].width);
830
                 = Number(videos[ssrc].height) * Number(videos[ssrc].width);
830
 
831
 
831
             // FPS is reported as 0 for users with no video
832
             // FPS is reported as 0 for users with no video
832
-            if (!isNaN(peerSsrcPixels) && peerSsrcPixels > 0) {
833
+            if (isValidNumber(peerSsrcPixels) && peerSsrcPixels > 0) {
833
                 peerPixelsSum += peerSsrcPixels;
834
                 peerPixelsSum += peerSsrcPixels;
834
                 peerSsrcCount += 1;
835
                 peerSsrcCount += 1;
835
             }
836
             }
866
                         = this._calculatePeerAvgVideoFps(
867
                         = this._calculatePeerAvgVideoFps(
867
                             videosFps, participant, videoType);
868
                             videosFps, participant, videoType);
868
 
869
 
869
-                    if (!isNaN(peerAvgFPS)) {
870
+                    if (isValidNumber(peerAvgFPS)) {
870
                         peerFpsSum += peerAvgFPS;
871
                         peerFpsSum += peerAvgFPS;
871
                         peerCount += 1;
872
                         peerCount += 1;
872
                     }
873
                     }
923
             const peerSsrcFps = Number(videos[ssrc]);
924
             const peerSsrcFps = Number(videos[ssrc]);
924
 
925
 
925
             // FPS is reported as 0 for users with no video
926
             // FPS is reported as 0 for users with no video
926
-            if (!isNaN(peerSsrcFps) && peerSsrcFps > 0) {
927
+            if (isValidNumber(peerSsrcFps) && peerSsrcFps > 0) {
927
                 peerFpsSum += peerSsrcFps;
928
                 peerFpsSum += peerSsrcFps;
928
                 peerSsrcCount += 1;
929
                 peerSsrcCount += 1;
929
             }
930
             }

+ 6
- 5
modules/statistics/RTPStatsCollector.js Прегледај датотеку

4
 import * as StatisticsEvents from '../../service/statistics/Events';
4
 import * as StatisticsEvents from '../../service/statistics/Events';
5
 import browser from '../browser';
5
 import browser from '../browser';
6
 import FeatureFlags from '../flags/FeatureFlags';
6
 import FeatureFlags from '../flags/FeatureFlags';
7
+import { isValidNumber } from '../util/MathUtil';
7
 
8
 
8
 const logger = getLogger('modules/statistics/RTPStatsCollector');
9
 const logger = getLogger('modules/statistics/RTPStatsCollector');
9
 
10
 
305
             if (!FeatureFlags.isSsrcRewritingSupported()) {
306
             if (!FeatureFlags.isSsrcRewritingSupported()) {
306
                 logger.error(`No participant ID returned by ${track}`);
307
                 logger.error(`No participant ID returned by ${track}`);
307
             }
308
             }
308
-            continue; // eslint-disable-line no-continue
309
+            continue;
309
         }
310
         }
310
 
311
 
311
         const userCodecs = codecs[participantId] ?? { };
312
         const userCodecs = codecs[participantId] ?? { };
319
         const { resolution } = ssrcStats;
320
         const { resolution } = ssrcStats;
320
 
321
 
321
         if (!track.isVideoTrack()
322
         if (!track.isVideoTrack()
322
-            || isNaN(resolution?.height)
323
-            || isNaN(resolution?.width)
323
+            || !isValidNumber(resolution?.height)
324
+            || !isValidNumber(resolution?.width)
324
             || resolution.height === -1
325
             || resolution.height === -1
325
             || resolution.width === -1) {
326
             || resolution.width === -1) {
326
-            continue; // eslint-disable-line no-continue
327
+            continue;
327
         }
328
         }
328
         const userResolutions = resolutions[participantId] || {};
329
         const userResolutions = resolutions[participantId] || {};
329
 
330
 
413
         value = Number(value);
414
         value = Number(value);
414
     }
415
     }
415
 
416
 
416
-    if (isNaN(value)) {
417
+    if (!isValidNumber(value)) {
417
         return 0;
418
         return 0;
418
     }
419
     }
419
 
420
 

+ 13
- 1
modules/util/MathUtil.ts Прегледај датотеку

103
  * @returns {number} - x - y or 0 if x or y is not a number.
103
  * @returns {number} - x - y or 0 if x or y is not a number.
104
  */
104
  */
105
 export function safeSubtract(x: any, y: any): number {
105
 export function safeSubtract(x: any, y: any): number {
106
-    return !isNaN(x) && !isNaN(y) ? x - y : 0;
106
+    return isValidNumber(x) && isValidNumber(y) ? x - y : 0;
107
+}
108
+
109
+/**
110
+ * Checks if the given value is a valid number.
111
+ *
112
+ * @param n - The value to check.
113
+ * @returns - `true` if the value is a valid number, `false` otherwise.
114
+ */
115
+export function isValidNumber(n: any): boolean {
116
+    const v = Number.parseInt(n, 10);
117
+
118
+    return Number.isFinite(v); // Filter out NaN and Infinity.
107
 }
119
 }

+ 2
- 1
service/RTC/SignalingLayer.ts Прегледај датотеку

1
 import Listenable from '../../modules/util/Listenable';
1
 import Listenable from '../../modules/util/Listenable';
2
+import { isValidNumber } from '../../modules/util/MathUtil';
2
 
3
 
3
 import { MediaType } from './MediaType';
4
 import { MediaType } from './MediaType';
4
 import { VideoType } from './VideoType';
5
 import { VideoType } from './VideoType';
69
     const nameParts = sourceName.split('-');
70
     const nameParts = sourceName.split('-');
70
     const trackIdx = Number(nameParts[nameParts.length - 1].substring(1));
71
     const trackIdx = Number(nameParts[nameParts.length - 1].substring(1));
71
 
72
 
72
-    if (Number.isNaN(trackIdx)) {
73
+    if (!isValidNumber(trackIdx)) {
73
         throw new Error(`Failed to parse track idx for source name: ${sourceName}`);
74
         throw new Error(`Failed to parse track idx for source name: ${sourceName}`);
74
     }
75
     }
75
 
76
 

Loading…
Откажи
Сачувај