Repository: yt-dlp/yt-dlp
Pull request #7279 (2023-06-10 21:07:55)

[jsinterp] Fix division
Fixes failing nsig decryption for new YT JS player `8c7583ff`

See https://github.com/ytdl-org/youtube-dl/issues/32292

Zero divided by any non-zero number was returning `NaN`
```
[debug] JS:                     c[new Date("1970-01-01T09:15:00.000+09:15")/1E3]
[debug] JS:                       new Date("1970-01-01T09:15:00.000+09:15")/1E3
[debug] JS:                         "1970-01-01T09:15:00.000+09:15"
[debug] JS:                         -> '1970-01-01T09:15:00.000+09:15' <-| "1970-01-01T09:15:00.000+09:15"
[debug] JS:                         0
[debug] JS:                         1E3
[debug] JS:                         -> 1000.0 <-| 1E3
[debug] JS:                       -> nan <-| new Date("1970-01-01T09:15:00.000+09:15")/1E3
[debug] JS:                     => Raises: Cannot get index nan in: [F<247>, -1658198590, ..., -1183556064, -705166834, -1680476002, 208789974] <-| c[new Date("1970-01-01T09:15:00.000+09:15")/1E3]
```

<details open><summary>Template</summary> <!-- OPEN is intentional -->

<!--

# PLEASE FOLLOW THE GUIDE BELOW

- You will be asked some questions, please read them **carefully** and answer honestly
- Put an `x` into all the boxes `[ ]` relevant to your *pull request* (like [x])
- Use *Preview* tab to see how your *pull request* will actually look like

-->

### Before submitting a *pull request* make sure you have:
- [x] At least skimmed through [contributing guidelines](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#developer-instructions) including [yt-dlp coding conventions](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#yt-dlp-coding-conventions)
- [x] [Searched](https://github.com/yt-dlp/yt-dlp/search?q=is%3Apr&type=Issues) the bugtracker for similar pull requests
- [x] Checked the code with [flake8](https://pypi.python.org/pypi/flake8) and [ran relevant tests](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#developer-instructions)

### In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under [Unlicense](http://unlicense.org/). Check all of the following options that apply:
- [x] I am the original author of this code and I am willing to release it under [Unlicense](http://unlicense.org/)
- [ ] I am not the original author of this code but it is in public domain or released under [Unlicense](http://unlicense.org/) (provide reliable evidence)

### What is the purpose of your *pull request*?
- [ ] Fix or improvement to an extractor (Make sure to add/update tests)
- [ ] New extractor ([Piracy websites will not be accepted](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-website-primarily-used-for-piracy))
- [x] Core bug fix/improvement
- [ ] New feature (It is strongly [recommended to open an issue first](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#adding-new-feature-or-making-overarching-changes))


<!-- Do NOT edit/remove anything below this! -->
</details><details><summary>Copilot Summary</summary>  

<!--
copilot:all
-->
### <samp>🤖 Generated by Copilot at 50405ed</samp>

### Summary
🧪🐛➗

<!--
1.  🧪 for adding a new test case
2.  🐛 for fixing a bug
3.  ➗ for implementing the division operator
-->
Fix JavaScript division operator in `yt_dlp/jsinterp.py` and add a test case in `test/test_jsinterp.py` to verify its behavior.

> _`_js_div` fixed_
> _Zero division bug no more_
> _Autumn tests pass now_

### Walkthrough
* Fix JavaScript division operator `/` to return `inf` or `-inf` when dividing by zero, instead of `nan` ([link](https://github.com/yt-dlp/yt-dlp/pull/7279/files?diff=unified&w=0#diff-729b57caa8d006426f6a8960c061f519a8b6658682284015e069745af52ffb07L47-R47))
* Add test case for JavaScript division operator `/` with different values, such as zero, undefined, and infinity ([link](https://github.com/yt-dlp/yt-dlp/pull/7279/files?diff=unified&w=0#diff-d64df7f8209b00a6f337bba53eb0a8a5a237c35f2cc0ea70f793cc4fbec4a8ceR31-R37))
* Use `JSInterpreter` class from `yt_dlp/jsinterp.py` to evaluate and call a simple JavaScript function that performs division in the test case ([link](https://github.com/yt-dlp/yt-dlp/pull/7279/files?diff=unified&w=0#diff-d64df7f8209b00a6f337bba53eb0a8a5a237c35f2cc0ea70f793cc4fbec4a8ceR31-R37))
* Assert that the results match the expected values according to the JavaScript specification in the test case ([link](https://github.com/yt-dlp/yt-dlp/pull/7279/files?diff=unified&w=0#diff-d64df7f8209b00a6f337bba53eb0a8a5a237c35f2cc0ea70f793cc4fbec4a8ceR31-R37))



</details>


coletdjnz: Add a nsig test for player 8c7583ff too (in test_YouTube_signature)

Patch:
diff --git a/yt_dlp/jsinterp.py b/yt_dlp/jsinterp.py
index 7c7940efd..d6d555733 100644
--- a/yt_dlp/jsinterp.py
+++ b/yt_dlp/jsinterp.py
@@ -44,7 +44,7 @@ def wrapped(a, b):
 
 
 def _js_div(a, b):
-    if JS_Undefined in (a, b) or not (a and b):
+    if JS_Undefined in (a, b) or not (a or b):
         return float('nan')
     return (a or 0) / b if b else float('inf')
 


Test patch:
diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py
index 4d44e6efe..b01477e6f 100644
--- a/test/test_jsinterp.py
+++ b/test/test_jsinterp.py
@@ -28,6 +28,13 @@ def test_basic(self):
     def test_calc(self):
         self._test('function f(a){return 2*a+1;}', 7, args=[3])
 
+    def test_div(self):
+        jsi = JSInterpreter('function f(a, b){return a / b;}')
+        self.assertTrue(math.isnan(jsi.call_function('f', 0, 0)))
+        self.assertTrue(math.isnan(jsi.call_function('f', JS_Undefined, 1)))
+        self.assertTrue(math.isinf(jsi.call_function('f', 2, 0)))
+        self.assertEqual(jsi.call_function('f', 0, 3), 0)
+
     def test_empty_return(self):
         self._test('function f(){return; y()}', None)
 
diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py
index 13120d97f..01f09de88 100644
--- a/test/test_youtube_signature.py
+++ b/test/test_youtube_signature.py
@@ -150,6 +150,10 @@
         'https://www.youtube.com/s/player/cfa9e7cb/player_ias.vflset/en_US/base.js',
         'aCi3iElgd2kq0bxVbQ', 'QX1y8jGb2IbZ0w',
     ),
+    (
+        'https://www.youtube.com/s/player/8c7583ff/player_ias.vflset/en_US/base.js',
+        '1wWCVpRR96eAmMI87L', 'KSkWAVv1ZQxC3A',
+    ),
 ]